investing-algorithm-framework 1.7.9__tar.gz → 2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/PKG-INFO +40 -29
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/README.md +39 -28
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/__init__.py +7 -10
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/algorithm.py +73 -135
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/app.py +124 -61
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/strategy.py +1 -5
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/create_app.py +3 -1
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/dependency_container.py +23 -15
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/__init__.py +17 -12
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/constants.py +4 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/domain/data_structures.py +41 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/__init__.py +3 -8
- investing_algorithm_framework-2.0/investing_algorithm_framework/domain/models/market/__init__.py +5 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/domain/models/market/market_credential.py +26 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -2
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +3 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +7 -37
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/services/__init__.py +3 -1
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/services/market_data_sources.py +27 -13
- investing_algorithm_framework-2.0/investing_algorithm_framework/domain/services/market_service.py +129 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/__init__.py +1 -4
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +70 -44
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +3 -11
- investing_algorithm_framework-2.0/investing_algorithm_framework/infrastructure/services/__init__.py +7 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +5 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +141 -145
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/__init__.py +9 -5
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/backtest_service.py +34 -32
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_credential_service.py +24 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/__init__.py +8 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +113 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +131 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service/__init__.py +7 -0
- {investing_algorithm_framework-1.7.9/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service}/order_backtest_service.py +64 -34
- {investing_algorithm_framework-1.7.9/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service}/order_service.py +23 -24
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/portfolio_configuration_service.py +3 -14
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service/__init__.py +7 -0
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service/backtest_portfolio_service.py +20 -0
- {investing_algorithm_framework-1.7.9/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service}/portfolio_service.py +12 -12
- investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service.py +207 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/position_service.py +19 -9
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +9 -6
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/PKG-INFO +40 -29
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/SOURCES.txt +14 -13
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/tests/test_create_app.py +1 -3
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/market_data/__init__.py +0 -11
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/market_data/asset_price.py +0 -50
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/market_data/ohlcv.py +0 -105
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/market_data/order_book.py +0 -63
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/market_data/ticker.py +0 -92
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/models/portfolio/backtest_portfolio_configuration.py +0 -21
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/domain/services/order_executor_service.py +0 -33
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/infrastructure/services/__init__.py +0 -10
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -9
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/infrastructure/services/market_service/backtest_market_service.py +0 -185
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/infrastructure/services/market_service/market_service.py +0 -112
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/services/market_data_service.py +0 -80
- investing_algorithm_framework-1.7.9/investing_algorithm_framework/services/position_cost_service.py +0 -5
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/AUTHORS.md +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/LICENSE +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/task.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/responses.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/config.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/backtest_profile.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_fee.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trade.py +1 -1
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/singleton.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/strategy.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/backtesting.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/configuration_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/portfolio_snapshot_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/repository_service.py +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/dependency_links.txt +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/requires.txt +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/top_level.txt +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/setup.cfg +0 -0
- {investing_algorithm_framework-1.7.9 → investing_algorithm_framework-2.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: investing_algorithm_framework
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0
|
|
4
4
|
Summary: A framework for creating an investment algorithm
|
|
5
5
|
Home-page: https://github.com/coding-kitties/investing-algorithm-framework.git
|
|
6
6
|
Download-URL: https://github.com/coding-kitties/investing-algorithm-framework/archive/v0.1.1.tar.gz
|
|
@@ -64,12 +64,11 @@ import pathlib
|
|
|
64
64
|
from datetime import datetime, timedelta
|
|
65
65
|
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
|
|
66
66
|
RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
|
|
67
|
-
CCXTTickerMarketDataSource
|
|
67
|
+
CCXTTickerMarketDataSource, MarketCredential
|
|
68
68
|
|
|
69
69
|
# Define market data sources
|
|
70
|
-
# OHLCV data
|
|
71
70
|
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
72
|
-
identifier="BTC",
|
|
71
|
+
identifier="BTC-ohlcv",
|
|
73
72
|
market="BITVAVO",
|
|
74
73
|
symbol="BTC/EUR",
|
|
75
74
|
timeframe="2h",
|
|
@@ -77,19 +76,23 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
|
77
76
|
)
|
|
78
77
|
# Ticker data for orders, trades and positions
|
|
79
78
|
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
80
|
-
identifier="BTC",
|
|
79
|
+
identifier="BTC-ticker",
|
|
81
80
|
market="BITVAVO",
|
|
82
81
|
symbol="BTC/EUR",
|
|
83
82
|
)
|
|
84
83
|
app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
|
|
85
84
|
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
|
|
86
85
|
app.add_market_data_source(bitvavo_btc_eur_ticker)
|
|
86
|
+
app.add_market_credential(MarketCredential(
|
|
87
|
+
market="bitvavo",
|
|
88
|
+
api_key="<your api key>",
|
|
89
|
+
secret_key="<your secret key>",
|
|
90
|
+
))
|
|
87
91
|
app.add_portfolio_configuration(
|
|
88
92
|
PortfolioConfiguration(
|
|
89
|
-
market="
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
trading_symbol="EUR"
|
|
93
|
+
market="bitvavo",
|
|
94
|
+
trading_symbol="EUR",
|
|
95
|
+
initial_balance=400
|
|
93
96
|
)
|
|
94
97
|
)
|
|
95
98
|
|
|
@@ -99,12 +102,12 @@ app.add_portfolio_configuration(
|
|
|
99
102
|
time_unit=TimeUnit.HOUR,
|
|
100
103
|
interval=2,
|
|
101
104
|
# Specify market data sources that need to be passed to the strategy
|
|
102
|
-
market_data_sources=[
|
|
105
|
+
market_data_sources=["BTC-ticker", "BTC-ohlcv"]
|
|
103
106
|
)
|
|
104
|
-
def perform_strategy(algorithm: Algorithm, market_data):
|
|
107
|
+
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
105
108
|
print(
|
|
106
109
|
f"Performing trading strategy on market " +
|
|
107
|
-
f"data {market_data[
|
|
110
|
+
f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
|
|
108
111
|
)
|
|
109
112
|
|
|
110
113
|
if __name__ == "__main__":
|
|
@@ -122,19 +125,19 @@ import pathlib
|
|
|
122
125
|
from datetime import datetime, timedelta
|
|
123
126
|
from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY, \
|
|
124
127
|
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, pretty_print_backtest, \
|
|
125
|
-
CCXTTickerMarketDataSource,
|
|
128
|
+
CCXTTickerMarketDataSource, PortfolioConfiguration
|
|
126
129
|
|
|
127
130
|
# Define market data sources
|
|
128
131
|
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
129
|
-
identifier="BTC",
|
|
130
|
-
market="
|
|
132
|
+
identifier="BTC-ohlcv",
|
|
133
|
+
market="bitvavo",
|
|
131
134
|
symbol="BTC/EUR",
|
|
132
135
|
timeframe="2h",
|
|
133
136
|
start_date_func=lambda : datetime.utcnow() - timedelta(days=17)
|
|
134
137
|
)
|
|
135
138
|
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
136
|
-
identifier="BTC",
|
|
137
|
-
market="
|
|
139
|
+
identifier="BTC-ticker",
|
|
140
|
+
market="bitvavo",
|
|
138
141
|
symbol="BTC/EUR",
|
|
139
142
|
backtest_timeframe="2h" # We want the ticker data to
|
|
140
143
|
# be sampled every 2 hours, inline with the strategy interval
|
|
@@ -142,24 +145,25 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
|
142
145
|
app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
|
|
143
146
|
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
|
|
144
147
|
app.add_market_data_source(bitvavo_btc_eur_ticker)
|
|
148
|
+
app.add_portfolio_configuration(PortfolioConfiguration(
|
|
149
|
+
initial_balance=400,
|
|
150
|
+
market="bitvavo",
|
|
151
|
+
trading_symbol="EUR",
|
|
152
|
+
))
|
|
153
|
+
|
|
145
154
|
|
|
146
155
|
@app.strategy(
|
|
147
156
|
time_unit=TimeUnit.HOUR,
|
|
148
157
|
interval=2,
|
|
149
|
-
market_data_sources=[
|
|
158
|
+
market_data_sources=["BTC-ticker", "BTC-ohlcv"]
|
|
150
159
|
)
|
|
151
|
-
def perform_strategy(algorithm: Algorithm, market_data):
|
|
160
|
+
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
152
161
|
print(
|
|
153
162
|
f"Performing trading strategy on market " +
|
|
154
|
-
f"data {market_data[
|
|
163
|
+
f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
|
|
155
164
|
)
|
|
156
165
|
|
|
157
166
|
if __name__ == "__main__":
|
|
158
|
-
app.add_portfolio_configuration(BacktestPortfolioConfiguration(
|
|
159
|
-
unallocated=400,
|
|
160
|
-
market="BITVAVO",
|
|
161
|
-
trading_symbol="EUR",
|
|
162
|
-
))
|
|
163
167
|
backtest_report = app.backtest(
|
|
164
168
|
start_date=datetime(2023, 11, 12) - timedelta(days=10),
|
|
165
169
|
end_date=datetime(2023, 11, 12),
|
|
@@ -255,13 +259,20 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
|
|
|
255
259
|
This should allow you to connect to a lot of brokers/exchanges.
|
|
256
260
|
|
|
257
261
|
```python
|
|
258
|
-
from investing_algorithm_framework import App, PortfolioConfiguration
|
|
262
|
+
from investing_algorithm_framework import App, PortfolioConfiguration, \
|
|
263
|
+
MarketCredential
|
|
259
264
|
app = App()
|
|
265
|
+
app.add_market_credential(
|
|
266
|
+
MarketCredential(
|
|
267
|
+
market="<your market>",
|
|
268
|
+
api_key="<your api key>",
|
|
269
|
+
secret_key="<your secret key>",
|
|
270
|
+
)
|
|
271
|
+
)
|
|
260
272
|
app.add_portfolio_configuration(
|
|
261
273
|
PortfolioConfiguration(
|
|
262
|
-
market="
|
|
263
|
-
|
|
264
|
-
secret_key="xxxx",
|
|
274
|
+
market="<your market>",
|
|
275
|
+
initial_balance=400,
|
|
265
276
|
track_from="01/01/2022",
|
|
266
277
|
trading_symbol="EUR"
|
|
267
278
|
)
|
|
@@ -27,12 +27,11 @@ import pathlib
|
|
|
27
27
|
from datetime import datetime, timedelta
|
|
28
28
|
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
|
|
29
29
|
RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
|
|
30
|
-
CCXTTickerMarketDataSource
|
|
30
|
+
CCXTTickerMarketDataSource, MarketCredential
|
|
31
31
|
|
|
32
32
|
# Define market data sources
|
|
33
|
-
# OHLCV data
|
|
34
33
|
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
35
|
-
identifier="BTC",
|
|
34
|
+
identifier="BTC-ohlcv",
|
|
36
35
|
market="BITVAVO",
|
|
37
36
|
symbol="BTC/EUR",
|
|
38
37
|
timeframe="2h",
|
|
@@ -40,19 +39,23 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
|
40
39
|
)
|
|
41
40
|
# Ticker data for orders, trades and positions
|
|
42
41
|
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
43
|
-
identifier="BTC",
|
|
42
|
+
identifier="BTC-ticker",
|
|
44
43
|
market="BITVAVO",
|
|
45
44
|
symbol="BTC/EUR",
|
|
46
45
|
)
|
|
47
46
|
app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
|
|
48
47
|
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
|
|
49
48
|
app.add_market_data_source(bitvavo_btc_eur_ticker)
|
|
49
|
+
app.add_market_credential(MarketCredential(
|
|
50
|
+
market="bitvavo",
|
|
51
|
+
api_key="<your api key>",
|
|
52
|
+
secret_key="<your secret key>",
|
|
53
|
+
))
|
|
50
54
|
app.add_portfolio_configuration(
|
|
51
55
|
PortfolioConfiguration(
|
|
52
|
-
market="
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
trading_symbol="EUR"
|
|
56
|
+
market="bitvavo",
|
|
57
|
+
trading_symbol="EUR",
|
|
58
|
+
initial_balance=400
|
|
56
59
|
)
|
|
57
60
|
)
|
|
58
61
|
|
|
@@ -62,12 +65,12 @@ app.add_portfolio_configuration(
|
|
|
62
65
|
time_unit=TimeUnit.HOUR,
|
|
63
66
|
interval=2,
|
|
64
67
|
# Specify market data sources that need to be passed to the strategy
|
|
65
|
-
market_data_sources=[
|
|
68
|
+
market_data_sources=["BTC-ticker", "BTC-ohlcv"]
|
|
66
69
|
)
|
|
67
|
-
def perform_strategy(algorithm: Algorithm, market_data):
|
|
70
|
+
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
68
71
|
print(
|
|
69
72
|
f"Performing trading strategy on market " +
|
|
70
|
-
f"data {market_data[
|
|
73
|
+
f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
|
|
71
74
|
)
|
|
72
75
|
|
|
73
76
|
if __name__ == "__main__":
|
|
@@ -85,19 +88,19 @@ import pathlib
|
|
|
85
88
|
from datetime import datetime, timedelta
|
|
86
89
|
from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY, \
|
|
87
90
|
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, pretty_print_backtest, \
|
|
88
|
-
CCXTTickerMarketDataSource,
|
|
91
|
+
CCXTTickerMarketDataSource, PortfolioConfiguration
|
|
89
92
|
|
|
90
93
|
# Define market data sources
|
|
91
94
|
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
92
|
-
identifier="BTC",
|
|
93
|
-
market="
|
|
95
|
+
identifier="BTC-ohlcv",
|
|
96
|
+
market="bitvavo",
|
|
94
97
|
symbol="BTC/EUR",
|
|
95
98
|
timeframe="2h",
|
|
96
99
|
start_date_func=lambda : datetime.utcnow() - timedelta(days=17)
|
|
97
100
|
)
|
|
98
101
|
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
99
|
-
identifier="BTC",
|
|
100
|
-
market="
|
|
102
|
+
identifier="BTC-ticker",
|
|
103
|
+
market="bitvavo",
|
|
101
104
|
symbol="BTC/EUR",
|
|
102
105
|
backtest_timeframe="2h" # We want the ticker data to
|
|
103
106
|
# be sampled every 2 hours, inline with the strategy interval
|
|
@@ -105,24 +108,25 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
|
105
108
|
app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
|
|
106
109
|
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
|
|
107
110
|
app.add_market_data_source(bitvavo_btc_eur_ticker)
|
|
111
|
+
app.add_portfolio_configuration(PortfolioConfiguration(
|
|
112
|
+
initial_balance=400,
|
|
113
|
+
market="bitvavo",
|
|
114
|
+
trading_symbol="EUR",
|
|
115
|
+
))
|
|
116
|
+
|
|
108
117
|
|
|
109
118
|
@app.strategy(
|
|
110
119
|
time_unit=TimeUnit.HOUR,
|
|
111
120
|
interval=2,
|
|
112
|
-
market_data_sources=[
|
|
121
|
+
market_data_sources=["BTC-ticker", "BTC-ohlcv"]
|
|
113
122
|
)
|
|
114
|
-
def perform_strategy(algorithm: Algorithm, market_data):
|
|
123
|
+
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
115
124
|
print(
|
|
116
125
|
f"Performing trading strategy on market " +
|
|
117
|
-
f"data {market_data[
|
|
126
|
+
f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
|
|
118
127
|
)
|
|
119
128
|
|
|
120
129
|
if __name__ == "__main__":
|
|
121
|
-
app.add_portfolio_configuration(BacktestPortfolioConfiguration(
|
|
122
|
-
unallocated=400,
|
|
123
|
-
market="BITVAVO",
|
|
124
|
-
trading_symbol="EUR",
|
|
125
|
-
))
|
|
126
130
|
backtest_report = app.backtest(
|
|
127
131
|
start_date=datetime(2023, 11, 12) - timedelta(days=10),
|
|
128
132
|
end_date=datetime(2023, 11, 12),
|
|
@@ -218,13 +222,20 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
|
|
|
218
222
|
This should allow you to connect to a lot of brokers/exchanges.
|
|
219
223
|
|
|
220
224
|
```python
|
|
221
|
-
from investing_algorithm_framework import App, PortfolioConfiguration
|
|
225
|
+
from investing_algorithm_framework import App, PortfolioConfiguration, \
|
|
226
|
+
MarketCredential
|
|
222
227
|
app = App()
|
|
228
|
+
app.add_market_credential(
|
|
229
|
+
MarketCredential(
|
|
230
|
+
market="<your market>",
|
|
231
|
+
api_key="<your api key>",
|
|
232
|
+
secret_key="<your secret key>",
|
|
233
|
+
)
|
|
234
|
+
)
|
|
223
235
|
app.add_portfolio_configuration(
|
|
224
236
|
PortfolioConfiguration(
|
|
225
|
-
market="
|
|
226
|
-
|
|
227
|
-
secret_key="xxxx",
|
|
237
|
+
market="<your market>",
|
|
238
|
+
initial_balance=400,
|
|
228
239
|
track_from="01/01/2022",
|
|
229
240
|
trading_symbol="EUR"
|
|
230
241
|
)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from investing_algorithm_framework.app import App, Algorithm
|
|
2
2
|
from .create_app import create_app
|
|
3
3
|
from investing_algorithm_framework.domain import ApiException, \
|
|
4
|
-
TradingDataType,
|
|
4
|
+
TradingDataType, TradingTimeFrame, OrderType,\
|
|
5
5
|
OrderStatus, OrderSide, Config, TimeUnit, TimeInterval, Order, Portfolio, \
|
|
6
|
-
Position, TimeFrame, BACKTESTING_INDEX_DATETIME
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
BacktestPortfolioConfiguration
|
|
6
|
+
Position, TimeFrame, BACKTESTING_INDEX_DATETIME, MarketCredential, \
|
|
7
|
+
PortfolioConfiguration, RESOURCE_DIRECTORY, pretty_print_backtest, \
|
|
8
|
+
Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, \
|
|
9
|
+
TickerMarketDataSource, MarketService
|
|
11
10
|
from investing_algorithm_framework.app import TradingStrategy, \
|
|
12
11
|
StatelessAction, Task
|
|
13
12
|
from investing_algorithm_framework.infrastructure import \
|
|
@@ -22,10 +21,7 @@ __all__ = [
|
|
|
22
21
|
"create_app",
|
|
23
22
|
"ApiException",
|
|
24
23
|
"TradingDataType",
|
|
25
|
-
"OrderBook",
|
|
26
|
-
"Ticker",
|
|
27
24
|
"TradingTimeFrame",
|
|
28
|
-
"OHLCV",
|
|
29
25
|
"OrderType",
|
|
30
26
|
"OrderStatus",
|
|
31
27
|
"OrderSide",
|
|
@@ -49,7 +45,8 @@ __all__ = [
|
|
|
49
45
|
"OHLCVMarketDataSource",
|
|
50
46
|
"OrderBookMarketDataSource",
|
|
51
47
|
"TickerMarketDataSource",
|
|
52
|
-
"BacktestPortfolioConfiguration",
|
|
53
48
|
"CSVOHLCVMarketDataSource",
|
|
54
49
|
"CSVTickerMarketDataSource",
|
|
50
|
+
"MarketCredential",
|
|
51
|
+
"MarketService"
|
|
55
52
|
]
|
|
@@ -3,8 +3,10 @@ from typing import List
|
|
|
3
3
|
|
|
4
4
|
from investing_algorithm_framework.domain import OrderStatus, OrderFee, \
|
|
5
5
|
Position, Order, Portfolio, OrderType, OrderSide, ApiException, \
|
|
6
|
-
BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, Trade, \
|
|
7
|
-
|
|
6
|
+
BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, Trade, PeekableQueue, \
|
|
7
|
+
MarketService
|
|
8
|
+
from investing_algorithm_framework.services import MarketCredentialService, \
|
|
9
|
+
MarketDataSourceService
|
|
8
10
|
|
|
9
11
|
logger = logging.getLogger("investing_algorithm_framework")
|
|
10
12
|
|
|
@@ -20,16 +22,22 @@ class Algorithm:
|
|
|
20
22
|
order_service,
|
|
21
23
|
market_service,
|
|
22
24
|
strategy_orchestrator_service,
|
|
25
|
+
market_credential_service,
|
|
26
|
+
market_data_source_service
|
|
23
27
|
):
|
|
24
28
|
self.portfolio_service = portfolio_service
|
|
25
29
|
self.position_service = position_service
|
|
26
30
|
self.order_service = order_service
|
|
27
|
-
self.
|
|
31
|
+
self._market_service: MarketService = market_service
|
|
28
32
|
self.configuration_service = configuration_service
|
|
29
33
|
self.portfolio_configuration_service = portfolio_configuration_service
|
|
30
34
|
self.strategy_orchestrator_service = strategy_orchestrator_service
|
|
31
|
-
self._market_data_sources =
|
|
35
|
+
self._market_data_sources = {}
|
|
32
36
|
self._strategies = []
|
|
37
|
+
self._market_credential_service: MarketCredentialService \
|
|
38
|
+
= market_credential_service
|
|
39
|
+
self._market_data_source_service: MarketDataSourceService \
|
|
40
|
+
= market_data_source_service
|
|
33
41
|
|
|
34
42
|
def start(self, number_of_iterations=None, stateless=False):
|
|
35
43
|
|
|
@@ -51,16 +59,16 @@ class Algorithm:
|
|
|
51
59
|
self.strategy_orchestrator_service.run_pending_jobs()
|
|
52
60
|
|
|
53
61
|
def create_order(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
self,
|
|
63
|
+
target_symbol,
|
|
64
|
+
price,
|
|
65
|
+
order_type,
|
|
66
|
+
order_side,
|
|
67
|
+
amount,
|
|
68
|
+
market=None,
|
|
69
|
+
execute=True,
|
|
70
|
+
validate=True,
|
|
71
|
+
sync=True
|
|
64
72
|
):
|
|
65
73
|
portfolio = self.portfolio_service.find({"market": market})
|
|
66
74
|
order_data = {
|
|
@@ -84,18 +92,18 @@ class Algorithm:
|
|
|
84
92
|
)
|
|
85
93
|
|
|
86
94
|
def create_limit_order(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
self,
|
|
96
|
+
target_symbol,
|
|
97
|
+
price,
|
|
98
|
+
order_side,
|
|
99
|
+
amount=None,
|
|
100
|
+
percentage_of_portfolio=None,
|
|
101
|
+
percentage_of_position=None,
|
|
102
|
+
precision=None,
|
|
103
|
+
market=None,
|
|
104
|
+
execute=True,
|
|
105
|
+
validate=True,
|
|
106
|
+
sync=True
|
|
99
107
|
):
|
|
100
108
|
portfolio = self.portfolio_service.find({"market": market})
|
|
101
109
|
|
|
@@ -455,10 +463,6 @@ class Algorithm:
|
|
|
455
463
|
portfolio = self.portfolio_service.find(
|
|
456
464
|
{"market": market, "identifier": identifier}
|
|
457
465
|
)
|
|
458
|
-
portfolio_config = self.portfolio_configuration_service.find(
|
|
459
|
-
{"portfolio": portfolio.id}
|
|
460
|
-
)
|
|
461
|
-
self.market_service.initialize(portfolio_config)
|
|
462
466
|
position = self.position_service.find(
|
|
463
467
|
{"portfolio": portfolio.id, "symbol": symbol}
|
|
464
468
|
)
|
|
@@ -476,10 +480,8 @@ class Algorithm:
|
|
|
476
480
|
self.order_service.cancel_order(order)
|
|
477
481
|
|
|
478
482
|
symbol = f"{symbol.upper()}/{portfolio.trading_symbol.upper()}"
|
|
479
|
-
ticker = self.
|
|
480
|
-
.
|
|
481
|
-
backtest_index_date=self.config.get(BACKTESTING_INDEX_DATETIME)
|
|
482
|
-
)
|
|
483
|
+
ticker = self._market_data_source_service\
|
|
484
|
+
.get_ticker(market=portfolio.market, symbol=symbol)
|
|
483
485
|
self.create_limit_order(
|
|
484
486
|
target_symbol=position.symbol,
|
|
485
487
|
amount=position.get_amount(),
|
|
@@ -678,11 +680,8 @@ class Algorithm:
|
|
|
678
680
|
|
|
679
681
|
for buy_order in buy_orders:
|
|
680
682
|
symbol = buy_order.get_symbol()
|
|
681
|
-
ticker = self.
|
|
682
|
-
portfolio.market
|
|
683
|
-
).get_data(
|
|
684
|
-
backtest_index_date=self.config
|
|
685
|
-
.get(BACKTESTING_INDEX_DATETIME)
|
|
683
|
+
ticker = self._market_data_source_service.get_ticker(
|
|
684
|
+
symbol=symbol, market=portfolio.market
|
|
686
685
|
)
|
|
687
686
|
trades.append(
|
|
688
687
|
Trade(
|
|
@@ -726,6 +725,7 @@ class Algorithm:
|
|
|
726
725
|
def get_open_trades(self, target_symbol=None):
|
|
727
726
|
portfolios = self.portfolio_service.get_all()
|
|
728
727
|
trades = []
|
|
728
|
+
|
|
729
729
|
for portfolio in portfolios:
|
|
730
730
|
|
|
731
731
|
if target_symbol is not None:
|
|
@@ -735,46 +735,56 @@ class Algorithm:
|
|
|
735
735
|
"portfolio_id": portfolio.id,
|
|
736
736
|
"target_symbol": target_symbol
|
|
737
737
|
})
|
|
738
|
+
sell_orders = self.order_service.get_all({
|
|
739
|
+
"status": OrderStatus.OPEN.value,
|
|
740
|
+
"order_side": OrderSide.SELL.value,
|
|
741
|
+
"portfolio_id": portfolio.id,
|
|
742
|
+
"target_symbol": target_symbol
|
|
743
|
+
})
|
|
738
744
|
else:
|
|
739
745
|
buy_orders = self.order_service.get_all({
|
|
740
746
|
"status": OrderStatus.CLOSED.value,
|
|
741
747
|
"order_side": OrderSide.BUY.value,
|
|
742
748
|
"portfolio_id": portfolio.id
|
|
743
749
|
})
|
|
750
|
+
sell_orders = self.order_service.get_all({
|
|
751
|
+
"status": OrderStatus.OPEN.value,
|
|
752
|
+
"order_side": OrderSide.SELL.value,
|
|
753
|
+
"portfolio_id": portfolio.id
|
|
754
|
+
})
|
|
755
|
+
|
|
744
756
|
buy_orders = [
|
|
745
757
|
buy_order for buy_order in buy_orders
|
|
746
758
|
if buy_order.get_trade_closed_at() is None
|
|
747
759
|
]
|
|
748
|
-
|
|
749
|
-
"status": OrderStatus.OPEN.value,
|
|
750
|
-
"order_side": OrderSide.SELL.value,
|
|
751
|
-
"portfolio_id": portfolio.id
|
|
752
|
-
})
|
|
753
|
-
sell_amount = sum([order.get_amount() for order in sell_orders])
|
|
760
|
+
sell_amount = sum([order.amount for order in sell_orders])
|
|
754
761
|
|
|
755
762
|
# Subtract the amount of the open sell orders
|
|
756
763
|
# from the amount of the buy orders
|
|
757
|
-
|
|
758
|
-
first_order = buy_orders[0]
|
|
764
|
+
buy_orders_queue = PeekableQueue()
|
|
759
765
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
766
|
+
for buy_order in buy_orders:
|
|
767
|
+
buy_orders_queue.enqueue(buy_order)
|
|
768
|
+
|
|
769
|
+
while sell_amount > 0 and not buy_orders_queue.is_empty():
|
|
770
|
+
first_buy_order = buy_orders_queue.peek()
|
|
771
|
+
available = first_buy_order.get_filled() \
|
|
772
|
+
- first_buy_order.get_trade_closed_amount()
|
|
773
|
+
|
|
774
|
+
if available > sell_amount:
|
|
775
|
+
remaining = available - sell_amount
|
|
764
776
|
sell_amount = 0
|
|
777
|
+
first_buy_order.set_filled(remaining)
|
|
765
778
|
else:
|
|
766
|
-
sell_amount = sell_amount -
|
|
767
|
-
|
|
779
|
+
sell_amount = sell_amount - available
|
|
780
|
+
buy_orders_queue.dequeue()
|
|
768
781
|
|
|
769
|
-
for buy_order in
|
|
782
|
+
for buy_order in buy_orders_queue:
|
|
770
783
|
symbol = buy_order.get_symbol()
|
|
771
784
|
|
|
772
785
|
try:
|
|
773
|
-
ticker = self.
|
|
774
|
-
portfolio.market
|
|
775
|
-
).get_data(
|
|
776
|
-
backtest_index_date=self.config
|
|
777
|
-
.get(BACKTESTING_INDEX_DATETIME)
|
|
786
|
+
ticker = self._market_data_source_service.get_ticker(
|
|
787
|
+
symbol=symbol, market=portfolio.market
|
|
778
788
|
)
|
|
779
789
|
except Exception as e:
|
|
780
790
|
logger.error(e)
|
|
@@ -792,7 +802,8 @@ class Algorithm:
|
|
|
792
802
|
buy_order_id=buy_order.id,
|
|
793
803
|
target_symbol=buy_order.get_target_symbol(),
|
|
794
804
|
trading_symbol=buy_order.get_trading_symbol(),
|
|
795
|
-
amount=buy_order.
|
|
805
|
+
amount=buy_order.get_filled()
|
|
806
|
+
- buy_order.get_trade_closed_amount(),
|
|
796
807
|
open_price=buy_order.get_price(),
|
|
797
808
|
opened_at=buy_order.get_created_at(),
|
|
798
809
|
current_price=ticker["bid"]
|
|
@@ -829,84 +840,11 @@ class Algorithm:
|
|
|
829
840
|
|
|
830
841
|
symbol = f"{order.get_target_symbol().upper()}" \
|
|
831
842
|
f"/{order.get_trading_symbol().upper()}"
|
|
832
|
-
ticker = self.
|
|
833
|
-
.
|
|
834
|
-
backtest_index_date=self.config
|
|
835
|
-
.get(BACKTESTING_INDEX_DATETIME)
|
|
836
|
-
)
|
|
843
|
+
ticker = self._market_data_source_service\
|
|
844
|
+
.get_ticker(symbol=symbol, market=portfolio.market)
|
|
837
845
|
self.create_limit_order(
|
|
838
846
|
target_symbol=order.target_symbol,
|
|
839
847
|
amount=amount,
|
|
840
848
|
order_side=OrderSide.SELL.value,
|
|
841
849
|
price=ticker["bid"],
|
|
842
850
|
)
|
|
843
|
-
|
|
844
|
-
def get_market_data_sources(self):
|
|
845
|
-
market_data_sources = []
|
|
846
|
-
|
|
847
|
-
for key in self._market_data_sources.keys():
|
|
848
|
-
market_data_sources.append(self._market_data_sources[key])
|
|
849
|
-
|
|
850
|
-
return market_data_sources
|
|
851
|
-
|
|
852
|
-
def get_market_data_source(self, identifier):
|
|
853
|
-
|
|
854
|
-
if identifier in self._market_data_sources:
|
|
855
|
-
return self._market_data_sources[identifier]
|
|
856
|
-
|
|
857
|
-
raise ApiException(
|
|
858
|
-
f"No market data source found for with identifier {identifier}."
|
|
859
|
-
)
|
|
860
|
-
|
|
861
|
-
def set_market_data_sources(self, market_data_sources):
|
|
862
|
-
self._market_data_sources = {}
|
|
863
|
-
|
|
864
|
-
for market_data_source in market_data_sources:
|
|
865
|
-
self._market_data_sources[market_data_source.identifier] = \
|
|
866
|
-
market_data_source
|
|
867
|
-
|
|
868
|
-
def get_ticker_market_data_source(self, market, symbol):
|
|
869
|
-
|
|
870
|
-
for identifier in self._market_data_sources:
|
|
871
|
-
market_data_source = self._market_data_sources[identifier]
|
|
872
|
-
|
|
873
|
-
if isinstance(market_data_source, TickerMarketDataSource):
|
|
874
|
-
|
|
875
|
-
if market_data_source.symbol == symbol \
|
|
876
|
-
and market_data_source.market == market:
|
|
877
|
-
return market_data_source
|
|
878
|
-
|
|
879
|
-
raise ApiException(
|
|
880
|
-
f"No ticker market data source found for with symbol {symbol} "
|
|
881
|
-
f"and market {market}."
|
|
882
|
-
)
|
|
883
|
-
|
|
884
|
-
def get_ohlcv_market_data_source(self, market, symbol):
|
|
885
|
-
|
|
886
|
-
for market_data_source in self._market_data_sources.values():
|
|
887
|
-
|
|
888
|
-
if isinstance(market_data_source, OHLCVMarketDataSource):
|
|
889
|
-
|
|
890
|
-
if market_data_source.symbol == symbol \
|
|
891
|
-
and market_data_source.market == market:
|
|
892
|
-
return market_data_source
|
|
893
|
-
|
|
894
|
-
raise ApiException(
|
|
895
|
-
f"No OHLCV market data source found for with symbol {symbol} "
|
|
896
|
-
f"and market {market}."
|
|
897
|
-
)
|
|
898
|
-
|
|
899
|
-
def get_order_book_market_data_source(self, market, symbol):
|
|
900
|
-
|
|
901
|
-
for market_data_source in self._market_data_sources.values():
|
|
902
|
-
|
|
903
|
-
if isinstance(market_data_source, OrderBookMarketDataSource):
|
|
904
|
-
|
|
905
|
-
if market_data_source.symbol == symbol \
|
|
906
|
-
and market_data_source.market == market:
|
|
907
|
-
return market_data_source
|
|
908
|
-
|
|
909
|
-
raise ApiException(
|
|
910
|
-
f"No OHLCV market data source found for with symbol {symbol} "
|
|
911
|
-
f"and market {market}."
|
|
912
|
-
)
|