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.

Files changed (256) hide show
  1. investing_algorithm_framework/__init__.py +168 -45
  2. investing_algorithm_framework/app/__init__.py +32 -1
  3. investing_algorithm_framework/app/algorithm/__init__.py +7 -0
  4. investing_algorithm_framework/app/algorithm/algorithm.py +239 -0
  5. investing_algorithm_framework/app/algorithm/algorithm_factory.py +114 -0
  6. investing_algorithm_framework/app/analysis/__init__.py +15 -0
  7. investing_algorithm_framework/app/analysis/backtest_data_ranges.py +121 -0
  8. investing_algorithm_framework/app/analysis/backtest_utils.py +107 -0
  9. investing_algorithm_framework/app/analysis/permutation.py +116 -0
  10. investing_algorithm_framework/app/analysis/ranking.py +297 -0
  11. investing_algorithm_framework/app/app.py +1933 -589
  12. investing_algorithm_framework/app/app_hook.py +28 -0
  13. investing_algorithm_framework/app/context.py +1725 -0
  14. investing_algorithm_framework/app/eventloop.py +590 -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/stop_loss_table.py +0 -0
  31. investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +80 -0
  32. investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +147 -0
  33. investing_algorithm_framework/app/reporting/tables/trades_table.py +75 -0
  34. investing_algorithm_framework/app/reporting/tables/utils.py +29 -0
  35. investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +154 -0
  36. investing_algorithm_framework/app/stateless/action_handlers/__init__.py +4 -2
  37. investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +1 -1
  38. investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +1 -1
  39. investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +14 -7
  40. investing_algorithm_framework/app/strategy.py +664 -84
  41. investing_algorithm_framework/app/task.py +5 -3
  42. investing_algorithm_framework/app/web/__init__.py +2 -1
  43. investing_algorithm_framework/app/web/create_app.py +4 -2
  44. investing_algorithm_framework/cli/__init__.py +0 -0
  45. investing_algorithm_framework/cli/cli.py +226 -0
  46. investing_algorithm_framework/cli/deploy_to_aws_lambda.py +501 -0
  47. investing_algorithm_framework/cli/deploy_to_azure_function.py +718 -0
  48. investing_algorithm_framework/cli/initialize_app.py +603 -0
  49. investing_algorithm_framework/cli/templates/.gitignore.template +178 -0
  50. investing_algorithm_framework/cli/templates/app.py.template +18 -0
  51. investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +48 -0
  52. investing_algorithm_framework/cli/templates/app_azure_function.py.template +14 -0
  53. investing_algorithm_framework/cli/templates/app_web.py.template +18 -0
  54. investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
  55. investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
  56. investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +110 -0
  57. investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -0
  58. investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +65 -0
  59. investing_algorithm_framework/cli/templates/azure_function_host.json.template +15 -0
  60. investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +8 -0
  61. investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +3 -0
  62. investing_algorithm_framework/cli/templates/data_providers.py.template +17 -0
  63. investing_algorithm_framework/cli/templates/env.example.template +2 -0
  64. investing_algorithm_framework/cli/templates/env_azure_function.example.template +4 -0
  65. investing_algorithm_framework/cli/templates/market_data_providers.py.template +9 -0
  66. investing_algorithm_framework/cli/templates/readme.md.template +135 -0
  67. investing_algorithm_framework/cli/templates/requirements.txt.template +2 -0
  68. investing_algorithm_framework/cli/templates/run_backtest.py.template +20 -0
  69. investing_algorithm_framework/cli/templates/strategy.py.template +124 -0
  70. investing_algorithm_framework/create_app.py +40 -6
  71. investing_algorithm_framework/dependency_container.py +72 -56
  72. investing_algorithm_framework/domain/__init__.py +71 -47
  73. investing_algorithm_framework/domain/backtesting/__init__.py +21 -0
  74. investing_algorithm_framework/domain/backtesting/backtest.py +503 -0
  75. investing_algorithm_framework/domain/backtesting/backtest_date_range.py +96 -0
  76. investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +242 -0
  77. investing_algorithm_framework/domain/backtesting/backtest_metrics.py +459 -0
  78. investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
  79. investing_algorithm_framework/domain/backtesting/backtest_run.py +605 -0
  80. investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
  81. investing_algorithm_framework/domain/backtesting/combine_backtests.py +280 -0
  82. investing_algorithm_framework/domain/config.py +59 -91
  83. investing_algorithm_framework/domain/constants.py +13 -38
  84. investing_algorithm_framework/domain/data_provider.py +334 -0
  85. investing_algorithm_framework/domain/data_structures.py +3 -2
  86. investing_algorithm_framework/domain/exceptions.py +51 -1
  87. investing_algorithm_framework/domain/models/__init__.py +17 -12
  88. investing_algorithm_framework/domain/models/data/__init__.py +7 -0
  89. investing_algorithm_framework/domain/models/data/data_source.py +214 -0
  90. investing_algorithm_framework/domain/models/data/data_type.py +46 -0
  91. investing_algorithm_framework/domain/models/event.py +35 -0
  92. investing_algorithm_framework/domain/models/market/market_credential.py +55 -1
  93. investing_algorithm_framework/domain/models/order/order.py +77 -83
  94. investing_algorithm_framework/domain/models/order/order_status.py +2 -2
  95. investing_algorithm_framework/domain/models/order/order_type.py +1 -3
  96. investing_algorithm_framework/domain/models/portfolio/portfolio.py +81 -3
  97. investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +26 -3
  98. investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +108 -11
  99. investing_algorithm_framework/domain/models/position/__init__.py +2 -1
  100. investing_algorithm_framework/domain/models/position/position.py +12 -0
  101. investing_algorithm_framework/domain/models/position/position_size.py +41 -0
  102. investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
  103. investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
  104. investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
  105. investing_algorithm_framework/domain/models/snapshot_interval.py +45 -0
  106. investing_algorithm_framework/domain/models/strategy_profile.py +19 -151
  107. investing_algorithm_framework/domain/models/time_frame.py +37 -0
  108. investing_algorithm_framework/domain/models/time_interval.py +33 -0
  109. investing_algorithm_framework/domain/models/time_unit.py +66 -2
  110. investing_algorithm_framework/domain/models/trade/__init__.py +8 -1
  111. investing_algorithm_framework/domain/models/trade/trade.py +295 -171
  112. investing_algorithm_framework/domain/models/trade/trade_status.py +9 -2
  113. investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +332 -0
  114. investing_algorithm_framework/domain/models/trade/trade_take_profit.py +365 -0
  115. investing_algorithm_framework/domain/order_executor.py +112 -0
  116. investing_algorithm_framework/domain/portfolio_provider.py +118 -0
  117. investing_algorithm_framework/domain/services/__init__.py +2 -9
  118. investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -6
  119. investing_algorithm_framework/domain/services/state_handler.py +38 -0
  120. investing_algorithm_framework/domain/strategy.py +1 -29
  121. investing_algorithm_framework/domain/utils/__init__.py +12 -7
  122. investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
  123. investing_algorithm_framework/domain/utils/dates.py +57 -0
  124. investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
  125. investing_algorithm_framework/domain/utils/polars.py +53 -0
  126. investing_algorithm_framework/domain/utils/random.py +29 -0
  127. investing_algorithm_framework/download_data.py +108 -0
  128. investing_algorithm_framework/infrastructure/__init__.py +31 -18
  129. investing_algorithm_framework/infrastructure/data_providers/__init__.py +36 -0
  130. investing_algorithm_framework/infrastructure/data_providers/ccxt.py +1143 -0
  131. investing_algorithm_framework/infrastructure/data_providers/csv.py +568 -0
  132. investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
  133. investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
  134. investing_algorithm_framework/infrastructure/database/sql_alchemy.py +86 -12
  135. investing_algorithm_framework/infrastructure/models/__init__.py +6 -11
  136. investing_algorithm_framework/infrastructure/models/order/__init__.py +2 -1
  137. investing_algorithm_framework/infrastructure/models/order/order.py +35 -49
  138. investing_algorithm_framework/infrastructure/models/order/order_metadata.py +44 -0
  139. investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
  140. investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +1 -1
  141. investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +8 -0
  142. investing_algorithm_framework/infrastructure/models/portfolio/{portfolio.py → sql_portfolio.py} +17 -5
  143. investing_algorithm_framework/infrastructure/models/trades/__init__.py +9 -0
  144. investing_algorithm_framework/infrastructure/models/trades/trade.py +130 -0
  145. investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +59 -0
  146. investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +55 -0
  147. investing_algorithm_framework/infrastructure/order_executors/__init__.py +21 -0
  148. investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
  149. investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +200 -0
  150. investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +19 -0
  151. investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +199 -0
  152. investing_algorithm_framework/infrastructure/repositories/__init__.py +8 -0
  153. investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +17 -0
  154. investing_algorithm_framework/infrastructure/repositories/order_repository.py +5 -0
  155. investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +1 -1
  156. investing_algorithm_framework/infrastructure/repositories/position_repository.py +11 -0
  157. investing_algorithm_framework/infrastructure/repositories/repository.py +81 -27
  158. investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
  159. investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +29 -0
  160. investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +29 -0
  161. investing_algorithm_framework/infrastructure/services/__init__.py +4 -4
  162. investing_algorithm_framework/infrastructure/services/aws/__init__.py +6 -0
  163. investing_algorithm_framework/infrastructure/services/aws/state_handler.py +113 -0
  164. investing_algorithm_framework/infrastructure/services/azure/__init__.py +5 -0
  165. investing_algorithm_framework/infrastructure/services/azure/state_handler.py +158 -0
  166. investing_algorithm_framework/services/__init__.py +113 -16
  167. investing_algorithm_framework/services/backtesting/__init__.py +0 -7
  168. investing_algorithm_framework/services/backtesting/backtest_service.py +566 -359
  169. investing_algorithm_framework/services/configuration_service.py +77 -11
  170. investing_algorithm_framework/services/data_providers/__init__.py +5 -0
  171. investing_algorithm_framework/services/data_providers/data_provider_service.py +850 -0
  172. investing_algorithm_framework/services/market_credential_service.py +16 -1
  173. investing_algorithm_framework/services/metrics/__init__.py +114 -0
  174. investing_algorithm_framework/services/metrics/alpha.py +0 -0
  175. investing_algorithm_framework/services/metrics/beta.py +0 -0
  176. investing_algorithm_framework/services/metrics/cagr.py +60 -0
  177. investing_algorithm_framework/services/metrics/calmar_ratio.py +40 -0
  178. investing_algorithm_framework/services/metrics/drawdown.py +181 -0
  179. investing_algorithm_framework/services/metrics/equity_curve.py +24 -0
  180. investing_algorithm_framework/services/metrics/exposure.py +210 -0
  181. investing_algorithm_framework/services/metrics/generate.py +358 -0
  182. investing_algorithm_framework/services/metrics/mean_daily_return.py +83 -0
  183. investing_algorithm_framework/services/metrics/profit_factor.py +165 -0
  184. investing_algorithm_framework/services/metrics/recovery.py +113 -0
  185. investing_algorithm_framework/services/metrics/returns.py +452 -0
  186. investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
  187. investing_algorithm_framework/services/metrics/sharpe_ratio.py +137 -0
  188. investing_algorithm_framework/services/metrics/sortino_ratio.py +74 -0
  189. investing_algorithm_framework/services/metrics/standard_deviation.py +157 -0
  190. investing_algorithm_framework/services/metrics/trades.py +500 -0
  191. investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
  192. investing_algorithm_framework/services/metrics/ulcer.py +0 -0
  193. investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
  194. investing_algorithm_framework/services/metrics/volatility.py +97 -0
  195. investing_algorithm_framework/services/metrics/win_rate.py +177 -0
  196. investing_algorithm_framework/services/order_service/__init__.py +3 -1
  197. investing_algorithm_framework/services/order_service/order_backtest_service.py +76 -89
  198. investing_algorithm_framework/services/order_service/order_executor_lookup.py +110 -0
  199. investing_algorithm_framework/services/order_service/order_service.py +407 -326
  200. investing_algorithm_framework/services/portfolios/__init__.py +3 -1
  201. investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +37 -3
  202. investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +22 -8
  203. investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +106 -0
  204. investing_algorithm_framework/services/portfolios/portfolio_service.py +96 -28
  205. investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +97 -28
  206. investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +116 -313
  207. investing_algorithm_framework/services/positions/__init__.py +7 -0
  208. investing_algorithm_framework/services/positions/position_service.py +210 -0
  209. investing_algorithm_framework/services/repository_service.py +8 -2
  210. investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
  211. investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +113 -0
  212. investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
  213. investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
  214. investing_algorithm_framework/services/trade_service/__init__.py +7 -1
  215. investing_algorithm_framework/services/trade_service/trade_service.py +1013 -315
  216. investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
  217. investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
  218. investing_algorithm_framework-7.19.15.dist-info/METADATA +537 -0
  219. investing_algorithm_framework-7.19.15.dist-info/RECORD +263 -0
  220. investing_algorithm_framework-7.19.15.dist-info/entry_points.txt +3 -0
  221. investing_algorithm_framework/app/algorithm.py +0 -1105
  222. investing_algorithm_framework/domain/graphs.py +0 -382
  223. investing_algorithm_framework/domain/metrics/__init__.py +0 -6
  224. investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -11
  225. investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -43
  226. investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -120
  227. investing_algorithm_framework/domain/models/backtesting/backtest_report.py +0 -580
  228. investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -243
  229. investing_algorithm_framework/domain/models/trading_data_types.py +0 -47
  230. investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
  231. investing_algorithm_framework/domain/services/market_data_sources.py +0 -344
  232. investing_algorithm_framework/domain/services/market_service.py +0 -153
  233. investing_algorithm_framework/domain/singleton.py +0 -9
  234. investing_algorithm_framework/domain/utils/backtesting.py +0 -472
  235. investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -12
  236. investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -559
  237. investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -254
  238. investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -47
  239. investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -5
  240. investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -455
  241. investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -7
  242. investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -2
  243. investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -350
  244. investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -53
  245. investing_algorithm_framework/services/backtesting/graphs.py +0 -61
  246. investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -8
  247. investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -150
  248. investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -189
  249. investing_algorithm_framework/services/position_service.py +0 -31
  250. investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -264
  251. investing_algorithm_framework-3.7.0.dist-info/METADATA +0 -339
  252. investing_algorithm_framework-3.7.0.dist-info/RECORD +0 -147
  253. /investing_algorithm_framework/{domain → services}/metrics/price_efficiency.py +0 -0
  254. /investing_algorithm_framework/services/{position_snapshot_service.py → positions/position_snapshot_service.py} +0 -0
  255. {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/LICENSE +0 -0
  256. {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/WHEEL +0 -0
@@ -1,243 +0,0 @@
1
- from typing import List, Dict
2
-
3
- from investing_algorithm_framework.domain.exceptions import \
4
- OperationalException
5
- from investing_algorithm_framework.domain.models.backtesting\
6
- .backtest_date_range import BacktestDateRange
7
- from .backtest_report import BacktestReport
8
-
9
-
10
- class BacktestReportsEvaluation:
11
- """
12
- A class to evaluate backtest reports.
13
-
14
- This class is used to evaluate backtest reports and order them based on
15
- different metrics. It also groups the reports by backtest date range.
16
-
17
- The class has methods to get the best algorithm based on profit and growth.
18
- """
19
- report_groupings: Dict[BacktestDateRange, List[BacktestReport]]
20
-
21
- def __init__(self, backtest_reports: List[BacktestReport]):
22
-
23
- if backtest_reports is None:
24
- raise OperationalException("No backtest reports to evaluate")
25
-
26
- self.backtest_reports = backtest_reports
27
- self.group_reports(self.backtest_reports)
28
- self.profit_order = {}
29
- self.profit_order_grouped_by_date = {}
30
- self.growth_order = {}
31
- self.growth_order_grouped_by_date = {}
32
- self.percentage_positive_trades_order = {}
33
- self.percentage_positive_trades_order_grouped_by_date = {}
34
-
35
- # Calculate all metrics and group reports
36
- for key in self.report_groupings:
37
- self.profit_order_grouped_by_date[key] = self.order_on_profit(
38
- self.report_groupings[key].copy()
39
- )
40
- self.growth_order_grouped_by_date[key] = self.order_on_growth(
41
- self.report_groupings[key].copy()
42
- )
43
- self.percentage_positive_trades_order_grouped_by_date[key] = \
44
- self.order_on_positive_trades(
45
- self.report_groupings[key].copy()
46
- )
47
-
48
- # Overall ordered reports
49
- self.percentage_positive_trades_order = \
50
- self.order_on_positive_trades(self.backtest_reports)
51
- self.growth_order = self.order_on_growth(self.backtest_reports)
52
- self.profit_order = self.order_on_profit(self.backtest_reports)
53
-
54
- def order_on_profit(self, reports: List[BacktestReport]):
55
- return sorted(reports, key=lambda x: x.total_net_gain, reverse=True)
56
-
57
- def order_on_growth(self, reports: List[BacktestReport]):
58
- return sorted(reports, key=lambda x: x.growth_rate, reverse=True)
59
-
60
- def order_on_positive_trades(self, reports: List[BacktestReport]):
61
- return sorted(
62
- reports, key=lambda x: x.percentage_positive_trades, reverse=True
63
- )
64
-
65
- def group_reports(self, reports: List[BacktestReport]):
66
- """
67
- Group reports by backtest start and end date.
68
- """
69
- self.report_groupings = {}
70
-
71
- for report in reports:
72
- key = report.backtest_date_range
73
- if key not in self.report_groupings:
74
- self.report_groupings[key] = []
75
- self.report_groupings[key].append(report)
76
-
77
- def get_date_ranges(self):
78
- """
79
- Get the date ranges of the backtest reports.
80
- """
81
- return list(self.report_groupings.keys())
82
-
83
- def get_profit_order(
84
- self, backtest_date_range: BacktestDateRange = None
85
- ) -> List[BacktestReport]:
86
- """
87
- Function to get profit order of all the backtest reports
88
- in an ordered list.
89
-
90
- :param backtest_date_range: Tuple with two datetime objects
91
- :return: List of backtest reports
92
- """
93
-
94
- if backtest_date_range is None:
95
- return self.profit_order
96
- else:
97
-
98
- if backtest_date_range in self.profit_order_grouped_by_date:
99
- return self.profit_order_grouped_by_date[backtest_date_range]
100
-
101
- raise OperationalException("No matches for given date range")
102
-
103
- def get_growth_order(
104
- self, backtest_date_range: BacktestDateRange = None
105
- ) -> List[BacktestReport]:
106
- """
107
- Function to get growth order of all the backtest reports
108
- in an ordered list.
109
-
110
- :param backtest_date_range: Tuple with two datetime objects
111
- :return: List of backtest reports
112
- """
113
-
114
- if backtest_date_range is None:
115
- return self.growth_order
116
- else:
117
-
118
- if backtest_date_range in self.growth_order_grouped_by_date:
119
- return self.growth_order_grouped_by_date[backtest_date_range]
120
-
121
- raise OperationalException("No matches for given date range")
122
-
123
- def get_percentage_positive_trades_order(
124
- self, backtest_date_range: BacktestDateRange = None
125
- ) -> List[BacktestReport]:
126
- """
127
- Function to get growth order of all the backtest reports
128
- in an ordered list.
129
-
130
- :param backtest_date_range: Tuple with two datetime objects
131
- :return: List of backtest reports
132
- """
133
-
134
- if backtest_date_range is None:
135
- return self.percentage_positive_trades_order
136
- else:
137
-
138
- if backtest_date_range in \
139
- self.percentage_positive_trades_order_grouped_by_date:
140
- return self.percentage_positive_trades_order_grouped_by_date[
141
- backtest_date_range
142
- ]
143
-
144
- raise OperationalException("No matches for given date range")
145
-
146
- def rank(
147
- self,
148
- weight_profit=0.7,
149
- weight_growth=0.3,
150
- backtest_date_range: BacktestDateRange = None
151
- ) -> str:
152
- """
153
- Function to get the best overall algorithm based on the
154
- weighted sum of profit and growth.
155
-
156
- :param weight_profit: Weight for profit
157
- :param weight_growth: Weight for growth
158
- :return: Name of the best algorithm
159
- """
160
-
161
- # Create a dictionary with the algorithm name as key and group
162
- # the reports by name
163
- ordered_reports = {}
164
-
165
- if backtest_date_range is not None:
166
- reports = self.report_groupings[backtest_date_range]
167
- else:
168
- reports = self.backtest_reports
169
-
170
- for report in reports:
171
- if report.name not in ordered_reports:
172
- ordered_reports[report.name] = []
173
- ordered_reports[report.name].append(report)
174
-
175
- best_algorithm = None
176
- best_score = 0
177
- profit_score = 0
178
- growth_score = 0
179
-
180
- for algorithm in ordered_reports:
181
- profit_score += sum(
182
- [report.total_net_gain for
183
- report in ordered_reports[algorithm]]
184
- )
185
- growth_score += sum(
186
- [report.growth for report in
187
- ordered_reports[algorithm]]
188
- )
189
- score = weight_profit * profit_score + weight_growth * growth_score
190
-
191
- if score > best_score:
192
- best_score = score
193
- best_algorithm = algorithm
194
-
195
- profit_score = 0
196
- growth_score = 0
197
-
198
- return best_algorithm
199
-
200
- def get_reports(
201
- self, name: str = None, backtest_date_range: BacktestDateRange = None
202
- ) -> List[BacktestReport]:
203
- """
204
- Function to get all the reports for a given algorithm name.
205
-
206
- :param name: Name of the algorithm
207
- :param backtest_date_range: Tuple with two datetime objects
208
- :return: List of backtest reports
209
- """
210
-
211
- if name is not None and backtest_date_range is not None:
212
- return [
213
- report for report in self.report_groupings[backtest_date_range]
214
- if report.name == name
215
- ]
216
-
217
- if name is not None:
218
- return [
219
- report for report in self.backtest_reports
220
- if report.name == name
221
- ]
222
-
223
- if backtest_date_range is not None:
224
- return self.report_groupings[backtest_date_range]
225
-
226
- def get_report(
227
- self, name: str, backtest_date_range: BacktestDateRange = None
228
- ):
229
- """
230
- Function to get the report for a given algorithm name and date range.
231
-
232
- :param name: Name of the algorithm
233
- :param backtest_date_range: Tuple with two datetime objects
234
- :return: Backtest report
235
- """
236
- reports = self.get_reports(name, backtest_date_range)
237
-
238
- if len(reports) == 0:
239
- raise OperationalException(
240
- "No matches for given name and date range"
241
- )
242
-
243
- return reports[0]
@@ -1,47 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class TradingDataType(Enum):
5
- TICKER = 'TICKER'
6
- ORDER_BOOK = 'ORDER_BOOK'
7
- OHLCV = "OHLCV"
8
-
9
- @staticmethod
10
- def from_value(value):
11
-
12
- if isinstance(value, TradingDataType):
13
- for trading_data_type in TradingDataType:
14
-
15
- if value == trading_data_type:
16
- return trading_data_type
17
-
18
- elif isinstance(value, str):
19
- return TradingDataType.from_string(value)
20
-
21
- raise ValueError(
22
- "Could not convert value to trading data type"
23
- )
24
-
25
- @staticmethod
26
- def from_string(value: str):
27
-
28
- if isinstance(value, str):
29
- for order_type in TradingDataType:
30
-
31
- if value.upper() == order_type.value:
32
- return order_type
33
-
34
- raise ValueError(
35
- "Could not convert value to trading data type"
36
- )
37
-
38
- def equals(self, other):
39
-
40
- if other is None:
41
- return False
42
-
43
- if isinstance(other, Enum):
44
- return self.value == other.value
45
-
46
- else:
47
- return TradingDataType.from_string(other) == self
@@ -1,223 +0,0 @@
1
- from datetime import timedelta, datetime
2
- from enum import Enum
3
-
4
- from investing_algorithm_framework.domain.exceptions import \
5
- OperationalException
6
-
7
-
8
- class TradingTimeFrame(Enum):
9
- ONE_MINUTE = "ONE_MINUTE"
10
- FIFTEEN_MINUTE = "FIFTEEN_MINUTE"
11
- ONE_HOUR = "ONE_HOUR"
12
- TWO_HOUR = "TWO_HOUR"
13
- ONE_DAY = 'ONE_DAY'
14
- ONE_MONTH = "ONE_MONTH"
15
- ONE_YEAR = "ONE_YEAR"
16
-
17
- def create_time_frame_from_limit(self, limit: int = 50):
18
-
19
- if TradingTimeFrame.ONE_MINUTE.equals(self):
20
- hold = 1
21
- start_date = datetime.now() - timedelta(minutes=limit)
22
- elif TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
23
- hold = 15
24
- start_date = datetime.now() - timedelta(minutes=(limit * 15))
25
- elif TradingTimeFrame.ONE_HOUR.equals(self):
26
- hold = 60
27
- start_date = datetime.now() - timedelta(hours=limit)
28
- elif TradingTimeFrame.TWO_HOUR.equals(self):
29
- hold = 60 * 2
30
- start_date = datetime.now() - timedelta(hours=limit)
31
- elif TradingTimeFrame.ONE_DAY.equals(self):
32
- hold = 60 * 24
33
- start_date = datetime.now() - timedelta(days=limit)
34
- elif TradingTimeFrame.ONE_MONTH.equals(self):
35
- hold = 60 * 24 * 30
36
- start_date = datetime.now() - timedelta(weeks=(4 * limit))
37
- else:
38
- hold = 60 * 24 * 365
39
- start_date = datetime.now() - timedelta(days=(limit * 365))
40
-
41
- iteration = 1
42
- dates = []
43
- while iteration < limit or \
44
- start_date + timedelta(minutes=hold) < datetime.now():
45
- dates.append(start_date + timedelta(minutes=hold))
46
- start_date += timedelta(minutes=hold)
47
- iteration += 1
48
-
49
- dates.append(datetime.now())
50
- return dates
51
-
52
- def create_time_frame_from_start_date(self, start_date: datetime):
53
-
54
- if start_date > datetime.now():
55
- raise OperationalException("Start date cannot be in the future")
56
-
57
- if TradingTimeFrame.ONE_MINUTE.equals(self):
58
- hold = 1
59
- elif TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
60
- hold = 15
61
- elif TradingTimeFrame.ONE_HOUR.equals(self):
62
- hold = 60
63
- elif TradingTimeFrame.TWO_HOUR.equals(self):
64
- hold = 60 * 2
65
- elif TradingTimeFrame.ONE_DAY.equals(self):
66
- hold = 60 * 24
67
- elif TradingTimeFrame.ONE_MONTH.equals(self):
68
- hold = 60 * 24 * 30
69
- else:
70
- hold = 60 * 24 * 365
71
-
72
- iteration = 1
73
- dates = []
74
-
75
- while start_date < datetime.now():
76
- dates.append(start_date + timedelta(minutes=hold))
77
- start_date += timedelta(minutes=hold)
78
- iteration += 1
79
-
80
- dates.append(datetime.now())
81
- return dates
82
-
83
- def to_ccxt_string(self):
84
-
85
- if TradingTimeFrame.ONE_MINUTE.equals(self):
86
- return "1m"
87
-
88
- if TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
89
- return "15m"
90
-
91
- if TradingTimeFrame.ONE_HOUR.equals(self):
92
- return "1h"
93
-
94
- if TradingTimeFrame.TWO_HOUR.equals(self):
95
- return "2h"
96
-
97
- if TradingTimeFrame.ONE_DAY.equals(self):
98
- return "1d"
99
-
100
- if TradingTimeFrame.ONE_MONTH.equals(self):
101
- return "1m"
102
-
103
- if TradingTimeFrame.ONE_YEAR.equals(self):
104
- return "1y"
105
-
106
- raise OperationalException("Data time unit value is not supported")
107
-
108
- @staticmethod
109
- def from_value(value):
110
-
111
- if isinstance(value, TradingTimeFrame):
112
- for data_time_unit in TradingTimeFrame:
113
-
114
- if value == data_time_unit:
115
- return data_time_unit
116
-
117
- elif isinstance(value, str):
118
- return TradingTimeFrame.from_string(value)
119
-
120
- raise ValueError(
121
- "Could not convert value to data time unit"
122
- )
123
-
124
- @staticmethod
125
- def from_string(value: str):
126
-
127
- if isinstance(value, str):
128
- for data_time_unit in TradingTimeFrame:
129
-
130
- if value.upper() == data_time_unit.value:
131
- return data_time_unit
132
-
133
- raise ValueError(
134
- "Could not convert value to data time unit"
135
- )
136
-
137
- def equals(self, other):
138
-
139
- if other is None:
140
- return False
141
-
142
- if isinstance(other, Enum):
143
- return self.value == other.value
144
-
145
- else:
146
- return TradingTimeFrame.from_string(other) == self
147
-
148
- def create_start_date(self, limit=50):
149
-
150
- if TradingTimeFrame.ONE_MINUTE.equals(self):
151
- return datetime.now() - timedelta(minutes=limit)
152
-
153
- if TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
154
- return datetime.now() - timedelta(minutes=(limit * 15))
155
-
156
- if TradingTimeFrame.ONE_HOUR.equals(self):
157
- return datetime.now() - timedelta(hours=limit)
158
-
159
- if TradingTimeFrame.TWO_HOUR.equals(self):
160
- return datetime.now() - timedelta(hours=limit * 2)
161
-
162
- if TradingTimeFrame.ONE_DAY.equals(self):
163
- return datetime.now() - timedelta(days=limit)
164
-
165
- if TradingTimeFrame.ONE_MONTH.equals(self):
166
- return datetime.now() - timedelta(weeks=(4 * limit))
167
-
168
- if TradingTimeFrame.ONE_YEAR.equals(self):
169
- return datetime.now() - timedelta(days=(limit * 365))
170
-
171
- raise OperationalException("Data time unit value is not supported")
172
-
173
- @property
174
- def minutes(self):
175
-
176
- if TradingTimeFrame.ONE_MINUTE.equals(self):
177
- return 1
178
-
179
- if TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
180
- return 15
181
-
182
- if TradingTimeFrame.ONE_HOUR.equals(self):
183
- return 60
184
-
185
- if TradingTimeFrame.TWO_HOUR.equals(self):
186
- return 120
187
-
188
- if TradingTimeFrame.ONE_DAY.equals(self):
189
- return 60 * 24
190
-
191
- if TradingTimeFrame.ONE_MONTH.equals(self):
192
- return 60 * 24 * 30
193
-
194
- if TradingTimeFrame.ONE_YEAR.equals(self):
195
- return 60 * 24 * 365
196
-
197
- raise OperationalException("Data time frame value is not supported")
198
-
199
- @property
200
- def milliseconds(self):
201
-
202
- if TradingTimeFrame.ONE_MINUTE.equals(self):
203
- return 60 * 1000
204
-
205
- if TradingTimeFrame.FIFTEEN_MINUTE.equals(self):
206
- return 15 * 60 * 1000
207
-
208
- if TradingTimeFrame.ONE_HOUR.equals(self):
209
- return 60 * 60 * 1000
210
-
211
- if TradingTimeFrame.TWO_HOUR.equals(self):
212
- return 2 * 60 * 60 * 1000
213
-
214
- if TradingTimeFrame.ONE_DAY.equals(self):
215
- return 60 * 60 * 24 * 1000
216
-
217
- if TradingTimeFrame.ONE_MONTH.equals(self):
218
- return 60 * 60 * 24 * 30 * 1000
219
-
220
- if TradingTimeFrame.ONE_YEAR.equals(self):
221
- return 60 * 60 * 24 * 365 * 1000
222
-
223
- raise OperationalException("Data time frame value is not supported")