investing-algorithm-framework 1.5__py3-none-any.whl → 7.25.6__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.
Files changed (276) hide show
  1. investing_algorithm_framework/__init__.py +192 -16
  2. investing_algorithm_framework/analysis/__init__.py +16 -0
  3. investing_algorithm_framework/analysis/backtest_data_ranges.py +202 -0
  4. investing_algorithm_framework/analysis/data.py +170 -0
  5. investing_algorithm_framework/analysis/markdown.py +91 -0
  6. investing_algorithm_framework/analysis/ranking.py +298 -0
  7. investing_algorithm_framework/app/__init__.py +29 -4
  8. investing_algorithm_framework/app/algorithm/__init__.py +7 -0
  9. investing_algorithm_framework/app/algorithm/algorithm.py +193 -0
  10. investing_algorithm_framework/app/algorithm/algorithm_factory.py +118 -0
  11. investing_algorithm_framework/app/app.py +2220 -379
  12. investing_algorithm_framework/app/app_hook.py +28 -0
  13. investing_algorithm_framework/app/context.py +1724 -0
  14. investing_algorithm_framework/app/eventloop.py +620 -0
  15. investing_algorithm_framework/app/reporting/__init__.py +27 -0
  16. investing_algorithm_framework/app/reporting/ascii.py +921 -0
  17. investing_algorithm_framework/app/reporting/backtest_report.py +349 -0
  18. investing_algorithm_framework/app/reporting/charts/__init__.py +19 -0
  19. investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +66 -0
  20. investing_algorithm_framework/app/reporting/charts/equity_curve.py +37 -0
  21. investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +74 -0
  22. investing_algorithm_framework/app/reporting/charts/line_chart.py +11 -0
  23. investing_algorithm_framework/app/reporting/charts/monthly_returns_heatmap.py +70 -0
  24. investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +51 -0
  25. investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +79 -0
  26. investing_algorithm_framework/app/reporting/charts/yearly_returns_barchart.py +55 -0
  27. investing_algorithm_framework/app/reporting/generate.py +185 -0
  28. investing_algorithm_framework/app/reporting/tables/__init__.py +11 -0
  29. investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +217 -0
  30. investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +80 -0
  31. investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +147 -0
  32. investing_algorithm_framework/app/reporting/tables/trades_table.py +75 -0
  33. investing_algorithm_framework/app/reporting/tables/utils.py +29 -0
  34. investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +154 -0
  35. investing_algorithm_framework/app/stateless/action_handlers/__init__.py +6 -3
  36. investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +1 -1
  37. investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +2 -1
  38. investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +14 -7
  39. investing_algorithm_framework/app/strategy.py +867 -60
  40. investing_algorithm_framework/app/task.py +5 -3
  41. investing_algorithm_framework/app/web/__init__.py +2 -1
  42. investing_algorithm_framework/app/web/controllers/__init__.py +2 -2
  43. investing_algorithm_framework/app/web/controllers/orders.py +3 -2
  44. investing_algorithm_framework/app/web/controllers/positions.py +2 -2
  45. investing_algorithm_framework/app/web/create_app.py +4 -2
  46. investing_algorithm_framework/app/web/schemas/position.py +1 -0
  47. investing_algorithm_framework/cli/__init__.py +0 -0
  48. investing_algorithm_framework/cli/cli.py +231 -0
  49. investing_algorithm_framework/cli/deploy_to_aws_lambda.py +501 -0
  50. investing_algorithm_framework/cli/deploy_to_azure_function.py +718 -0
  51. investing_algorithm_framework/cli/initialize_app.py +603 -0
  52. investing_algorithm_framework/cli/templates/.gitignore.template +178 -0
  53. investing_algorithm_framework/cli/templates/app.py.template +18 -0
  54. investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +48 -0
  55. investing_algorithm_framework/cli/templates/app_azure_function.py.template +14 -0
  56. investing_algorithm_framework/cli/templates/app_web.py.template +18 -0
  57. investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
  58. investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
  59. investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +110 -0
  60. investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -0
  61. investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +65 -0
  62. investing_algorithm_framework/cli/templates/azure_function_host.json.template +15 -0
  63. investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +8 -0
  64. investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +3 -0
  65. investing_algorithm_framework/cli/templates/data_providers.py.template +17 -0
  66. investing_algorithm_framework/cli/templates/env.example.template +2 -0
  67. investing_algorithm_framework/cli/templates/env_azure_function.example.template +4 -0
  68. investing_algorithm_framework/cli/templates/market_data_providers.py.template +9 -0
  69. investing_algorithm_framework/cli/templates/readme.md.template +135 -0
  70. investing_algorithm_framework/cli/templates/requirements.txt.template +2 -0
  71. investing_algorithm_framework/cli/templates/run_backtest.py.template +20 -0
  72. investing_algorithm_framework/cli/templates/strategy.py.template +124 -0
  73. investing_algorithm_framework/cli/validate_backtest_checkpoints.py +197 -0
  74. investing_algorithm_framework/create_app.py +40 -7
  75. investing_algorithm_framework/dependency_container.py +100 -47
  76. investing_algorithm_framework/domain/__init__.py +97 -30
  77. investing_algorithm_framework/domain/algorithm_id.py +69 -0
  78. investing_algorithm_framework/domain/backtesting/__init__.py +25 -0
  79. investing_algorithm_framework/domain/backtesting/backtest.py +548 -0
  80. investing_algorithm_framework/domain/backtesting/backtest_date_range.py +113 -0
  81. investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +241 -0
  82. investing_algorithm_framework/domain/backtesting/backtest_metrics.py +470 -0
  83. investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
  84. investing_algorithm_framework/domain/backtesting/backtest_run.py +663 -0
  85. investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
  86. investing_algorithm_framework/domain/backtesting/backtest_utils.py +198 -0
  87. investing_algorithm_framework/domain/backtesting/combine_backtests.py +392 -0
  88. investing_algorithm_framework/domain/config.py +59 -136
  89. investing_algorithm_framework/domain/constants.py +18 -37
  90. investing_algorithm_framework/domain/data_provider.py +334 -0
  91. investing_algorithm_framework/domain/data_structures.py +42 -0
  92. investing_algorithm_framework/domain/exceptions.py +51 -1
  93. investing_algorithm_framework/domain/models/__init__.py +26 -19
  94. investing_algorithm_framework/domain/models/app_mode.py +34 -0
  95. investing_algorithm_framework/domain/models/data/__init__.py +7 -0
  96. investing_algorithm_framework/domain/models/data/data_source.py +222 -0
  97. investing_algorithm_framework/domain/models/data/data_type.py +46 -0
  98. investing_algorithm_framework/domain/models/event.py +35 -0
  99. investing_algorithm_framework/domain/models/market/__init__.py +5 -0
  100. investing_algorithm_framework/domain/models/market/market_credential.py +88 -0
  101. investing_algorithm_framework/domain/models/order/__init__.py +3 -4
  102. investing_algorithm_framework/domain/models/order/order.py +198 -65
  103. investing_algorithm_framework/domain/models/order/order_status.py +2 -2
  104. investing_algorithm_framework/domain/models/order/order_type.py +1 -3
  105. investing_algorithm_framework/domain/models/portfolio/__init__.py +6 -2
  106. investing_algorithm_framework/domain/models/portfolio/portfolio.py +98 -3
  107. investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +37 -43
  108. investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +108 -11
  109. investing_algorithm_framework/domain/models/position/__init__.py +2 -1
  110. investing_algorithm_framework/domain/models/position/position.py +20 -0
  111. investing_algorithm_framework/domain/models/position/position_size.py +41 -0
  112. investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -2
  113. investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
  114. investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
  115. investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
  116. investing_algorithm_framework/domain/models/snapshot_interval.py +45 -0
  117. investing_algorithm_framework/domain/models/strategy_profile.py +19 -141
  118. investing_algorithm_framework/domain/models/time_frame.py +94 -98
  119. investing_algorithm_framework/domain/models/time_interval.py +33 -0
  120. investing_algorithm_framework/domain/models/time_unit.py +66 -2
  121. investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
  122. investing_algorithm_framework/domain/models/tracing/trace.py +23 -0
  123. investing_algorithm_framework/domain/models/trade/__init__.py +11 -0
  124. investing_algorithm_framework/domain/models/trade/trade.py +389 -0
  125. investing_algorithm_framework/domain/models/trade/trade_status.py +40 -0
  126. investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +332 -0
  127. investing_algorithm_framework/domain/models/trade/trade_take_profit.py +365 -0
  128. investing_algorithm_framework/domain/order_executor.py +112 -0
  129. investing_algorithm_framework/domain/portfolio_provider.py +118 -0
  130. investing_algorithm_framework/domain/services/__init__.py +11 -0
  131. investing_algorithm_framework/domain/services/market_credential_service.py +37 -0
  132. investing_algorithm_framework/domain/services/portfolios/__init__.py +5 -0
  133. investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +9 -0
  134. investing_algorithm_framework/domain/services/rounding_service.py +27 -0
  135. investing_algorithm_framework/domain/services/state_handler.py +38 -0
  136. investing_algorithm_framework/domain/strategy.py +1 -29
  137. investing_algorithm_framework/domain/utils/__init__.py +15 -5
  138. investing_algorithm_framework/domain/utils/csv.py +22 -0
  139. investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
  140. investing_algorithm_framework/domain/utils/dates.py +57 -0
  141. investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
  142. investing_algorithm_framework/domain/utils/polars.py +53 -0
  143. investing_algorithm_framework/domain/utils/random.py +29 -0
  144. investing_algorithm_framework/download_data.py +244 -0
  145. investing_algorithm_framework/infrastructure/__init__.py +37 -11
  146. investing_algorithm_framework/infrastructure/data_providers/__init__.py +36 -0
  147. investing_algorithm_framework/infrastructure/data_providers/ccxt.py +1152 -0
  148. investing_algorithm_framework/infrastructure/data_providers/csv.py +568 -0
  149. investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
  150. investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
  151. investing_algorithm_framework/infrastructure/database/sql_alchemy.py +86 -12
  152. investing_algorithm_framework/infrastructure/models/__init__.py +7 -3
  153. investing_algorithm_framework/infrastructure/models/order/__init__.py +2 -2
  154. investing_algorithm_framework/infrastructure/models/order/order.py +53 -53
  155. investing_algorithm_framework/infrastructure/models/order/order_metadata.py +44 -0
  156. investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
  157. investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +1 -1
  158. investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +8 -2
  159. investing_algorithm_framework/infrastructure/models/portfolio/{portfolio.py → sql_portfolio.py} +17 -6
  160. investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +3 -1
  161. investing_algorithm_framework/infrastructure/models/trades/__init__.py +9 -0
  162. investing_algorithm_framework/infrastructure/models/trades/trade.py +130 -0
  163. investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +59 -0
  164. investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +55 -0
  165. investing_algorithm_framework/infrastructure/order_executors/__init__.py +21 -0
  166. investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
  167. investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +200 -0
  168. investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +19 -0
  169. investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +199 -0
  170. investing_algorithm_framework/infrastructure/repositories/__init__.py +10 -4
  171. investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +17 -0
  172. investing_algorithm_framework/infrastructure/repositories/order_repository.py +16 -5
  173. investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +2 -2
  174. investing_algorithm_framework/infrastructure/repositories/position_repository.py +11 -0
  175. investing_algorithm_framework/infrastructure/repositories/repository.py +84 -30
  176. investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
  177. investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +29 -0
  178. investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +29 -0
  179. investing_algorithm_framework/infrastructure/services/__init__.py +9 -4
  180. investing_algorithm_framework/infrastructure/services/aws/__init__.py +6 -0
  181. investing_algorithm_framework/infrastructure/services/aws/state_handler.py +193 -0
  182. investing_algorithm_framework/infrastructure/services/azure/__init__.py +5 -0
  183. investing_algorithm_framework/infrastructure/services/azure/state_handler.py +158 -0
  184. investing_algorithm_framework/infrastructure/services/backtesting/__init__.py +9 -0
  185. investing_algorithm_framework/infrastructure/services/backtesting/backtest_service.py +2596 -0
  186. investing_algorithm_framework/infrastructure/services/backtesting/event_backtest_service.py +285 -0
  187. investing_algorithm_framework/infrastructure/services/backtesting/vector_backtest_service.py +468 -0
  188. investing_algorithm_framework/services/__init__.py +123 -15
  189. investing_algorithm_framework/services/configuration_service.py +77 -11
  190. investing_algorithm_framework/services/data_providers/__init__.py +5 -0
  191. investing_algorithm_framework/services/data_providers/data_provider_service.py +1058 -0
  192. investing_algorithm_framework/services/market_credential_service.py +40 -0
  193. investing_algorithm_framework/services/metrics/__init__.py +119 -0
  194. investing_algorithm_framework/services/metrics/alpha.py +0 -0
  195. investing_algorithm_framework/services/metrics/beta.py +0 -0
  196. investing_algorithm_framework/services/metrics/cagr.py +60 -0
  197. investing_algorithm_framework/services/metrics/calmar_ratio.py +40 -0
  198. investing_algorithm_framework/services/metrics/drawdown.py +218 -0
  199. investing_algorithm_framework/services/metrics/equity_curve.py +24 -0
  200. investing_algorithm_framework/services/metrics/exposure.py +210 -0
  201. investing_algorithm_framework/services/metrics/generate.py +358 -0
  202. investing_algorithm_framework/services/metrics/mean_daily_return.py +84 -0
  203. investing_algorithm_framework/services/metrics/price_efficiency.py +57 -0
  204. investing_algorithm_framework/services/metrics/profit_factor.py +165 -0
  205. investing_algorithm_framework/services/metrics/recovery.py +113 -0
  206. investing_algorithm_framework/services/metrics/returns.py +452 -0
  207. investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
  208. investing_algorithm_framework/services/metrics/sharpe_ratio.py +137 -0
  209. investing_algorithm_framework/services/metrics/sortino_ratio.py +74 -0
  210. investing_algorithm_framework/services/metrics/standard_deviation.py +156 -0
  211. investing_algorithm_framework/services/metrics/trades.py +473 -0
  212. investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
  213. investing_algorithm_framework/services/metrics/ulcer.py +0 -0
  214. investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
  215. investing_algorithm_framework/services/metrics/volatility.py +118 -0
  216. investing_algorithm_framework/services/metrics/win_rate.py +177 -0
  217. investing_algorithm_framework/services/order_service/__init__.py +9 -0
  218. investing_algorithm_framework/services/order_service/order_backtest_service.py +178 -0
  219. investing_algorithm_framework/services/order_service/order_executor_lookup.py +110 -0
  220. investing_algorithm_framework/services/order_service/order_service.py +826 -0
  221. investing_algorithm_framework/services/portfolios/__init__.py +16 -0
  222. investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +54 -0
  223. investing_algorithm_framework/services/{portfolio_configuration_service.py → portfolios/portfolio_configuration_service.py} +27 -12
  224. investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +106 -0
  225. investing_algorithm_framework/services/portfolios/portfolio_service.py +188 -0
  226. investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +136 -0
  227. investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +182 -0
  228. investing_algorithm_framework/services/positions/__init__.py +7 -0
  229. investing_algorithm_framework/services/positions/position_service.py +210 -0
  230. investing_algorithm_framework/services/repository_service.py +8 -2
  231. investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
  232. investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +117 -0
  233. investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
  234. investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
  235. investing_algorithm_framework/services/trade_service/__init__.py +9 -0
  236. investing_algorithm_framework/services/trade_service/trade_service.py +1099 -0
  237. investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
  238. investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
  239. investing_algorithm_framework-7.25.6.dist-info/METADATA +535 -0
  240. investing_algorithm_framework-7.25.6.dist-info/RECORD +268 -0
  241. {investing_algorithm_framework-1.5.dist-info → investing_algorithm_framework-7.25.6.dist-info}/WHEEL +1 -2
  242. investing_algorithm_framework-7.25.6.dist-info/entry_points.txt +3 -0
  243. investing_algorithm_framework/app/algorithm.py +0 -630
  244. investing_algorithm_framework/domain/models/backtest_profile.py +0 -414
  245. investing_algorithm_framework/domain/models/market_data/__init__.py +0 -11
  246. investing_algorithm_framework/domain/models/market_data/asset_price.py +0 -50
  247. investing_algorithm_framework/domain/models/market_data/ohlcv.py +0 -105
  248. investing_algorithm_framework/domain/models/market_data/order_book.py +0 -63
  249. investing_algorithm_framework/domain/models/market_data/ticker.py +0 -92
  250. investing_algorithm_framework/domain/models/order/order_fee.py +0 -45
  251. investing_algorithm_framework/domain/models/trade.py +0 -78
  252. investing_algorithm_framework/domain/models/trading_data_types.py +0 -47
  253. investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
  254. investing_algorithm_framework/domain/singleton.py +0 -9
  255. investing_algorithm_framework/domain/utils/backtesting.py +0 -82
  256. investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -21
  257. investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -15
  258. investing_algorithm_framework/infrastructure/services/market_backtest_service.py +0 -360
  259. investing_algorithm_framework/infrastructure/services/market_service.py +0 -410
  260. investing_algorithm_framework/infrastructure/services/performance_service.py +0 -192
  261. investing_algorithm_framework/services/backtest_service.py +0 -268
  262. investing_algorithm_framework/services/market_data_service.py +0 -77
  263. investing_algorithm_framework/services/order_backtest_service.py +0 -122
  264. investing_algorithm_framework/services/order_service.py +0 -752
  265. investing_algorithm_framework/services/portfolio_service.py +0 -164
  266. investing_algorithm_framework/services/portfolio_snapshot_service.py +0 -68
  267. investing_algorithm_framework/services/position_cost_service.py +0 -5
  268. investing_algorithm_framework/services/position_service.py +0 -63
  269. investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -225
  270. investing_algorithm_framework-1.5.dist-info/AUTHORS.md +0 -8
  271. investing_algorithm_framework-1.5.dist-info/METADATA +0 -230
  272. investing_algorithm_framework-1.5.dist-info/RECORD +0 -119
  273. investing_algorithm_framework-1.5.dist-info/top_level.txt +0 -1
  274. /investing_algorithm_framework/{infrastructure/services/performance_backtest_service.py → app/reporting/tables/stop_loss_table.py} +0 -0
  275. /investing_algorithm_framework/services/{position_snapshot_service.py → positions/position_snapshot_service.py} +0 -0
  276. {investing_algorithm_framework-1.5.dist-info → investing_algorithm_framework-7.25.6.dist-info}/LICENSE +0 -0
