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,92 +0,0 @@
1
- from datetime import datetime
2
-
3
-
4
- class Ticker:
5
-
6
- def __init__(
7
- self,
8
- symbol,
9
- price,
10
- ask_price=None,
11
- ask_volume=None,
12
- bid_price=None,
13
- bid_volume=None,
14
- high_price=None,
15
- low_price=None,
16
- creation_date=None
17
- ):
18
- self.symbol = symbol
19
- self.price = price
20
- self.ask_price = ask_price
21
- self.ask_volume = ask_volume
22
- self.bid_price = bid_price
23
- self.bid_volume = bid_volume
24
- self.high_price = high_price
25
- self.low_price = low_price
26
-
27
- if creation_date is None:
28
- self.creation_date = datetime.now()
29
-
30
- def get_price(self):
31
- return self.price
32
-
33
- def get_creation_date(self):
34
- return self.creation_date
35
-
36
- def get_symbol(self):
37
- return self.symbol
38
-
39
- def to_dict(self):
40
- return {
41
- "symbol": self.symbol,
42
- "price": self.price,
43
- "ask_price": self.ask_price,
44
- "ask_volume": self.ask_volume,
45
- "bid_price": self.bid_price,
46
- "bid_volume": self.bid_volume,
47
- "high_price": self.high_price,
48
- "low_price": self.low_price
49
- }
50
-
51
- @staticmethod
52
- def from_dict(data):
53
- return Ticker(
54
- symbol=data.get("symbol"),
55
- price=data.get("price"),
56
- ask_price=data.get("ask_price"),
57
- ask_volume=data.get("ask_volume"),
58
- bid_price=data.get("bid_price"),
59
- bid_volume=data.get("bid_volume"),
60
- high_price=data.get("high_price"),
61
- low_price=data.get("low_price"),
62
- creation_date=data.get("creation_date")
63
- )
64
-
65
- def repr(self, **fields) -> str:
66
- """
67
- Helper for __repr__
68
- """
69
-
70
- field_strings = []
71
- at_least_one_attached_attribute = False
72
-
73
- for key, field in fields.items():
74
- field_strings.append(f'{key}={field!r}')
75
- at_least_one_attached_attribute = True
76
-
77
- if at_least_one_attached_attribute:
78
- return f"<{self.__class__.__name__}({','.join(field_strings)})>"
79
-
80
- return f"<{self.__class__.__name__} {id(self)}>"
81
-
82
- def __repr__(self):
83
- return self.repr(
84
- symbol=self.symbol,
85
- price=self.price,
86
- ask_price=self.ask_price,
87
- ask_volume=self.ask_volume,
88
- bid_price=self.bid_price,
89
- bid_volume=self.bid_volume,
90
- high_price=self.high_price,
91
- low_price=self.low_price
92
- )
@@ -1,45 +0,0 @@
1
- from investing_algorithm_framework.domain.models.base_model import BaseModel
2
-
3
-
4
- class OrderFee(BaseModel):
5
- def __init__(self, currency, cost, rate):
6
- self.currency = currency
7
- self.cost = cost
8
- self.rate = rate
9
-
10
- def get_currency(self):
11
- return self.currency
12
-
13
- def set_currency(self, currency):
14
- self.currency = currency
15
-
16
- def get_cost(self):
17
- return self.cost
18
-
19
- def set_cost(self, cost):
20
- self.cost = cost
21
-
22
- def get_rate(self):
23
- return self.rate
24
-
25
- @staticmethod
26
- def from_ccxt_fee(ccxt_fee):
27
- return OrderFee(
28
- currency=ccxt_fee.get('currency'),
29
- cost=ccxt_fee.get('cost'),
30
- rate=ccxt_fee.get('rate'),
31
- )
32
-
33
- def to_dict(self):
34
- return {
35
- "currency": self.currency,
36
- "cost": self.cost,
37
- "rate": self.rate
38
- }
39
-
40
- def __repr__(self):
41
- return self.repr(
42
- currency=self.get_currency(),
43
- cost=self.get_cost(),
44
- rate=self.get_rate(),
45
- )
@@ -1,78 +0,0 @@
1
- from investing_algorithm_framework.domain.models.base_model import BaseModel
2
-
3
-
4
- class Trade(BaseModel):
5
-
6
- def __init__(
7
- self,
8
- target_symbol,
9
- trading_symbol,
10
- amount,
11
- open_price,
12
- closed_price,
13
- closed_at,
14
- opened_at
15
- ):
16
- self._target_symbol = target_symbol
17
- self._trading_symbol = trading_symbol
18
- self._amount = amount
19
- self._open_price = open_price
20
- self._closed_price = closed_price
21
- self._closed_at = closed_at
22
- self._opened_at = opened_at
23
- self._trading_symbol = trading_symbol
24
-
25
- @property
26
- def target_symbol(self):
27
- return self._target_symbol
28
-
29
- @property
30
- def trading_symbol(self):
31
- return self._trading_symbol
32
-
33
- @property
34
- def amount(self):
35
- return self._amount
36
-
37
- @property
38
- def open_price(self):
39
- return self._open_price
40
-
41
- @property
42
- def closed_price(self):
43
- return self._closed_price
44
-
45
- @property
46
- def closed_at(self):
47
- return self._closed_at
48
-
49
- @property
50
- def opened_at(self):
51
- return self._opened_at
52
-
53
- @property
54
- def size(self):
55
- return self.amount * self.open_price
56
-
57
- @property
58
- def net_gain(self):
59
- return self.amount * (self.closed_price - self.open_price)
60
-
61
- @property
62
- def net_gain_percentage(self):
63
- return self.net_gain / self.size * 100
64
-
65
- @property
66
- def duration(self):
67
- return (self.closed_at - self.opened_at).total_seconds() / 3600
68
-
69
- def __repr__(self):
70
- return self.repr(
71
- target_symbol=self.target_symbol,
72
- trading_symbol=self.trading_symbol,
73
- amount=self.amount,
74
- open_price=self.open_price,
75
- closed_price=self.closed_price,
76
- opened_at=self.opened_at,
77
- closed_at=self.closed_at,
78
- )
@@ -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 enum import Enum
2
- from datetime import timedelta, datetime
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")
@@ -1,9 +0,0 @@
1
- class Singleton(type):
2
- _instances = {}
3
-
4
- def __call__(cls, *args, **kwargs):
5
- if cls not in cls._instances:
6
- cls._instances[cls] = \
7
- super(Singleton, cls).__call__(*args, **kwargs)
8
-
9
- return cls._instances[cls]
@@ -1,82 +0,0 @@
1
-
2
-
3
- def print_number_of_runs(report):
4
-
5
- if report.number_of_runs == 1:
6
-
7
- if report.inteval > 1:
8
- print(f"Strategy ran every {report.interval} {report.time_unit} for a total of {report.number_of_runs} time")
9
-
10
-
11
- def pretty_print_backtest(backtest_report, show_positions=True, show_trades=True, precision=4):
12
- print("====================Backtest report===============================")
13
- print(f"* Start date: {backtest_report.backtest_start_date}")
14
- print(f"* End date: {backtest_report.backtest_end_date}")
15
- print(f"* Number of days: {backtest_report.number_of_days}")
16
- print(f"* Number of runs: {backtest_report.number_of_runs}")
17
- print("====================Portfolio overview============================")
18
- print(f"* Number of orders: {backtest_report.number_of_orders}")
19
- print(f"* Initial balance: "
20
- f"{backtest_report.initial_unallocated:.{precision}f} "
21
- f"{backtest_report.trading_symbol}")
22
- print(f"* Final balance: {backtest_report.total_value:.{precision}f} "
23
- f"{backtest_report.trading_symbol}")
24
- print(f"* Total net gain: {backtest_report.total_net_gain:.{precision}f} "
25
- f"{backtest_report.trading_symbol}")
26
- print(f"* Total net gain percentage: "
27
- f"{backtest_report.total_net_gain_percentage:.{precision}f}%")
28
- print(f"* Growth rate: "
29
- f"{float(backtest_report.growth_rate):.{precision}f}%")
30
- print(f"* Growth {backtest_report.growth:.{precision}f} "
31
- f"{backtest_report.trading_symbol}")
32
-
33
- if show_positions:
34
- print("====================Positions overview========================")
35
- print(f"* Number of positions at the end of backtest: {backtest_report.number_of_positions}")
36
- print(f"* Total cost of current positions: "
37
- f"{backtest_report.total_cost:.{precision}f} "
38
- f"{backtest_report.trading_symbol}")
39
- for position in backtest_report.positions:
40
- print(
41
- f"{position.symbol}, "
42
- f"amount: {position.amount:.{precision}f}, "
43
- f"cost: {position.cost:.{precision}f} "
44
- f"{backtest_report.trading_symbol}, "
45
- f"value: {position.value:.{precision}f} "
46
- f"{backtest_report.trading_symbol}, "
47
- f"growth: {position.growth:.{precision}f} "
48
- f"{backtest_report.trading_symbol} "
49
- f"({position.growth_rate:.{precision}f}%)."
50
- )
51
-
52
- if show_trades:
53
- print("====================Trades overview===========================")
54
- print(f"* Number of trades closed: "
55
- f"{backtest_report.number_of_trades_closed}")
56
- print(
57
- f"* Number of trades open: "
58
- f"{backtest_report.number_of_trades_open}"
59
- )
60
- print(f"* Percentage of positive trades: "
61
- f"{backtest_report.percentage_positive_trades}%")
62
- print(f"* Percentage of negative trades: "
63
- f"{backtest_report.percentage_negative_trades}%")
64
- print(f"* Average trade size: "
65
- f"{backtest_report.average_trade_size:.{precision}f} "
66
- f"{backtest_report.trading_symbol}")
67
- print(f"* Average trade duration: "
68
- f"{backtest_report.average_trade_duration} hours")
69
- for trade in backtest_report.trades:
70
- print(
71
- f"{trade.target_symbol} -> {trade.trading_symbol}, "
72
- f"open date: {trade.opened_at}, "
73
- f"close date: {trade.closed_at}, "
74
- f"size: {trade.size:.{precision}f} {trade.trading_symbol}, "
75
- f"net gain: {trade.net_gain:.{precision}f}, "
76
- f"net gain percentage: "
77
- f"{trade.net_gain_percentage:.{precision}f}%, "
78
- f"duration: {trade.duration} hours, "
79
- f"open price: {trade.open_price}, "
80
- f"close price: {trade.closed_price}"
81
- )
82
- print("==================================================================")
@@ -1,21 +0,0 @@
1
- from sqlalchemy import Column, Integer, String, ForeignKey, Float
2
- from sqlalchemy.orm import relationship
3
-
4
- from investing_algorithm_framework.domain import OrderFee
5
- from investing_algorithm_framework.infrastructure.database import SQLBaseModel
6
- from investing_algorithm_framework.infrastructure.models.model_extension \
7
- import SQLAlchemyModelExtension
8
-
9
-
10
- class SQLOrderFee(OrderFee, SQLBaseModel, SQLAlchemyModelExtension):
11
- __tablename__ = "order_fees"
12
- id = Column(Integer, primary_key=True, unique=True)
13
- currency = Column(String)
14
- cost = Column(Float)
15
- rate = Column(Float)
16
- order_id = Column(Integer, ForeignKey('orders.id'))
17
- order = relationship("SQLOrder", back_populates="fee")
18
-
19
- def __init__(self, currency, cost, rate, order_id):
20
- super().__init__(currency, cost, rate)
21
- self.order_id = order_id
@@ -1,15 +0,0 @@
1
- from investing_algorithm_framework.infrastructure.models import SQLOrderFee
2
- from .repository import Repository
3
-
4
-
5
- class SQLOrderFeeRepository(Repository):
6
- base_class = SQLOrderFee
7
- DEFAULT_NOT_FOUND_MESSAGE = "Order fee not found"
8
-
9
- def _apply_query_params(self, db, query, query_params):
10
- order_query_param = self.get_query_param("order", query_params)
11
-
12
- if order_query_param:
13
- query = query.filter_by(order_id=order_query_param)
14
-
15
- return query