investing-algorithm-framework 3.7.0__py3-none-any.whl → 7.19.15__py3-none-any.whl
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.
Potentially problematic release.
This version of investing-algorithm-framework might be problematic. Click here for more details.
- investing_algorithm_framework/__init__.py +168 -45
- investing_algorithm_framework/app/__init__.py +32 -1
- investing_algorithm_framework/app/algorithm/__init__.py +7 -0
- investing_algorithm_framework/app/algorithm/algorithm.py +239 -0
- investing_algorithm_framework/app/algorithm/algorithm_factory.py +114 -0
- investing_algorithm_framework/app/analysis/__init__.py +15 -0
- investing_algorithm_framework/app/analysis/backtest_data_ranges.py +121 -0
- investing_algorithm_framework/app/analysis/backtest_utils.py +107 -0
- investing_algorithm_framework/app/analysis/permutation.py +116 -0
- investing_algorithm_framework/app/analysis/ranking.py +297 -0
- investing_algorithm_framework/app/app.py +1933 -589
- investing_algorithm_framework/app/app_hook.py +28 -0
- investing_algorithm_framework/app/context.py +1725 -0
- investing_algorithm_framework/app/eventloop.py +590 -0
- investing_algorithm_framework/app/reporting/__init__.py +27 -0
- investing_algorithm_framework/app/reporting/ascii.py +921 -0
- investing_algorithm_framework/app/reporting/backtest_report.py +349 -0
- investing_algorithm_framework/app/reporting/charts/__init__.py +19 -0
- investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +66 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve.py +37 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +74 -0
- investing_algorithm_framework/app/reporting/charts/line_chart.py +11 -0
- investing_algorithm_framework/app/reporting/charts/monthly_returns_heatmap.py +70 -0
- investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +51 -0
- investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +79 -0
- investing_algorithm_framework/app/reporting/charts/yearly_returns_barchart.py +55 -0
- investing_algorithm_framework/app/reporting/generate.py +185 -0
- investing_algorithm_framework/app/reporting/tables/__init__.py +11 -0
- investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +217 -0
- investing_algorithm_framework/app/reporting/tables/stop_loss_table.py +0 -0
- investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +80 -0
- investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +147 -0
- investing_algorithm_framework/app/reporting/tables/trades_table.py +75 -0
- investing_algorithm_framework/app/reporting/tables/utils.py +29 -0
- investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +154 -0
- investing_algorithm_framework/app/stateless/action_handlers/__init__.py +4 -2
- investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +1 -1
- investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +1 -1
- investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +14 -7
- investing_algorithm_framework/app/strategy.py +664 -84
- investing_algorithm_framework/app/task.py +5 -3
- investing_algorithm_framework/app/web/__init__.py +2 -1
- investing_algorithm_framework/app/web/create_app.py +4 -2
- investing_algorithm_framework/cli/__init__.py +0 -0
- investing_algorithm_framework/cli/cli.py +226 -0
- investing_algorithm_framework/cli/deploy_to_aws_lambda.py +501 -0
- investing_algorithm_framework/cli/deploy_to_azure_function.py +718 -0
- investing_algorithm_framework/cli/initialize_app.py +603 -0
- investing_algorithm_framework/cli/templates/.gitignore.template +178 -0
- investing_algorithm_framework/cli/templates/app.py.template +18 -0
- investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +48 -0
- investing_algorithm_framework/cli/templates/app_azure_function.py.template +14 -0
- investing_algorithm_framework/cli/templates/app_web.py.template +18 -0
- investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
- investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
- investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +110 -0
- investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -0
- investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +65 -0
- investing_algorithm_framework/cli/templates/azure_function_host.json.template +15 -0
- investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +8 -0
- investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +3 -0
- investing_algorithm_framework/cli/templates/data_providers.py.template +17 -0
- investing_algorithm_framework/cli/templates/env.example.template +2 -0
- investing_algorithm_framework/cli/templates/env_azure_function.example.template +4 -0
- investing_algorithm_framework/cli/templates/market_data_providers.py.template +9 -0
- investing_algorithm_framework/cli/templates/readme.md.template +135 -0
- investing_algorithm_framework/cli/templates/requirements.txt.template +2 -0
- investing_algorithm_framework/cli/templates/run_backtest.py.template +20 -0
- investing_algorithm_framework/cli/templates/strategy.py.template +124 -0
- investing_algorithm_framework/create_app.py +40 -6
- investing_algorithm_framework/dependency_container.py +72 -56
- investing_algorithm_framework/domain/__init__.py +71 -47
- investing_algorithm_framework/domain/backtesting/__init__.py +21 -0
- investing_algorithm_framework/domain/backtesting/backtest.py +503 -0
- investing_algorithm_framework/domain/backtesting/backtest_date_range.py +96 -0
- investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +242 -0
- investing_algorithm_framework/domain/backtesting/backtest_metrics.py +459 -0
- investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
- investing_algorithm_framework/domain/backtesting/backtest_run.py +605 -0
- investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
- investing_algorithm_framework/domain/backtesting/combine_backtests.py +280 -0
- investing_algorithm_framework/domain/config.py +59 -91
- investing_algorithm_framework/domain/constants.py +13 -38
- investing_algorithm_framework/domain/data_provider.py +334 -0
- investing_algorithm_framework/domain/data_structures.py +3 -2
- investing_algorithm_framework/domain/exceptions.py +51 -1
- investing_algorithm_framework/domain/models/__init__.py +17 -12
- investing_algorithm_framework/domain/models/data/__init__.py +7 -0
- investing_algorithm_framework/domain/models/data/data_source.py +214 -0
- investing_algorithm_framework/domain/models/data/data_type.py +46 -0
- investing_algorithm_framework/domain/models/event.py +35 -0
- investing_algorithm_framework/domain/models/market/market_credential.py +55 -1
- investing_algorithm_framework/domain/models/order/order.py +77 -83
- investing_algorithm_framework/domain/models/order/order_status.py +2 -2
- investing_algorithm_framework/domain/models/order/order_type.py +1 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio.py +81 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +26 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +108 -11
- investing_algorithm_framework/domain/models/position/__init__.py +2 -1
- investing_algorithm_framework/domain/models/position/position.py +12 -0
- investing_algorithm_framework/domain/models/position/position_size.py +41 -0
- investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
- investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
- investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
- investing_algorithm_framework/domain/models/snapshot_interval.py +45 -0
- investing_algorithm_framework/domain/models/strategy_profile.py +19 -151
- investing_algorithm_framework/domain/models/time_frame.py +37 -0
- investing_algorithm_framework/domain/models/time_interval.py +33 -0
- investing_algorithm_framework/domain/models/time_unit.py +66 -2
- investing_algorithm_framework/domain/models/trade/__init__.py +8 -1
- investing_algorithm_framework/domain/models/trade/trade.py +295 -171
- investing_algorithm_framework/domain/models/trade/trade_status.py +9 -2
- investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +332 -0
- investing_algorithm_framework/domain/models/trade/trade_take_profit.py +365 -0
- investing_algorithm_framework/domain/order_executor.py +112 -0
- investing_algorithm_framework/domain/portfolio_provider.py +118 -0
- investing_algorithm_framework/domain/services/__init__.py +2 -9
- investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -6
- investing_algorithm_framework/domain/services/state_handler.py +38 -0
- investing_algorithm_framework/domain/strategy.py +1 -29
- investing_algorithm_framework/domain/utils/__init__.py +12 -7
- investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
- investing_algorithm_framework/domain/utils/dates.py +57 -0
- investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
- investing_algorithm_framework/domain/utils/polars.py +53 -0
- investing_algorithm_framework/domain/utils/random.py +29 -0
- investing_algorithm_framework/download_data.py +108 -0
- investing_algorithm_framework/infrastructure/__init__.py +31 -18
- investing_algorithm_framework/infrastructure/data_providers/__init__.py +36 -0
- investing_algorithm_framework/infrastructure/data_providers/ccxt.py +1143 -0
- investing_algorithm_framework/infrastructure/data_providers/csv.py +568 -0
- investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
- investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
- investing_algorithm_framework/infrastructure/database/sql_alchemy.py +86 -12
- investing_algorithm_framework/infrastructure/models/__init__.py +6 -11
- investing_algorithm_framework/infrastructure/models/order/__init__.py +2 -1
- investing_algorithm_framework/infrastructure/models/order/order.py +35 -49
- investing_algorithm_framework/infrastructure/models/order/order_metadata.py +44 -0
- investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
- investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +1 -1
- investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +8 -0
- investing_algorithm_framework/infrastructure/models/portfolio/{portfolio.py → sql_portfolio.py} +17 -5
- investing_algorithm_framework/infrastructure/models/trades/__init__.py +9 -0
- investing_algorithm_framework/infrastructure/models/trades/trade.py +130 -0
- investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +59 -0
- investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +55 -0
- investing_algorithm_framework/infrastructure/order_executors/__init__.py +21 -0
- investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
- investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +200 -0
- investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +19 -0
- investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +199 -0
- investing_algorithm_framework/infrastructure/repositories/__init__.py +8 -0
- investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +17 -0
- investing_algorithm_framework/infrastructure/repositories/order_repository.py +5 -0
- investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +1 -1
- investing_algorithm_framework/infrastructure/repositories/position_repository.py +11 -0
- investing_algorithm_framework/infrastructure/repositories/repository.py +81 -27
- investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
- investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +29 -0
- investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +29 -0
- investing_algorithm_framework/infrastructure/services/__init__.py +4 -4
- investing_algorithm_framework/infrastructure/services/aws/__init__.py +6 -0
- investing_algorithm_framework/infrastructure/services/aws/state_handler.py +113 -0
- investing_algorithm_framework/infrastructure/services/azure/__init__.py +5 -0
- investing_algorithm_framework/infrastructure/services/azure/state_handler.py +158 -0
- investing_algorithm_framework/services/__init__.py +113 -16
- investing_algorithm_framework/services/backtesting/__init__.py +0 -7
- investing_algorithm_framework/services/backtesting/backtest_service.py +566 -359
- investing_algorithm_framework/services/configuration_service.py +77 -11
- investing_algorithm_framework/services/data_providers/__init__.py +5 -0
- investing_algorithm_framework/services/data_providers/data_provider_service.py +850 -0
- investing_algorithm_framework/services/market_credential_service.py +16 -1
- investing_algorithm_framework/services/metrics/__init__.py +114 -0
- investing_algorithm_framework/services/metrics/alpha.py +0 -0
- investing_algorithm_framework/services/metrics/beta.py +0 -0
- investing_algorithm_framework/services/metrics/cagr.py +60 -0
- investing_algorithm_framework/services/metrics/calmar_ratio.py +40 -0
- investing_algorithm_framework/services/metrics/drawdown.py +181 -0
- investing_algorithm_framework/services/metrics/equity_curve.py +24 -0
- investing_algorithm_framework/services/metrics/exposure.py +210 -0
- investing_algorithm_framework/services/metrics/generate.py +358 -0
- investing_algorithm_framework/services/metrics/mean_daily_return.py +83 -0
- investing_algorithm_framework/services/metrics/profit_factor.py +165 -0
- investing_algorithm_framework/services/metrics/recovery.py +113 -0
- investing_algorithm_framework/services/metrics/returns.py +452 -0
- investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
- investing_algorithm_framework/services/metrics/sharpe_ratio.py +137 -0
- investing_algorithm_framework/services/metrics/sortino_ratio.py +74 -0
- investing_algorithm_framework/services/metrics/standard_deviation.py +157 -0
- investing_algorithm_framework/services/metrics/trades.py +500 -0
- investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
- investing_algorithm_framework/services/metrics/ulcer.py +0 -0
- investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
- investing_algorithm_framework/services/metrics/volatility.py +97 -0
- investing_algorithm_framework/services/metrics/win_rate.py +177 -0
- investing_algorithm_framework/services/order_service/__init__.py +3 -1
- investing_algorithm_framework/services/order_service/order_backtest_service.py +76 -89
- investing_algorithm_framework/services/order_service/order_executor_lookup.py +110 -0
- investing_algorithm_framework/services/order_service/order_service.py +407 -326
- investing_algorithm_framework/services/portfolios/__init__.py +3 -1
- investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +37 -3
- investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +22 -8
- investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +106 -0
- investing_algorithm_framework/services/portfolios/portfolio_service.py +96 -28
- investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +97 -28
- investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +116 -313
- investing_algorithm_framework/services/positions/__init__.py +7 -0
- investing_algorithm_framework/services/positions/position_service.py +210 -0
- investing_algorithm_framework/services/repository_service.py +8 -2
- investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
- investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +113 -0
- investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
- investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
- investing_algorithm_framework/services/trade_service/__init__.py +7 -1
- investing_algorithm_framework/services/trade_service/trade_service.py +1013 -315
- investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
- investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
- investing_algorithm_framework-7.19.15.dist-info/METADATA +537 -0
- investing_algorithm_framework-7.19.15.dist-info/RECORD +263 -0
- investing_algorithm_framework-7.19.15.dist-info/entry_points.txt +3 -0
- investing_algorithm_framework/app/algorithm.py +0 -1105
- investing_algorithm_framework/domain/graphs.py +0 -382
- investing_algorithm_framework/domain/metrics/__init__.py +0 -6
- investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -11
- investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -43
- investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -120
- investing_algorithm_framework/domain/models/backtesting/backtest_report.py +0 -580
- investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -243
- investing_algorithm_framework/domain/models/trading_data_types.py +0 -47
- investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
- investing_algorithm_framework/domain/services/market_data_sources.py +0 -344
- investing_algorithm_framework/domain/services/market_service.py +0 -153
- investing_algorithm_framework/domain/singleton.py +0 -9
- investing_algorithm_framework/domain/utils/backtesting.py +0 -472
- investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -12
- investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -559
- investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -254
- investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -47
- investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -5
- investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -455
- investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -7
- investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -2
- investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -350
- investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -53
- investing_algorithm_framework/services/backtesting/graphs.py +0 -61
- investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -8
- investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -150
- investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -189
- investing_algorithm_framework/services/position_service.py +0 -31
- investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -264
- investing_algorithm_framework-3.7.0.dist-info/METADATA +0 -339
- investing_algorithm_framework-3.7.0.dist-info/RECORD +0 -147
- /investing_algorithm_framework/{domain → services}/metrics/price_efficiency.py +0 -0
- /investing_algorithm_framework/services/{position_snapshot_service.py → positions/position_snapshot_service.py} +0 -0
- {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/LICENSE +0 -0
- {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/WHEEL +0 -0
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import logging
|
|
3
|
-
import os
|
|
4
|
-
from abc import abstractmethod, ABC
|
|
5
|
-
from datetime import datetime, timedelta
|
|
6
|
-
|
|
7
|
-
import polars
|
|
8
|
-
|
|
9
|
-
from investing_algorithm_framework.domain import TimeFrame, \
|
|
10
|
-
OperationalException
|
|
11
|
-
|
|
12
|
-
logger = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class BacktestMarketDataSource(ABC):
|
|
16
|
-
column_names = []
|
|
17
|
-
|
|
18
|
-
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
identifier,
|
|
21
|
-
market,
|
|
22
|
-
symbol,
|
|
23
|
-
backtest_data_start_date=None,
|
|
24
|
-
backtest_data_index_date=None,
|
|
25
|
-
):
|
|
26
|
-
self._identifier = identifier
|
|
27
|
-
self._market = market
|
|
28
|
-
self._symbol = symbol
|
|
29
|
-
self._backtest_data_start_date = backtest_data_start_date
|
|
30
|
-
self._backtest_data_index_date = backtest_data_index_date
|
|
31
|
-
|
|
32
|
-
@property
|
|
33
|
-
def config(self):
|
|
34
|
-
return self._config
|
|
35
|
-
|
|
36
|
-
@config.setter
|
|
37
|
-
def config(self, value):
|
|
38
|
-
self._config = value
|
|
39
|
-
|
|
40
|
-
def _data_source_exists(self, file_path):
|
|
41
|
-
"""
|
|
42
|
-
Function to check if the data source exists.
|
|
43
|
-
This function will check if the file exists and if the column names
|
|
44
|
-
are correct.
|
|
45
|
-
|
|
46
|
-
This function will return True if the file exists and the column names
|
|
47
|
-
are correct. If the file does not exist or the column names are not
|
|
48
|
-
correct, this function will return False.
|
|
49
|
-
|
|
50
|
-
This function prevents the backtest datasource to download the data
|
|
51
|
-
every time the backtest is run.
|
|
52
|
-
"""
|
|
53
|
-
try:
|
|
54
|
-
if os.path.isfile(file_path):
|
|
55
|
-
df = polars.read_csv(file_path)
|
|
56
|
-
|
|
57
|
-
if df.columns != self.column_names:
|
|
58
|
-
raise OperationalException(
|
|
59
|
-
f"Wrong column names on {file_path}, required "
|
|
60
|
-
f"column names are {self.column_names}"
|
|
61
|
-
)
|
|
62
|
-
else:
|
|
63
|
-
return False
|
|
64
|
-
|
|
65
|
-
return True
|
|
66
|
-
except Exception:
|
|
67
|
-
return False
|
|
68
|
-
|
|
69
|
-
def write_data_to_file_path(self, data_file, data):
|
|
70
|
-
"""
|
|
71
|
-
Function to write data to a csv file.
|
|
72
|
-
This function will write the column names and all the data to the
|
|
73
|
-
file.
|
|
74
|
-
"""
|
|
75
|
-
with open(data_file, "w") as file:
|
|
76
|
-
column_headers = self.column_names
|
|
77
|
-
writer = csv.writer(file)
|
|
78
|
-
writer.writerow(column_headers)
|
|
79
|
-
rows = data
|
|
80
|
-
writer.writerows(rows)
|
|
81
|
-
|
|
82
|
-
@abstractmethod
|
|
83
|
-
def prepare_data(
|
|
84
|
-
self,
|
|
85
|
-
config,
|
|
86
|
-
backtest_start_date,
|
|
87
|
-
backtest_end_date,
|
|
88
|
-
**kwargs
|
|
89
|
-
):
|
|
90
|
-
pass
|
|
91
|
-
|
|
92
|
-
@abstractmethod
|
|
93
|
-
def get_data(self, **kwargs):
|
|
94
|
-
"""
|
|
95
|
-
Get data from the market data source.
|
|
96
|
-
:param kwargs: Additional arguments to get the data. Common arguments
|
|
97
|
-
- start_date: datetime
|
|
98
|
-
- end_date: datetime
|
|
99
|
-
- timeframe: str
|
|
100
|
-
- backtest_start_date: datetime
|
|
101
|
-
- backtest_end_date: datetime
|
|
102
|
-
- backtest_data_index_date: datetime
|
|
103
|
-
"""
|
|
104
|
-
pass
|
|
105
|
-
|
|
106
|
-
@property
|
|
107
|
-
def identifier(self):
|
|
108
|
-
return self._identifier
|
|
109
|
-
|
|
110
|
-
def get_identifier(self):
|
|
111
|
-
return self.identifier
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def market(self):
|
|
115
|
-
return self._market
|
|
116
|
-
|
|
117
|
-
def get_market(self):
|
|
118
|
-
return self.market
|
|
119
|
-
|
|
120
|
-
@property
|
|
121
|
-
def symbol(self):
|
|
122
|
-
return self._symbol
|
|
123
|
-
|
|
124
|
-
def get_symbol(self):
|
|
125
|
-
return self.symbol
|
|
126
|
-
|
|
127
|
-
@abstractmethod
|
|
128
|
-
def empty(self):
|
|
129
|
-
pass
|
|
130
|
-
|
|
131
|
-
@property
|
|
132
|
-
def market_credential_service(self):
|
|
133
|
-
return self._market_credential_service
|
|
134
|
-
|
|
135
|
-
@market_credential_service.setter
|
|
136
|
-
def market_credential_service(self, value):
|
|
137
|
-
self._market_credential_service = value
|
|
138
|
-
|
|
139
|
-
@property
|
|
140
|
-
def backtest_data_start_date(self):
|
|
141
|
-
return self._backtest_data_start_date
|
|
142
|
-
|
|
143
|
-
@backtest_data_start_date.setter
|
|
144
|
-
def backtest_data_start_date(self, value):
|
|
145
|
-
self._backtest_data_start_date = value
|
|
146
|
-
|
|
147
|
-
@property
|
|
148
|
-
def backtest_data_index_date(self):
|
|
149
|
-
return self._backtest_data_index_date
|
|
150
|
-
|
|
151
|
-
@backtest_data_index_date.setter
|
|
152
|
-
def backtest_data_index_date(self, value):
|
|
153
|
-
self._backtest_data_index_date = value
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
class MarketDataSource(ABC):
|
|
157
|
-
|
|
158
|
-
def __init__(
|
|
159
|
-
self,
|
|
160
|
-
identifier,
|
|
161
|
-
market,
|
|
162
|
-
symbol,
|
|
163
|
-
):
|
|
164
|
-
self._identifier = identifier
|
|
165
|
-
self._market = market
|
|
166
|
-
self._symbol = symbol
|
|
167
|
-
self._market_credential_service = None
|
|
168
|
-
self._config = None
|
|
169
|
-
|
|
170
|
-
@property
|
|
171
|
-
def config(self):
|
|
172
|
-
return self._config
|
|
173
|
-
|
|
174
|
-
@config.setter
|
|
175
|
-
def config(self, value):
|
|
176
|
-
self._config = value
|
|
177
|
-
|
|
178
|
-
def initialize(self, config):
|
|
179
|
-
pass
|
|
180
|
-
|
|
181
|
-
@property
|
|
182
|
-
def identifier(self):
|
|
183
|
-
return self._identifier
|
|
184
|
-
|
|
185
|
-
def get_identifier(self):
|
|
186
|
-
return self.identifier
|
|
187
|
-
|
|
188
|
-
@property
|
|
189
|
-
def market(self):
|
|
190
|
-
return self._market
|
|
191
|
-
|
|
192
|
-
def get_market(self):
|
|
193
|
-
return self.market
|
|
194
|
-
|
|
195
|
-
@property
|
|
196
|
-
def symbol(self):
|
|
197
|
-
return self._symbol
|
|
198
|
-
|
|
199
|
-
def get_symbol(self):
|
|
200
|
-
return self.symbol
|
|
201
|
-
|
|
202
|
-
@abstractmethod
|
|
203
|
-
def get_data(self, **kwargs):
|
|
204
|
-
"""
|
|
205
|
-
Get data from the market data source.
|
|
206
|
-
:param kwargs: Additional arguments to get the data. Common arguments
|
|
207
|
-
- start_date: datetime
|
|
208
|
-
- end_date: datetime
|
|
209
|
-
- timeframe: str
|
|
210
|
-
|
|
211
|
-
:return: Object with the data
|
|
212
|
-
"""
|
|
213
|
-
pass
|
|
214
|
-
|
|
215
|
-
@abstractmethod
|
|
216
|
-
def to_backtest_market_data_source(self) -> BacktestMarketDataSource:
|
|
217
|
-
pass
|
|
218
|
-
|
|
219
|
-
@property
|
|
220
|
-
def market_credential_service(self):
|
|
221
|
-
return self._market_credential_service
|
|
222
|
-
|
|
223
|
-
@market_credential_service.setter
|
|
224
|
-
def market_credential_service(self, value):
|
|
225
|
-
self._market_credential_service = value
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
229
|
-
"""
|
|
230
|
-
Abstract class for ohlcv market data sources.
|
|
231
|
-
"""
|
|
232
|
-
def __init__(
|
|
233
|
-
self,
|
|
234
|
-
identifier,
|
|
235
|
-
market,
|
|
236
|
-
symbol,
|
|
237
|
-
timeframe,
|
|
238
|
-
window_size=None,
|
|
239
|
-
):
|
|
240
|
-
super().__init__(
|
|
241
|
-
identifier=identifier,
|
|
242
|
-
market=market,
|
|
243
|
-
symbol=symbol,
|
|
244
|
-
)
|
|
245
|
-
self._window_size = window_size
|
|
246
|
-
|
|
247
|
-
if timeframe is not None:
|
|
248
|
-
self._timeframe = TimeFrame.from_value(timeframe)
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def timeframe(self):
|
|
252
|
-
return self._timeframe
|
|
253
|
-
|
|
254
|
-
def get_timeframe(self):
|
|
255
|
-
return self.timeframe
|
|
256
|
-
|
|
257
|
-
def create_start_date(self, end_date, timeframe, window_size):
|
|
258
|
-
minutes = TimeFrame.from_value(timeframe).amount_of_minutes
|
|
259
|
-
return end_date - timedelta(minutes=window_size * minutes)
|
|
260
|
-
|
|
261
|
-
def create_end_date(self, start_date, timeframe, window_size):
|
|
262
|
-
minutes = TimeFrame.from_value(timeframe).amount_of_minutes
|
|
263
|
-
return start_date + timedelta(minutes=window_size * minutes)
|
|
264
|
-
|
|
265
|
-
@property
|
|
266
|
-
def window_size(self):
|
|
267
|
-
return self._window_size
|
|
268
|
-
|
|
269
|
-
def get_date_ranges(
|
|
270
|
-
self,
|
|
271
|
-
start_date: datetime,
|
|
272
|
-
end_date: datetime,
|
|
273
|
-
window_size: int,
|
|
274
|
-
timeframe
|
|
275
|
-
):
|
|
276
|
-
"""
|
|
277
|
-
Function to get the date ranges of the market data source based
|
|
278
|
-
on the window size and the timeframe. The date ranges
|
|
279
|
-
will be calculated based on the start date and the end date.
|
|
280
|
-
"""
|
|
281
|
-
|
|
282
|
-
if start_date > end_date:
|
|
283
|
-
raise OperationalException(
|
|
284
|
-
"Start date must be before end date"
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
timeframe = TimeFrame.from_value(timeframe)
|
|
288
|
-
new_end_date = start_date + timedelta(
|
|
289
|
-
minutes=window_size * timeframe.amount_of_minutes
|
|
290
|
-
)
|
|
291
|
-
ranges = [(start_date, new_end_date)]
|
|
292
|
-
start_date = new_end_date
|
|
293
|
-
|
|
294
|
-
if new_end_date > end_date:
|
|
295
|
-
return [(start_date, end_date)]
|
|
296
|
-
|
|
297
|
-
while start_date < end_date:
|
|
298
|
-
new_end_date = start_date + timedelta(
|
|
299
|
-
minutes=self.window_size * timeframe.amount_of_minutes
|
|
300
|
-
)
|
|
301
|
-
|
|
302
|
-
if new_end_date > end_date:
|
|
303
|
-
new_end_date = end_date
|
|
304
|
-
|
|
305
|
-
ranges.append((start_date, new_end_date))
|
|
306
|
-
start_date = new_end_date
|
|
307
|
-
|
|
308
|
-
return ranges
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
class TickerMarketDataSource(MarketDataSource, ABC):
|
|
312
|
-
"""
|
|
313
|
-
Abstract class for ticker market data sources.
|
|
314
|
-
"""
|
|
315
|
-
|
|
316
|
-
def __init__(
|
|
317
|
-
self,
|
|
318
|
-
identifier,
|
|
319
|
-
market=None,
|
|
320
|
-
symbol=None,
|
|
321
|
-
):
|
|
322
|
-
super().__init__(
|
|
323
|
-
identifier=identifier,
|
|
324
|
-
market=market,
|
|
325
|
-
symbol=symbol,
|
|
326
|
-
)
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
class OrderBookMarketDataSource(MarketDataSource, ABC):
|
|
330
|
-
"""
|
|
331
|
-
Abstract class for order book market data sources.
|
|
332
|
-
"""
|
|
333
|
-
|
|
334
|
-
def __init__(
|
|
335
|
-
self,
|
|
336
|
-
identifier,
|
|
337
|
-
market,
|
|
338
|
-
symbol,
|
|
339
|
-
):
|
|
340
|
-
super().__init__(
|
|
341
|
-
identifier=identifier,
|
|
342
|
-
market=market,
|
|
343
|
-
symbol=symbol,
|
|
344
|
-
)
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from typing import Dict
|
|
5
|
-
|
|
6
|
-
from polars import DataFrame
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger("investing_algorithm_framework")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class MarketService(ABC):
|
|
12
|
-
|
|
13
|
-
def __init__(self, market_credential_service):
|
|
14
|
-
self._market_credential_service = market_credential_service
|
|
15
|
-
self._config = None
|
|
16
|
-
|
|
17
|
-
@property
|
|
18
|
-
def config(self):
|
|
19
|
-
return self._config
|
|
20
|
-
|
|
21
|
-
@config.setter
|
|
22
|
-
def config(self, value):
|
|
23
|
-
self._config = value
|
|
24
|
-
|
|
25
|
-
@abstractmethod
|
|
26
|
-
def pair_exists(
|
|
27
|
-
self,
|
|
28
|
-
market,
|
|
29
|
-
target_symbol: str,
|
|
30
|
-
trading_symbol: str,
|
|
31
|
-
):
|
|
32
|
-
raise NotImplementedError()
|
|
33
|
-
|
|
34
|
-
@abstractmethod
|
|
35
|
-
def get_ticker(self, symbol, market):
|
|
36
|
-
raise NotImplementedError()
|
|
37
|
-
|
|
38
|
-
@abstractmethod
|
|
39
|
-
def get_tickers(self, symbols, market):
|
|
40
|
-
raise NotImplementedError()
|
|
41
|
-
|
|
42
|
-
@abstractmethod
|
|
43
|
-
def get_order_book(self, symbol, market):
|
|
44
|
-
raise NotImplementedError()
|
|
45
|
-
|
|
46
|
-
@abstractmethod
|
|
47
|
-
def get_order_books(self, symbols, market):
|
|
48
|
-
raise NotImplementedError()
|
|
49
|
-
|
|
50
|
-
@abstractmethod
|
|
51
|
-
def get_order(self, order, market):
|
|
52
|
-
raise NotImplementedError()
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
def get_orders(self, symbol, market, since: datetime = None):
|
|
56
|
-
raise NotImplementedError()
|
|
57
|
-
|
|
58
|
-
@abstractmethod
|
|
59
|
-
def get_balance(self, market) -> Dict[str, float]:
|
|
60
|
-
raise NotImplementedError()
|
|
61
|
-
|
|
62
|
-
@abstractmethod
|
|
63
|
-
def create_limit_buy_order(
|
|
64
|
-
self,
|
|
65
|
-
target_symbol: str,
|
|
66
|
-
trading_symbol: str,
|
|
67
|
-
amount: float,
|
|
68
|
-
price: float,
|
|
69
|
-
market
|
|
70
|
-
):
|
|
71
|
-
raise NotImplementedError()
|
|
72
|
-
|
|
73
|
-
@abstractmethod
|
|
74
|
-
def create_limit_sell_order(
|
|
75
|
-
self,
|
|
76
|
-
target_symbol: str,
|
|
77
|
-
trading_symbol: str,
|
|
78
|
-
amount: float,
|
|
79
|
-
price: float,
|
|
80
|
-
market
|
|
81
|
-
):
|
|
82
|
-
raise NotImplementedError()
|
|
83
|
-
|
|
84
|
-
@abstractmethod
|
|
85
|
-
def create_market_sell_order(
|
|
86
|
-
self,
|
|
87
|
-
target_symbol: str,
|
|
88
|
-
trading_symbol: str,
|
|
89
|
-
amount: float,
|
|
90
|
-
market
|
|
91
|
-
):
|
|
92
|
-
raise NotImplementedError()
|
|
93
|
-
|
|
94
|
-
@abstractmethod
|
|
95
|
-
def cancel_order(self, order, market):
|
|
96
|
-
raise NotImplementedError()
|
|
97
|
-
|
|
98
|
-
@abstractmethod
|
|
99
|
-
def get_open_orders(
|
|
100
|
-
self, market, target_symbol: str = None, trading_symbol: str = None
|
|
101
|
-
):
|
|
102
|
-
raise NotImplementedError()
|
|
103
|
-
|
|
104
|
-
@abstractmethod
|
|
105
|
-
def get_closed_orders(
|
|
106
|
-
self, market, target_symbol: str = None, trading_symbol: str = None
|
|
107
|
-
):
|
|
108
|
-
raise NotImplementedError()
|
|
109
|
-
|
|
110
|
-
@abstractmethod
|
|
111
|
-
def get_ohlcv(
|
|
112
|
-
self, symbol, time_frame, from_timestamp, market, to_timestamp=None
|
|
113
|
-
) -> DataFrame:
|
|
114
|
-
raise NotImplementedError()
|
|
115
|
-
|
|
116
|
-
@abstractmethod
|
|
117
|
-
def get_ohlcvs(
|
|
118
|
-
self, symbols, time_frame, from_timestamp, market, to_timestamp=None
|
|
119
|
-
) -> Dict[str, DataFrame]:
|
|
120
|
-
raise NotImplementedError()
|
|
121
|
-
|
|
122
|
-
@property
|
|
123
|
-
def market_credentials(self):
|
|
124
|
-
|
|
125
|
-
if self._market_credential_service is None:
|
|
126
|
-
return []
|
|
127
|
-
|
|
128
|
-
return self._market_credential_service.get_all()
|
|
129
|
-
|
|
130
|
-
def get_market_credentials(self):
|
|
131
|
-
return self._market_credential_service.get_all()
|
|
132
|
-
|
|
133
|
-
def get_market_credential(self, market):
|
|
134
|
-
|
|
135
|
-
if self.market_credentials is None:
|
|
136
|
-
return None
|
|
137
|
-
|
|
138
|
-
if market is None:
|
|
139
|
-
return None
|
|
140
|
-
|
|
141
|
-
for market_data_credentials in self.market_credentials:
|
|
142
|
-
|
|
143
|
-
if market_data_credentials.market.lower() == market.lower():
|
|
144
|
-
return market_data_credentials
|
|
145
|
-
|
|
146
|
-
return None
|
|
147
|
-
|
|
148
|
-
@abstractmethod
|
|
149
|
-
def get_symbols(self, market):
|
|
150
|
-
"""
|
|
151
|
-
Get all available symbols for a market
|
|
152
|
-
"""
|
|
153
|
-
raise NotImplementedError()
|