Skip to content

Commit

Permalink
Add symbols specification
Browse files Browse the repository at this point in the history
  • Loading branch information
MDUYN committed Mar 23, 2024
1 parent 12b2d18 commit 4a1c579
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 68 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ lib/
bumpversion.egg-info/
*.sqlite3

*/backtest_data/
*/backtest_reports/
**/backtest_data/*
*/backtest_reports/
**/backtest_reports/*
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ It also exposes an REST API that allows you to interact with the algorithm.
import pathlib
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
CCXTTickerMarketDataSource, MarketCredential
CCXTTickerMarketDataSource, MarketCredential, SYMBOLS

# Define resource directory and the symbols you want to trade
config = {
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()
SYMBOLS: ["BTC/EUR"]
}

# Define market data sources
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
Expand All @@ -54,7 +60,7 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
market="BITVAVO",
symbol="BTC/EUR",
)
app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
app = create_app(config=config)
algorithm = Algorithm()

app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
Expand Down
4 changes: 4 additions & 0 deletions examples/backtest/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
app = create_app(
config={RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()}
)


if __name__ == "__main__":
app.run()
11 changes: 9 additions & 2 deletions examples/bitvavo_trading_bot/bitvavo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from investing_algorithm_framework import MarketCredential, TimeUnit, \
CCXTOHLCVMarketDataSource, CCXTTickerMarketDataSource, TradingStrategy, \
create_app, PortfolioConfiguration, Algorithm
create_app, PortfolioConfiguration, Algorithm, SYMBOLS, RESOURCE_DIRECTORY

"""
Bitvavo trading bot example with market data sources of bitvavo.
Expand Down Expand Up @@ -45,12 +46,18 @@ def apply_strategy(self, algorithm, market_data):
print(market_data["BTC/EUR-ohlcv"])
print(market_data["BTC/EUR-ticker"])


config = {
SYMBOLS: ["BTC/EUR"],
RESOURCE_DIRECTORY: os.path.join(os.path.dirname(__file__), "resources")
}

# Create an algorithm and link your trading strategy to it
algorithm = Algorithm()
algorithm.add_strategy(BitvavoTradingStrategy)

# Create an app and add the market data sources and market credentials to it
app = create_app()
app = create_app(config=config)
app.add_market_credential(bitvavo_market_credential)
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
app.add_market_data_source(bitvavo_btc_eur_ticker)
Expand Down
9 changes: 7 additions & 2 deletions examples/coinbase_trading_bot/coinbase.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from investing_algorithm_framework import MarketCredential, TimeUnit, \
CCXTOHLCVMarketDataSource, CCXTTickerMarketDataSource, TradingStrategy, \
create_app, PortfolioConfiguration, Algorithm
create_app, PortfolioConfiguration, Algorithm, SYMBOLS, RESOURCE_DIRECTORY

"""
Coinbase market data sources example. Coinbase requires you to have an API key
Expand Down Expand Up @@ -42,11 +43,15 @@ class CoinBaseTradingStrategy(TradingStrategy):
def apply_strategy(self, algorithm, market_data):
pass

config = {
SYMBOLS: ["BTC/EUR"],
RESOURCE_DIRECTORY: os.path.join(os.path.dirname(__file__), "resources")
}

algorithm = Algorithm()
algorithm.add_strategy(CoinBaseTradingStrategy)

app = create_app()
app = create_app(config=config)
app.add_algorithm(algorithm)
app.add_market_credential(coinbase_market_credential)
app.add_market_data_source(coinbase_btc_eur_ohlcv_2h)
Expand Down
11 changes: 7 additions & 4 deletions examples/crossover_moving_average_trading_bot/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import pathlib

from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY
from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY, \
SYMBOLS

app = create_app(
config={RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()}
)
config = {
SYMBOLS: ["BTC/EUR"],
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()
}
app = create_app(config=config)

3 changes: 2 additions & 1 deletion investing_algorithm_framework/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
OrderStatus, OrderSide, Config, TimeUnit, TimeInterval, Order, Portfolio, \
Position, TimeFrame, BACKTESTING_INDEX_DATETIME, MarketCredential, \
PortfolioConfiguration, RESOURCE_DIRECTORY, pretty_print_backtest, \
Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, \
Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, SYMBOLS, \
TickerMarketDataSource, MarketService, BacktestReportsEvaluation, \
pretty_print_backtest_reports_evaluation, load_backtest_reports
from investing_algorithm_framework.app import TradingStrategy, \
Expand Down Expand Up @@ -55,4 +55,5 @@
"pretty_print_backtest_reports_evaluation",
"BacktestReportsEvaluation",
"load_backtest_reports",
"SYMBOLS"
]
1 change: 1 addition & 0 deletions investing_algorithm_framework/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ def _initialize_app_for_backtest(
# Override the portfolio service with the backtest portfolio service
self.container.portfolio_service.override(
BacktestPortfolioService(
configuration_service=self.container.configuration_service(),
market_credential_service=self.container
.market_credential_service(),
market_service=self.container.market_service(),
Expand Down
1 change: 1 addition & 0 deletions investing_algorithm_framework/dependency_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class DependencyContainer(containers.DeclarativeContainer):
)
portfolio_service = providers.Factory(
PortfolioService,
configuration_service=configuration_service,
market_credential_service=market_credential_service,
market_service=market_service,
position_repository=position_repository,
Expand Down
3 changes: 2 additions & 1 deletion investing_algorithm_framework/domain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
DATETIME_FORMAT, DATETIME_FORMAT_BACKTESTING, BACKTESTING_FLAG, \
BACKTESTING_INDEX_DATETIME, BACKTESTING_START_DATE, CCXT_DATETIME_FORMAT, \
BACKTEST_DATA_DIRECTORY_NAME, TICKER_DATA_TYPE, OHLCV_DATA_TYPE, \
CURRENT_UTC_DATETIME, BACKTESTING_END_DATE, \
CURRENT_UTC_DATETIME, BACKTESTING_END_DATE, SYMBOLS, \
CCXT_DATETIME_FORMAT_WITH_TIMEZONE, \
BACKTESTING_PENDING_ORDER_CHECK_INTERVAL
from .singleton import Singleton
Expand Down Expand Up @@ -105,4 +105,5 @@
"BacktestReportsEvaluation",
"load_csv_into_dict",
"load_backtest_reports",
"SYMBOLS"
]
49 changes: 1 addition & 48 deletions investing_algorithm_framework/domain/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Config(dict):
SQLITE_ENABLED = True
SQLITE_INITIALIZED = False
BACKTEST_DATA_DIRECTORY_NAME = "backtest_data"
SYMBOLS = None

def __init__(self, resource_directory=None):
super().__init__()
Expand All @@ -85,54 +86,6 @@ def __init__(self, resource_directory=None):

super().__init__(vars(self.__class__))

# def __setitem__(self, key, item):
# self.__dict__[key] = item
#
# def __getitem__(self, key):
# return self.__dict__[key]
#
# def __repr__(self):
# return repr(self.__dict__)
#
# def __len__(self):
# return len(self.__dict__)
#
# def __delitem__(self, key):
# del self.__dict__[key]
#
# def clear(self):
# return self.__dict__.clear()
#
# def copy(self):
# return self.__dict__.copy()
#
# def has_key(self, k):
# return k in self.__dict__
#
# def update(self, *args, **kwargs):
# return self.__dict__.update(*args, **kwargs)
#
# def keys(self):
# return self.__dict__.keys()
#
# def values(self):
# return self.__dict__.values()
#
# def items(self):
# return self.__dict__.items()
#
# def pop(self, *args):
# return self.__dict__.pop(*args)
#
# def __cmp__(self, dict_):
# return self.__cmp__(self.__dict__, dict_)
#
# def __contains__(self, item):
# return item in self.__dict__
#
# def __iter__(self):
# return iter(self.__dict__)

def __str__(self):
field_strings = []

Expand Down
1 change: 1 addition & 0 deletions investing_algorithm_framework/domain/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
DATABASE_URL = 'DATABASE_URL'
DEFAULT_DATABASE_NAME = "database"

SYMBOLS = "SYMBOLS"
RESOURCE_DIRECTORY = "RESOURCE_DIRECTORY"
BACKTEST_DATA_DIRECTORY_NAME = "BACKTEST_DATA_DIRECTORY_NAME"
LOG_LEVEL = 'LOG_LEVEL'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
from datetime import datetime

from investing_algorithm_framework.domain import OrderSide, OrderStatus, \
OperationalException, MarketService, MarketCredentialService
OperationalException, MarketService, MarketCredentialService, SYMBOLS
from investing_algorithm_framework.services.repository_service \
import RepositoryService
from investing_algorithm_framework.services.configuration_service import \
ConfigurationService

logger = logging.getLogger("investing_algorithm_framework")

Expand All @@ -18,6 +20,7 @@ class PortfolioService(RepositoryService):

def __init__(
self,
configuration_service: ConfigurationService,
market_service: MarketService,
market_credential_service: MarketCredentialService,
position_repository,
Expand All @@ -26,6 +29,7 @@ def __init__(
portfolio_configuration_service,
portfolio_snapshot_service,
):
self.configuration_service = configuration_service
self.market_credential_service = market_credential_service
self.market_service = market_service
self.position_repository = position_repository
Expand Down Expand Up @@ -235,12 +239,24 @@ def sync_portfolio_orders(self, portfolio):
portfolio_configuration = self.portfolio_configuration_service \
.get(portfolio.identifier)

# Get all available symbols for the market and check if
# there are orders
available_symbols = self.market_service.get_symbols(
market=portfolio.market
)
# Check if the symbols param in the configuration is set
config = self.configuration_service.config

if SYMBOLS in config and config[SYMBOLS] is not None:
available_symbols = config[SYMBOLS]

if not isinstance(available_symbols, list):
raise OperationalException(
"The symbols configuration should be a list of strings"
)
else:
# if not, get all available symbols for the market and check if
# there are orders
available_symbols = self.market_service.get_symbols(
market=portfolio.market
)

# Check if there are orders for the available symbols
for symbol in available_symbols:
orders = self.market_service.get_orders(
symbol=symbol,
Expand Down
Loading

0 comments on commit 4a1c579

Please sign in to comment.