@@ -1,360 +0,0 @@
1
- import csv
2
- import logging
3
- import os
4
- from datetime import datetime
5
-
6
- from investing_algorithm_framework.domain import \
7
- DATETIME_FORMAT_BACKTESTING, DATETIME_FORMAT, BacktestProfile, \
8
- StrategyProfile, TradingDataType, BACKTESTING_INDEX_DATETIME
9
- from investing_algorithm_framework.domain import OperationalException
10
- from .market_service import MarketService
11
-
12
- logger = logging.getLogger("investing_algorithm_framework")
13
-
14
-
15
- class MarketBacktestService(MarketService):
16
- _data_index = None
17
-
18
- def __init__(self, backtest_data_directory, configuration_service):
19
- self._backtest_data_directory = backtest_data_directory
20
- self._configuration_service = configuration_service
21
-
22
- def initialize(self, portfolio_configuration):
23
- self._market = portfolio_configuration.market
24
-
25
- def write_ohlcv_to_file(self, data_file, data):
26
-
27
- if not os.path.isdir(self._backtest_data_directory):
28
- os.mkdir(self._backtest_data_directory)
29
-
30
- # Create the source data file if it does not exist
31
- with open(data_file, "w") as file:
32
- column_headers = [
33
- "Datetime", "Open", "High", "Low", "Close", "Volume"
34
- ]
35
- writer = csv.writer(file)
36
- writer.writerow(column_headers)
37
- rows = data
38
- writer.writerows(rows)
39
-
40
- def write_tickers_to_file(self, data_file, data):
41
-
42
- # Create the source data file if it does not exist
43
- with open(data_file, "w") as file:
44
- column_headers = [
45
- "Datetime", "Ask", "High", "Low", "previousClose",
46
- ]
47
- writer = csv.writer(file)
48
- writer.writerow(column_headers)
49
- rows = []
50
-
51
- for row in data:
52
- rows.append([
53
- row[0],
54
- row[4],
55
- row[2],
56
- row[3],
57
- row[4],
58
- ])
59
- writer.writerows(rows)
60
-
61
- def _backtest_data_exists(
62
- self,
63
- backtest_profile: BacktestProfile,
64
- strategy_profile: StrategyProfile,
65
- trading_data_type: TradingDataType,
66
- symbol
67
- ):
68
- return os.path.exists(self.create_backtest_data_file_path(
69
- backtest_profile, strategy_profile, symbol, trading_data_type
70
- ))
71
-
72
- def create_backtest_data(
73
- self,
74
- backtest_profile: BacktestProfile,
75
- strategy_profile: StrategyProfile,
76
- ):
77
-
78
- for symbol in strategy_profile.symbols:
79
-
80
- if strategy_profile.trading_data_types is not None:
81
-
82
- if TradingDataType.OHLCV in strategy_profile\
83
- .trading_data_types:
84
-
85
- if not self._backtest_data_exists(
86
- backtest_profile,
87
- strategy_profile,
88
- TradingDataType.OHLCV,
89
- symbol
90
- ):
91
- self.market = strategy_profile.market
92
- data = super().get_ohclv(
93
- symbol,
94
- time_frame=strategy_profile.trading_time_frame,
95
- from_timestamp=strategy_profile
96
- .backtest_start_date_data,
97
- to_timestamp=backtest_profile.backtest_end_date
98
- )
99
- file = self.create_backtest_data_file_path(
100
- backtest_profile,
101
- strategy_profile,
102
- symbol,
103
- TradingDataType.OHLCV
104
- )
105
- self.write_ohlcv_to_file(file, data)
106
-
107
- if TradingDataType.TICKER in strategy_profile\
108
- .trading_data_types:
109
-
110
- if not self._backtest_data_exists(
111
- backtest_profile,
112
- strategy_profile,
113
- TradingDataType.TICKER,
114
- symbol
115
- ):
116
- self.market = strategy_profile.market
117
- data = super().get_ohclv(
118
- symbol,
119
- time_frame=strategy_profile.trading_time_frame,
120
- from_timestamp=strategy_profile
121
- .backtest_start_date_data,
122
- to_timestamp=backtest_profile.backtest_end_date
123
- )
124
- file = self.create_backtest_data_file_path(
125
- backtest_profile,
126
- strategy_profile,
127
- symbol,
128
- TradingDataType.TICKER
129
- )
130
- self.write_tickers_to_file(file, data)
131
-
132
- def create_backtest_data_file_path(
133
- self,
134
- backtest_profile: BacktestProfile,
135
- strategy_profile: StrategyProfile,
136
- symbol,
137
- trading_data_type: TradingDataType
138
- ):
139
- symbol_string = symbol.replace("/", "-")
140
- time_frame_string = strategy_profile.trading_time_frame \
141
- .value.replace("_", "")
142
- return os.path.join(
143
- self._backtest_data_directory,
144
- os.path.join(
145
- f"{trading_data_type.value}_"
146
- f"{symbol_string}_"
147
- f"{time_frame_string}_"
148
- f"{strategy_profile.backtest_start_date_data.strftime(DATETIME_FORMAT_BACKTESTING)}_"
149
- f"{backtest_profile.backtest_end_date.strftime(DATETIME_FORMAT_BACKTESTING)}.csv"
150
- )
151
- )
152
-
153
- def create_backtest_data_file(
154
- self,
155
- backtest_profile: BacktestProfile,
156
- strategy_profile: StrategyProfile,
157
- symbol
158
- ):
159
-
160
- if not os.path.isdir(self._backtest_data_directory):
161
- os.mkdir(self._backtest_data_directory)
162
-
163
- file_path = self.create_backtest_data_file_path(
164
- backtest_profile, strategy_profile, symbol, TradingDataType.OHLCV
165
- )
166
-
167
- if os.path.isfile(file_path):
168
- os.mknod(file_path)
169
-
170
- return file_path
171
-
172
- def index_data(self):
173
- data_dir = os.path.join(self._backtest_data_directory)
174
- self._data_index = {
175
- TradingDataType.OHLCV.value: {}, TradingDataType.TICKER.value: {}
176
- }
177
-
178
- for file in os.listdir(data_dir):
179
- data_type = file.split("_")[0]
180
- symbol = file.split("_")[1]
181
- self._data_index[data_type][symbol] = {}
182
-
183
- if "files" in self._data_index[data_type]:
184
- self._data_index[data_type][symbol]["files"].append(file)
185
- else:
186
- self._data_index[data_type][symbol]["files"] = [file]
187
-
188
- def get_order(self, order):
189
- raise OperationalException(
190
- f"Backtest market service {self.market} does not support "
191
- f"functionality get_order"
192
- )
193
-
194
- def get_orders(self, symbol, since: datetime = None):
195
- raise OperationalException(
196
- f"Backtest market service {self.market} does not support "
197
- f"functionality get_orders"
198
- )
199
-
200
- def create_limit_buy_order(
201
- self,
202
- target_symbol: str,
203
- trading_symbol: str,
204
- amount: float,
205
- price: float
206
- ):
207
- raise OperationalException(
208
- f"Backtest market service {self.market} does not support "
209
- f"functionality create_limit_buy_order"
210
- )
211
-
212
- def create_limit_sell_order(
213
- self,
214
- target_symbol: str,
215
- trading_symbol: str,
216
- amount: float,
217
- price: float
218
- ):
219
- raise OperationalException(
220
- f"Backtest market service {self.market} does not support "
221
- f"functionality create_limit_sell_order"
222
- )
223
-
224
- def create_market_sell_order(
225
- self,
226
- target_symbol: str,
227
- trading_symbol: str,
228
- amount: float,
229
- ):
230
- raise OperationalException(
231
- f"Backtest market service {self.market} does not support "
232
- f"functionality create_market_sell_order"
233
- )
234
-
235
- def cancel_order(self, order):
236
- raise OperationalException(
237
- f"Backtest market service {self.market} does not support "
238
- f"functionality cancel_order"
239
- )
240
-
241
- def get_open_orders(
242
- self, target_symbol: str = None, trading_symbol: str = None
243
- ):
244
- raise OperationalException(
245
- f"Backtest market service {self.market} does not support "
246
- f"functionality get_open_orders"
247
- )
248
-
249
- def get_closed_orders(
250
- self, target_symbol: str = None, trading_symbol: str = None
251
- ):
252
- raise OperationalException(
253
- f"Backtest market service {self.market} does not support "
254
- f"functionality get_closed_orders"
255
- )
256
-
257
- def get_ohclv(self, symbol, time_frame, from_timestamp, to_timestamp=None):
258
- self.index_data()
259
- matching_rows = []
260
- matching_file = None
261
- symbol_string = symbol.replace("/", "-")
262
- self._data_index[TradingDataType.OHLCV.value][symbol_string]["files"].sort()
263
-
264
- if to_timestamp is None:
265
- to_timestamp = datetime.utcnow()
266
-
267
- for file in self._data_index[TradingDataType.OHLCV.value][symbol_string]["files"]:
268
- start_date_file = datetime.strptime(
269
- file.split("_")[3], DATETIME_FORMAT_BACKTESTING
270
- )
271
- end_date_file = datetime.strptime(
272
- file.split("_")[4].split(".")[0], DATETIME_FORMAT_BACKTESTING
273
- )
274
-
275
- if start_date_file <= from_timestamp and to_timestamp <= end_date_file:
276
- matching_file = file
277
- break
278
-
279
- if matching_file is None:
280
- raise OperationalException(
281
- f"No ohlvc backtest data found for symbol "
282
- f"{symbol} between {from_timestamp} and {to_timestamp}"
283
- )
284
-
285
- path = os.path.join(self._backtest_data_directory, matching_file)
286
- with open(path, 'r') as file:
287
- reader = csv.reader(file)
288
- next(reader) # Skip the header row
289
-
290
- for row in reader:
291
- row_date = datetime.strptime(row[0], DATETIME_FORMAT)
292
-
293
- if from_timestamp <= row_date <= to_timestamp:
294
- data = [
295
- row_date,
296
- float(row[1]),
297
- float(row[2]),
298
- float(row[3]),
299
- float(row[4]),
300
- float(row[5]),
301
- ]
302
- matching_rows.append(data)
303
-
304
- return matching_rows
305
-
306
- def get_ticker(self, symbol):
307
- self.index_data()
308
- matching_file = None
309
- match = None
310
- symbol_string = symbol.replace("/", "-")
311
- self._data_index[TradingDataType.TICKER.value][symbol_string]["files"].sort()
312
- date_time = self._configuration_service.config[BACKTESTING_INDEX_DATETIME]
313
-
314
- for file in self._data_index[TradingDataType.TICKER.value][symbol_string]["files"]:
315
- start_date_file = datetime.strptime(
316
- file.split("_")[3], DATETIME_FORMAT_BACKTESTING
317
- )
318
- end_date_file = datetime.strptime(
319
- file.split("_")[4].split(".")[0], DATETIME_FORMAT_BACKTESTING
320
- )
321
-
322
- if start_date_file <= date_time <= end_date_file:
323
- matching_file = file
324
-
325
- if matching_file is None:
326
- raise OperationalException(
327
- f"No backtest data found for symbol {symbol} on {date_time}"
328
- )
329
-
330
- path = os.path.join(self._backtest_data_directory, matching_file)
331
- with open(path, 'r') as file:
332
- reader = csv.reader(file)
333
- next(reader) # Skip the header row
334
- last_row = None
335
-
336
- for row in reader:
337
- row_date = datetime.strptime(row[0], DATETIME_FORMAT)
338
-
339
- if row_date > date_time:
340
- match = last_row
341
- break
342
-
343
- last_row = row
344
-
345
- if last_row is not None and match is None:
346
- match = last_row
347
-
348
- if match is None:
349
- raise OperationalException(
350
- f"No backtest data found for symbol {symbol} on {date_time}"
351
- )
352
-
353
- return {
354
- "symbol": symbol,
355
- "ask": float(match[1]),
356
- "high": float(match[2]),
357
- "low": float(match[3]),
358
- "previousClose": float(match[4]),
359
- "bid": float(match[1]),
360
- }