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,455 +0,0 @@
1
- import logging
2
- from datetime import datetime
3
- from time import sleep
4
- from typing import Dict
5
-
6
- import ccxt
7
- import polars as pl
8
- from dateutil import parser
9
-
10
- from investing_algorithm_framework.domain import OperationalException, Order, \
11
- MarketService, DATETIME_FORMAT, TimeFrame
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
-
16
- class CCXTMarketService(MarketService):
17
- """
18
- Market service implementation using the CCXT library
19
- """
20
- msec = 1000
21
- minute = 60 * msec
22
-
23
- def __init__(self, market_credential_service):
24
- super(CCXTMarketService, self).__init__(
25
- market_credential_service=market_credential_service,
26
- )
27
-
28
- @property
29
- def config(self):
30
- return self._config
31
-
32
- @config.setter
33
- def config(self, config):
34
- self._config = config
35
-
36
- def initialize_exchange(self, market, market_credential):
37
- market = market.lower()
38
- if not hasattr(ccxt, market):
39
- raise OperationalException(
40
- f"No market service found for market id {market}"
41
- )
42
-
43
- exchange_class = getattr(ccxt, market)
44
-
45
- if exchange_class is None:
46
- raise OperationalException(
47
- f"No market service found for market id {market}"
48
- )
49
-
50
- if market_credential is not None:
51
- exchange = exchange_class({
52
- 'apiKey': market_credential.api_key,
53
- 'secret': market_credential.secret_key,
54
- })
55
- else:
56
- exchange = exchange_class({})
57
-
58
- return exchange
59
-
60
- def pair_exists(self, target_symbol: str, trading_symbol: str, market):
61
- market_credential = self.get_market_credential(market)
62
- exchange = self.initialize_exchange(market, market_credential)
63
-
64
- if not exchange.has['fetchTicker']:
65
- raise OperationalException(
66
- f"Market service {market} does not support "
67
- f"functionality pair_exists"
68
- )
69
-
70
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
71
- try:
72
- data = exchange.fetchTicker(symbol)
73
- return "symbol" in data
74
- except OperationalException:
75
- return False
76
-
77
- def get_ticker(self, symbol, market):
78
- market_credential = self.get_market_credential(market)
79
- exchange = self.initialize_exchange(market, market_credential)
80
-
81
- if not exchange.has['fetchTicker']:
82
- raise OperationalException(
83
- f"Market service {market} does not support "
84
- f"functionality get_ticker"
85
- )
86
-
87
- try:
88
- return exchange.fetchTicker(symbol)
89
- except Exception as e:
90
- logger.exception(e)
91
- raise OperationalException(
92
- f"Could not retrieve ticker for symbol {symbol}"
93
- )
94
-
95
- def get_tickers(self, symbols, market):
96
- market_credential = self.get_market_credential(market)
97
- exchange = self.initialize_exchange(market, market_credential)
98
-
99
- if not exchange.has['fetchTickers']:
100
- raise OperationalException(
101
- f"Market service {market} does not support "
102
- f"functionality get_tickers"
103
- )
104
-
105
- try:
106
- return exchange.fetchTickers(symbols)
107
- except Exception as e:
108
- logger.exception(e)
109
- raise OperationalException(
110
- "Could not retrieve selection of tickers"
111
- )
112
-
113
- def get_order_book(self, symbol, market):
114
- market_credential = self.get_market_credential(market)
115
- exchange = self.initialize_exchange(market, market_credential)
116
-
117
- if not exchange.has['fetchOrderBook']:
118
- raise OperationalException(
119
- f"Market service {market} does not support "
120
- f"functionality get_order_book"
121
- )
122
-
123
- try:
124
- return exchange.fetchOrderBook(symbol)
125
- except Exception as e:
126
- logger.exception(e)
127
- raise OperationalException("Could not retrieve order book")
128
-
129
- def get_order_books(self, symbols, market):
130
- data = {}
131
-
132
- for symbol in symbols:
133
- try:
134
- entry = self.get_order_book(symbol, market)
135
- del entry['symbol']
136
- data[symbol] = entry
137
- except Exception as e:
138
- logger.exception(e)
139
-
140
- return data
141
-
142
- def get_order(self, order, market):
143
- market_credential = self.get_market_credential(market)
144
- exchange = self.initialize_exchange(market, market_credential)
145
- symbol = f"{order.target_symbol.upper()}/" \
146
- f"{order.trading_symbol.upper()}"
147
-
148
- if not exchange.has['fetchOrder']:
149
- raise OperationalException(
150
- f"Market service {market} does not support "
151
- f"functionality get_order"
152
- )
153
-
154
- try:
155
- order = exchange.fetchOrder(order.external_id, symbol)
156
- return Order.from_ccxt_order(order)
157
- except Exception as e:
158
- logger.exception(e)
159
- raise OperationalException("Could not retrieve order")
160
-
161
- def get_orders(self, symbol, market, since: datetime = None):
162
- market_credential = self.get_market_credential(market)
163
- exchange = self.initialize_exchange(market, market_credential)
164
- datetime_format = self.config["DATETIME_FORMAT"]
165
-
166
- if not exchange.has['fetchOrders']:
167
- raise OperationalException(
168
- f"Market service {market} does not support "
169
- f"functionality get_orders"
170
- )
171
-
172
- if since is not None:
173
- since = exchange.parse8601(datetime_format)
174
-
175
- try:
176
- ccxt_orders = exchange.fetchOrders(symbol, since=since)
177
- return [Order.from_ccxt_order(order) for order in ccxt_orders]
178
- except Exception as e:
179
- logger.exception(e)
180
- raise OperationalException("Could not retrieve orders")
181
- else:
182
- try:
183
- ccxt_orders = exchange.fetchOrders(symbol)
184
- return [Order.from_ccxt_order(order) for order in ccxt_orders]
185
- except Exception as e:
186
- logger.exception(e)
187
- raise OperationalException("Could not retrieve orders")
188
-
189
- def get_balance(self, market) -> Dict[str, float]:
190
- market_credential = self.get_market_credential(market)
191
-
192
- if market_credential is None:
193
- raise OperationalException(
194
- f"You don't have a market credential for market {market}"
195
- )
196
-
197
- exchange = self.initialize_exchange(market, market_credential)
198
-
199
- if not exchange.has['fetchBalance']:
200
- raise OperationalException(
201
- f"Market service {market} does not support "
202
- f"functionality get_balance"
203
- )
204
-
205
- try:
206
- return exchange.fetchBalance()["free"]
207
- except Exception as e:
208
- logger.exception(e)
209
- raise OperationalException(
210
- f"Please make sure you have "
211
- f"registered a valid market credential "
212
- f"object to the app: {str(e)}"
213
- )
214
-
215
- def create_limit_buy_order(
216
- self,
217
- target_symbol: str,
218
- trading_symbol: str,
219
- amount: float,
220
- price: float,
221
- market
222
- ):
223
- market_credential = self.get_market_credential(market)
224
- exchange = self.initialize_exchange(market, market_credential)
225
-
226
- if not exchange.has['createLimitBuyOrder']:
227
- raise OperationalException(
228
- f"Market service {market} does not support "
229
- f"functionality create_limit_buy_order"
230
- )
231
-
232
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
233
-
234
- try:
235
- order = exchange.createLimitBuyOrder(
236
- symbol, amount, price
237
- )
238
- return Order.from_ccxt_order(order)
239
- except Exception as e:
240
- logger.exception(e)
241
- raise OperationalException("Could not create limit buy order")
242
-
243
- def create_limit_sell_order(
244
- self,
245
- target_symbol: str,
246
- trading_symbol: str,
247
- amount: float,
248
- price: float,
249
- market
250
- ):
251
- market_credential = self.get_market_credential(market)
252
- exchange = self.initialize_exchange(market, market_credential)
253
-
254
- if not exchange.has['createLimitSellOrder']:
255
- raise OperationalException(
256
- f"Market service {market} does not support "
257
- f"functionality create_limit_sell_order"
258
- )
259
-
260
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
261
-
262
- try:
263
- order = exchange.createLimitSellOrder(
264
- symbol, amount, price
265
- )
266
- return Order.from_ccxt_order(order)
267
- except Exception as e:
268
- logger.exception(e)
269
- raise OperationalException("Could not create limit sell order")
270
-
271
- def create_market_sell_order(
272
- self,
273
- target_symbol: str,
274
- trading_symbol: str,
275
- amount: float,
276
- market
277
- ):
278
- market_credential = self.get_market_credential(market)
279
- exchange = self.initialize_exchange(market, market_credential)
280
-
281
- if not exchange.has['createMarketSellOrder']:
282
- raise OperationalException(
283
- f"Market service {market} does not support "
284
- f"functionality create_market_sell_order"
285
- )
286
-
287
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
288
-
289
- try:
290
- order = exchange.createMarketSellOrder(symbol, amount)
291
- return Order.from_ccxt_order(order)
292
- except Exception as e:
293
- logger.exception(e)
294
- raise OperationalException("Could not create market sell order")
295
-
296
- def cancel_order(self, order, market):
297
- market_credential = self.get_market_credential(market)
298
- exchange = self.initialize_exchange(market, market_credential)
299
-
300
- if not exchange.has['cancelOrder']:
301
- raise OperationalException(
302
- f"Market service {market} does not support "
303
- f"functionality cancel_order"
304
- )
305
-
306
- exchange.cancelOrder(
307
- order.get_order_reference(),
308
- f"{order.get_target_symbol()}/{order.get_trading_symbol()}")
309
-
310
- def get_open_orders(
311
- self, market, target_symbol: str = None, trading_symbol: str = None
312
- ):
313
- market_credential = self.get_market_credential(market)
314
- exchange = self.initialize_exchange(market, market_credential)
315
-
316
- if not exchange.has['fetchOpenOrders']:
317
- raise OperationalException(
318
- f"Market service {market} does not support "
319
- f"functionality get_open_orders"
320
- )
321
-
322
- try:
323
- if target_symbol is None or trading_symbol is None:
324
- return exchange.fetchOpenOrders()
325
-
326
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
327
- ccxt_orders = exchange.fetchOpenOrders(symbol)
328
- return [Order.from_ccxt_order(order) for order in ccxt_orders]
329
- except Exception as e:
330
- logger.exception(e)
331
- raise OperationalException("Could not retrieve open orders")
332
-
333
- def get_closed_orders(
334
- self, market, target_symbol: str = None, trading_symbol: str = None
335
- ):
336
- market_credential = self.get_market_credential(market)
337
- exchange = self.initialize_exchange(market, market_credential)
338
-
339
- if not exchange.has['fetchClosedOrders']:
340
- raise OperationalException(
341
- f"Market service {market} does not support "
342
- f"functionality get_closed_orders"
343
- )
344
-
345
- try:
346
- if target_symbol is None or trading_symbol is None:
347
- return exchange.fetchClosedOrders()
348
-
349
- symbol = f"{target_symbol.upper()}/{trading_symbol.upper()}"
350
- ccxt_orders = exchange.fetchClosedOrders(symbol)
351
- return [Order.from_ccxt_order(order) for order in ccxt_orders]
352
- except Exception as e:
353
- logger.exception(e)
354
- raise OperationalException("Could not retrieve closed orders")
355
-
356
- def get_ohlcv(
357
- self, symbol, time_frame, from_timestamp, market, to_timestamp=None
358
- ) -> pl.DataFrame:
359
- time_frame = TimeFrame.from_value(time_frame).value
360
-
361
- if self.config is not None and "DATETIME_FORMAT" in self.config:
362
- datetime_format = self.config["DATETIME_FORMAT"]
363
- else:
364
- datetime_format = DATETIME_FORMAT
365
-
366
- market_credential = self.get_market_credential(market)
367
- exchange = self.initialize_exchange(market, market_credential)
368
-
369
- if not exchange.has['fetchOHLCV']:
370
- raise OperationalException(
371
- f"Market service {market} does not support "
372
- f"functionality get_ohclvs"
373
- )
374
-
375
- from_time_stamp = exchange.parse8601(
376
- from_timestamp.strftime(datetime_format)
377
- )
378
-
379
- if to_timestamp is None:
380
- to_timestamp = exchange.milliseconds()
381
- else:
382
- to_timestamp = exchange.parse8601(
383
- to_timestamp.strftime(datetime_format)
384
- )
385
- data = []
386
-
387
- while from_time_stamp < to_timestamp:
388
- ohlcv = exchange.fetch_ohlcv(symbol, time_frame, from_time_stamp)
389
-
390
- if len(ohlcv) > 0:
391
- from_time_stamp = \
392
- ohlcv[-1][0] + exchange.parse_timeframe(time_frame) * 1000
393
- else:
394
- from_time_stamp = to_timestamp
395
-
396
- for candle in ohlcv:
397
- datetime_stamp = parser.parse(exchange.iso8601(candle[0]))
398
-
399
- to_timestamp_datetime = parser.parse(
400
- exchange.iso8601(to_timestamp),
401
- )
402
-
403
- if datetime_stamp <= to_timestamp_datetime:
404
- datetime_stamp = datetime_stamp\
405
- .strftime(datetime_format)
406
-
407
- data.append([datetime_stamp] + candle[1:])
408
-
409
- sleep(exchange.rateLimit / 1000)
410
-
411
- # Predefined column names
412
- col_names = ["Datetime", "Open", "High", "Low", "Close", "Volume"]
413
-
414
- # Combine the Series into a DataFrame with given column names
415
- df = pl.DataFrame(data)
416
-
417
- # Assign column names after DataFrame creation
418
- df.columns = col_names
419
- return df
420
-
421
- def get_ohlcvs(
422
- self,
423
- symbols,
424
- time_frame,
425
- from_timestamp,
426
- market,
427
- to_timestamp=None
428
- ) -> Dict[str, pl.DataFrame]:
429
- ohlcvs = {}
430
- time_frame = TimeFrame.from_value(time_frame).value
431
-
432
- for symbol in symbols:
433
-
434
- try:
435
- ohlcvs[symbol] = self.get_ohlcv(
436
- symbol=symbol,
437
- time_frame=time_frame,
438
- from_timestamp=from_timestamp,
439
- to_timestamp=to_timestamp,
440
- market=market
441
- )
442
- except Exception as e:
443
- logger.exception(e)
444
- logger.error(f"Could not retrieve ohlcv data for {symbol}")
445
-
446
- return ohlcvs
447
-
448
- def get_symbols(self, market):
449
- """
450
- Get all available symbols for a given market
451
- """
452
- market_credential = self.get_market_credential(market)
453
- exchange = self.initialize_exchange(market, market_credential)
454
- market_information = exchange.load_markets()
455
- return list(market_information.keys())
@@ -1,7 +0,0 @@
1
- from .backtest_performance_service import BacktestPerformanceService
2
- from .performance_service import PerformanceService
3
-
4
- __all__ = [
5
- "PerformanceService",
6
- "BacktestPerformanceService"
7
- ]
@@ -1,2 +0,0 @@
1
- class BacktestPerformanceService:
2
- pass