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,24 +1,56 @@
1
- from investing_algorithm_framework.app import App, Algorithm, AppHook
2
- from investing_algorithm_framework.app import TradingStrategy, \
3
- StatelessAction, Task
4
- from investing_algorithm_framework.domain import ApiException, \
5
- TradingDataType, TradingTimeFrame, OrderType, OperationalException, \
6
- OrderStatus, OrderSide, Config, TimeUnit, TimeInterval, Order, Portfolio, \
7
- Position, TimeFrame, BACKTESTING_INDEX_DATETIME, MarketCredential, \
8
- PortfolioConfiguration, RESOURCE_DIRECTORY, pretty_print_backtest, \
9
- Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, SYMBOLS, \
10
- TickerMarketDataSource, MarketService, BacktestReportsEvaluation, \
11
- pretty_print_backtest_reports_evaluation, load_backtest_reports, \
12
- RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
13
- load_backtest_report, BacktestDateRange, create_ema_graph, \
14
- create_prices_graph, create_rsi_graph, get_price_efficiency_ratio
15
- from investing_algorithm_framework.infrastructure import \
16
- CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
17
- CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
18
- CSVTickerMarketDataSource
1
+ from .app import App, Algorithm, \
2
+ TradingStrategy, StatelessAction, Task, AppHook, Context, \
3
+ add_html_report, BacktestReport, save_backtests_to_directory, \
4
+ pretty_print_trades, pretty_print_positions, \
5
+ pretty_print_orders, pretty_print_backtest, select_backtest_date_ranges, \
6
+ get_equity_curve_with_drawdown_chart, load_backtests_from_directory, \
7
+ get_rolling_sharpe_ratio_chart, rank_results, \
8
+ get_monthly_returns_heatmap_chart, create_weights, \
9
+ get_yearly_returns_bar_chart, get_entry_and_exit_signals, \
10
+ get_ohlcv_data_completeness_chart, get_equity_curve_chart
11
+ from .domain import ApiException, combine_backtests, PositionSize, \
12
+ OrderType, OperationalException, OrderStatus, OrderSide, \
13
+ TimeUnit, TimeInterval, Order, Portfolio, Backtest, DataError, \
14
+ Position, TimeFrame, INDEX_DATETIME, MarketCredential, TakeProfitRule, \
15
+ PortfolioConfiguration, RESOURCE_DIRECTORY, AWS_LAMBDA_LOGGING_CONFIG, \
16
+ Trade, APP_MODE, AppMode, DATETIME_FORMAT, \
17
+ BacktestDateRange, convert_polars_to_pandas, BacktestRun, \
18
+ DEFAULT_LOGGING_CONFIG, DataType, DataProvider, StopLossRule, \
19
+ TradeStatus, generate_backtest_summary_metrics, \
20
+ APPLICATION_DIRECTORY, DataSource, OrderExecutor, PortfolioProvider, \
21
+ SnapshotInterval, AWS_S3_STATE_BUCKET_NAME, BacktestEvaluationFocus
22
+ from .infrastructure import AzureBlobStorageStateHandler, \
23
+ CSVOHLCVDataProvider, CCXTOHLCVDataProvider, PandasOHLCVDataProvider, \
24
+ AWSS3StorageStateHandler
19
25
  from .create_app import create_app
20
- from investing_algorithm_framework.services import \
21
- create_trade_exit_markers_chart, create_trade_entry_markers_chart
26
+ from .download_data import download
27
+ from .services import get_annual_volatility, get_sortino_ratio, \
28
+ get_drawdown_series, get_max_drawdown, get_equity_curve, \
29
+ get_price_efficiency_ratio, get_sharpe_ratio, \
30
+ get_profit_factor, get_cumulative_profit_factor_series, \
31
+ get_rolling_profit_factor_series, get_cagr, \
32
+ get_standard_deviation_returns, get_standard_deviation_downside_returns, \
33
+ get_max_drawdown_absolute, get_total_return, get_exposure_ratio, \
34
+ get_average_trade_duration, get_win_rate, get_win_loss_ratio, \
35
+ get_calmar_ratio, get_trade_frequency, get_yearly_returns, \
36
+ get_monthly_returns, get_best_year, get_best_month, get_worst_year, \
37
+ get_worst_month, get_best_trade, get_worst_trade, \
38
+ get_average_yearly_return, get_average_trade_gain, \
39
+ get_average_trade_loss, get_average_monthly_return, \
40
+ get_percentage_winning_months, get_max_drawdown_duration, \
41
+ get_max_daily_drawdown, get_trades_per_day, \
42
+ get_trades_per_year, get_average_monthly_return_losing_months, \
43
+ get_average_monthly_return_winning_months, get_percentage_winning_years, \
44
+ get_rolling_sharpe_ratio, create_backtest_metrics, get_total_growth, \
45
+ get_total_loss, get_cumulative_exposure, get_median_trade_return, \
46
+ get_average_trade_return, get_risk_free_rate_us, get_cumulative_return, \
47
+ get_cumulative_return_series, get_current_average_trade_return, \
48
+ get_current_average_trade_gain, get_current_average_trade_duration, \
49
+ get_current_average_trade_loss, get_negative_trades, \
50
+ get_positive_trades, get_number_of_trades, get_current_win_rate, \
51
+ get_current_win_loss_ratio, create_backtest_metrics_for_backtest, \
52
+ TradeTakeProfitService, TradeStopLossService
53
+
22
54
 
23
55
  __all__ = [
24
56
  "Algorithm",
@@ -27,12 +59,9 @@ __all__ = [
27
59
  "AppHook",
28
60
  "create_app",
29
61
  "ApiException",
30
- "TradingDataType",
31
- "TradingTimeFrame",
32
62
  "OrderType",
33
63
  "OrderStatus",
34
64
  "OrderSide",
35
- "Config",
36
65
  "PortfolioConfiguration",
37
66
  "TimeUnit",
38
67
  "TimeInterval",
@@ -43,34 +72,128 @@ __all__ = [
43
72
  "StatelessAction",
44
73
  "Task",
45
74
  "pretty_print_backtest",
46
- "BACKTESTING_INDEX_DATETIME",
75
+ "INDEX_DATETIME",
47
76
  "Trade",
48
77
  "TimeFrame",
49
- "CCXTOrderBookMarketDataSource",
50
- "CCXTTickerMarketDataSource",
51
- "CCXTOHLCVMarketDataSource",
52
- "OHLCVMarketDataSource",
53
- "OrderBookMarketDataSource",
54
- "TickerMarketDataSource",
55
- "CSVOHLCVMarketDataSource",
56
- "CSVTickerMarketDataSource",
57
78
  "MarketCredential",
58
- "MarketService",
59
79
  "OperationalException",
60
- "pretty_print_backtest_reports_evaluation",
61
- "BacktestReportsEvaluation",
62
- "load_backtest_reports",
63
- "SYMBOLS",
64
- "RESERVED_BALANCES",
65
80
  "APP_MODE",
66
81
  "AppMode",
67
82
  "DATETIME_FORMAT",
68
- "load_backtest_report",
83
+ "Backtest",
69
84
  "BacktestDateRange",
70
- "create_trade_exit_markers_chart",
71
- "create_trade_entry_markers_chart",
72
- "create_ema_graph",
73
- "create_prices_graph",
74
- "create_rsi_graph",
75
- "get_price_efficiency_ratio"
85
+ "convert_polars_to_pandas",
86
+ "AzureBlobStorageStateHandler",
87
+ "DEFAULT_LOGGING_CONFIG",
88
+ "BacktestReport",
89
+ "TradeStatus",
90
+ "Context",
91
+ "APPLICATION_DIRECTORY",
92
+ "download",
93
+ "pretty_print_orders",
94
+ "pretty_print_trades",
95
+ "pretty_print_positions",
96
+ "DataSource",
97
+ "OrderExecutor",
98
+ "PortfolioProvider",
99
+ "SnapshotInterval",
100
+ "add_html_report",
101
+ "AWSS3StorageStateHandler",
102
+ "AWS_S3_STATE_BUCKET_NAME",
103
+ "AWS_LAMBDA_LOGGING_CONFIG",
104
+ 'select_backtest_date_ranges',
105
+ 'DataType',
106
+ 'CSVOHLCVDataProvider',
107
+ "CCXTOHLCVDataProvider",
108
+ "DataProvider",
109
+ "get_annual_volatility",
110
+ "get_sortino_ratio",
111
+ "get_drawdown_series",
112
+ "get_max_drawdown",
113
+ "get_equity_curve",
114
+ "get_price_efficiency_ratio",
115
+ "get_sharpe_ratio",
116
+ "get_profit_factor",
117
+ "get_cumulative_profit_factor_series",
118
+ "get_rolling_profit_factor_series",
119
+ "get_sharpe_ratio",
120
+ "get_cagr",
121
+ "get_standard_deviation_returns",
122
+ "get_standard_deviation_downside_returns",
123
+ "get_max_drawdown_absolute",
124
+ "get_total_return",
125
+ "get_exposure_ratio",
126
+ "get_cumulative_exposure",
127
+ "get_average_trade_duration",
128
+ "get_win_rate",
129
+ "get_win_loss_ratio",
130
+ "get_calmar_ratio",
131
+ "get_trade_frequency",
132
+ "get_yearly_returns",
133
+ "get_monthly_returns",
134
+ "get_best_year",
135
+ "get_best_month",
136
+ "get_worst_year",
137
+ "get_worst_month",
138
+ "get_best_trade",
139
+ "get_worst_trade",
140
+ "get_average_yearly_return",
141
+ "get_average_trade_gain",
142
+ "get_average_trade_loss",
143
+ "get_average_monthly_return",
144
+ "get_percentage_winning_months",
145
+ "get_average_trade_duration",
146
+ "get_trade_frequency",
147
+ "get_win_rate",
148
+ "get_win_loss_ratio",
149
+ "get_calmar_ratio",
150
+ "get_max_drawdown_absolute",
151
+ "get_max_drawdown_duration",
152
+ "get_max_daily_drawdown",
153
+ "get_trades_per_day",
154
+ "get_trades_per_year",
155
+ "get_average_monthly_return_losing_months",
156
+ "get_average_monthly_return_winning_months",
157
+ "get_percentage_winning_years",
158
+ "get_rolling_sharpe_ratio",
159
+ "create_backtest_metrics",
160
+ "PandasOHLCVDataProvider",
161
+ "get_equity_curve_with_drawdown_chart",
162
+ "get_rolling_sharpe_ratio_chart",
163
+ "get_monthly_returns_heatmap_chart",
164
+ "get_yearly_returns_bar_chart",
165
+ "get_ohlcv_data_completeness_chart",
166
+ "rank_results",
167
+ "create_weights",
168
+ "get_entry_and_exit_signals",
169
+ "BacktestEvaluationFocus",
170
+ "combine_backtests",
171
+ "PositionSize",
172
+ "get_median_trade_return",
173
+ "get_average_trade_return",
174
+ "get_risk_free_rate_us",
175
+ "get_cumulative_return",
176
+ "get_cumulative_return_series",
177
+ "get_total_loss",
178
+ "get_total_growth",
179
+ "generate_backtest_summary_metrics",
180
+ "get_equity_curve_chart",
181
+ "get_current_win_rate",
182
+ "get_current_win_loss_ratio",
183
+ "get_current_average_trade_loss",
184
+ "get_current_average_trade_duration",
185
+ "get_current_average_trade_gain",
186
+ "get_current_average_trade_return",
187
+ "get_negative_trades",
188
+ "get_positive_trades",
189
+ "get_number_of_trades",
190
+ "BacktestRun",
191
+ "load_backtests_from_directory",
192
+ "save_backtests_to_directory",
193
+ "DataError",
194
+ "create_backtest_metrics_for_backtest",
195
+ "TakeProfitRule",
196
+ "StopLossRule",
197
+ "TradeStopLossService",
198
+ "TradeTakeProfitService"
76
199
  ]
@@ -4,6 +4,18 @@ from investing_algorithm_framework.app.strategy import TradingStrategy
4
4
  from investing_algorithm_framework.app.task import Task
5
5
  from investing_algorithm_framework.app.web import create_flask_app
6
6
  from .algorithm import Algorithm
7
+ from .context import Context
8
+ from .reporting import add_html_report, \
9
+ BacktestReport, pretty_print_backtest, pretty_print_trades, \
10
+ pretty_print_positions, pretty_print_orders, \
11
+ get_equity_curve_with_drawdown_chart, \
12
+ get_rolling_sharpe_ratio_chart, \
13
+ get_monthly_returns_heatmap_chart, \
14
+ get_yearly_returns_bar_chart, get_equity_curve_chart, \
15
+ get_ohlcv_data_completeness_chart, get_entry_and_exit_signals
16
+ from .analysis import select_backtest_date_ranges, rank_results, \
17
+ create_weights, load_backtests_from_directory, save_backtests_to_directory
18
+
7
19
 
8
20
  __all__ = [
9
21
  "Algorithm",
@@ -12,5 +24,24 @@ __all__ = [
12
24
  "TradingStrategy",
13
25
  "StatelessAction",
14
26
  "Task",
15
- "AppHook"
27
+ "AppHook",
28
+ "Context",
29
+ "add_html_report",
30
+ "BacktestReport",
31
+ "pretty_print_backtest",
32
+ "pretty_print_trades",
33
+ "pretty_print_positions",
34
+ "pretty_print_orders",
35
+ "select_backtest_date_ranges",
36
+ "get_equity_curve_with_drawdown_chart",
37
+ "get_rolling_sharpe_ratio_chart",
38
+ "get_monthly_returns_heatmap_chart",
39
+ "get_yearly_returns_bar_chart",
40
+ "get_ohlcv_data_completeness_chart",
41
+ "rank_results",
42
+ "create_weights",
43
+ "get_entry_and_exit_signals",
44
+ "get_equity_curve_chart",
45
+ "load_backtests_from_directory",
46
+ "save_backtests_to_directory"
16
47
  ]
@@ -0,0 +1,7 @@
1
+ from .algorithm_factory import AlgorithmFactory
2
+ from .algorithm import Algorithm
3
+
4
+ __all__ = [
5
+ "AlgorithmFactory",
6
+ "Algorithm"
7
+ ]
@@ -0,0 +1,239 @@
1
+ import inspect
2
+ import logging
3
+ import re
4
+ from typing import List
5
+
6
+ from investing_algorithm_framework.app.app_hook import AppHook
7
+ from investing_algorithm_framework.app.strategy import TradingStrategy
8
+ from investing_algorithm_framework.domain import OperationalException, \
9
+ DataSource
10
+
11
+ logger = logging.getLogger("investing_algorithm_framework")
12
+
13
+
14
+ class Algorithm:
15
+ """
16
+ Class to represent an algorithm. An algorithm is a collection of
17
+ strategies that are executed in a specific order.
18
+
19
+ Attributes:
20
+ _name: The name of the algorithm. It should be a string and
21
+ can only contain letters and numbers.
22
+ _description: The description of the algorithm. It should be a string.
23
+ _strategies: A list of strategies that are part of the algorithm.
24
+ _tasks: A list of tasks that are part of the algorithm.
25
+ _data_sources: A list of data sources that are part of the algorithm.
26
+ _on_strategy_run_hooks: A list of hooks that will be called when a
27
+ """
28
+ def __init__(
29
+ self,
30
+ name: str = None,
31
+ description: str = None,
32
+ strategy=None,
33
+ strategies=None,
34
+ tasks: List = None,
35
+ data_sources: List[DataSource] = None,
36
+ on_strategy_run_hooks=None,
37
+ metadata=None
38
+ ):
39
+ self._name = name
40
+ self._context = {}
41
+ self._description = None
42
+
43
+ if description is not None:
44
+ self._description = description
45
+
46
+ self._strategies = []
47
+ self._tasks = []
48
+ self._data_sources = []
49
+ self._on_strategy_run_hooks = []
50
+ self.metadata = metadata
51
+
52
+ if data_sources is not None:
53
+ self._data_sources = data_sources
54
+
55
+ if strategies is not None:
56
+ self.strategies = strategies
57
+
58
+ if tasks is not None:
59
+ self.tasks = tasks
60
+
61
+ if strategy is not None:
62
+ self.add_strategy(strategy, throw_exception=True)
63
+
64
+ if on_strategy_run_hooks is not None:
65
+ for hook in on_strategy_run_hooks:
66
+ self.add_on_strategy_run_hook(hook)
67
+
68
+ @staticmethod
69
+ def _validate_name(name):
70
+ """
71
+ Function to validate the name of the algorithm. This function
72
+ will check if the name of the algorithm is a string and raise
73
+ an exception if it is not.
74
+
75
+ Name can only contain letters, numbers
76
+
77
+ Parameters:
78
+ name: The name of the algorithm
79
+
80
+ Returns:
81
+ None
82
+ """
83
+ if not isinstance(name, str):
84
+ raise OperationalException(
85
+ "The name of the algorithm must be a string"
86
+ )
87
+
88
+ pattern = re.compile(r"^[a-zA-Z0-9]*$")
89
+
90
+ if not pattern.match(name):
91
+ raise OperationalException(
92
+ "The name of the algorithm can only contain" +
93
+ " letters and numbers"
94
+ )
95
+
96
+ illegal_chars = r"[\/:*?\"<>|]"
97
+
98
+ if re.search(illegal_chars, name):
99
+ raise OperationalException(
100
+ f"Illegal characters detected in algorithm: {name}. "
101
+ f"Illegal characters: / \\ : * ? \" < > |"
102
+ )
103
+
104
+ @property
105
+ def name(self):
106
+ return self._name
107
+
108
+ @name.setter
109
+ def name(self, name):
110
+ Algorithm._validate_name(name)
111
+ self._name = name
112
+
113
+ @property
114
+ def data_sources(self):
115
+ return self._data_sources
116
+
117
+ @data_sources.setter
118
+ def data_sources(self, data_sources):
119
+ self._data_sources = data_sources
120
+
121
+ @property
122
+ def description(self):
123
+ """
124
+ Function to get the description of the algorithm
125
+ """
126
+ return self._description
127
+
128
+ @property
129
+ def strategies(self):
130
+ return self._strategies
131
+
132
+ @property
133
+ def on_strategy_run_hooks(self):
134
+ return self._on_strategy_run_hooks
135
+
136
+ @strategies.setter
137
+ def strategies(self, strategies):
138
+
139
+ for strategy in strategies:
140
+ self.add_strategy(strategy)
141
+
142
+ @property
143
+ def tasks(self):
144
+ return self._tasks
145
+
146
+ @tasks.setter
147
+ def tasks(self, tasks):
148
+
149
+ for task in tasks:
150
+ self.add_task(task)
151
+
152
+ def get_strategy(self, strategy_id):
153
+ for strategy in self._strategies:
154
+ if strategy.worker_id == strategy_id:
155
+ return strategy
156
+
157
+ return None
158
+
159
+ def get_strategies(self):
160
+
161
+ if self._strategies is None:
162
+ raise OperationalException(
163
+ "No strategies have been added to the algorithm"
164
+ )
165
+ return self._strategies
166
+
167
+ def add_strategy(self, strategy, throw_exception=True) -> None:
168
+ """
169
+ Function to add a strategy to the algorithm. The strategy should be an
170
+ instance of TradingStrategy or a subclass based on the TradingStrategy
171
+ class.
172
+
173
+ Args:
174
+ strategy: Instance of TradingStrategy
175
+ throw_exception: Flag to allow for throwing an exception when
176
+ the provided strategy is not inline with what the application
177
+ expects.
178
+
179
+ Returns:
180
+ None
181
+ """
182
+
183
+ if inspect.isclass(strategy):
184
+
185
+ if not issubclass(strategy, TradingStrategy):
186
+ raise OperationalException(
187
+ "The strategy must be a subclass of TradingStrategy"
188
+ )
189
+
190
+ strategy = strategy()
191
+
192
+ if not isinstance(strategy, TradingStrategy):
193
+
194
+ if throw_exception:
195
+ raise OperationalException(
196
+ "Strategy should be an instance of TradingStrategy"
197
+ )
198
+ else:
199
+ return
200
+
201
+ has_duplicates = False
202
+
203
+ for i in range(len(self._strategies)):
204
+ for j in range(i + 1, len(self._strategies)):
205
+ if self._strategies[i].worker_id == strategy.worker_id:
206
+ has_duplicates = True
207
+ break
208
+
209
+ if has_duplicates:
210
+ raise OperationalException(
211
+ "Can't add strategy, there already exists a strategy "
212
+ "with the same id in the algorithm"
213
+ )
214
+
215
+ self._strategies.append(strategy)
216
+
217
+ def add_task(self, task):
218
+ if inspect.isclass(task):
219
+ task = task()
220
+
221
+ self._tasks.append(task)
222
+
223
+ def add_on_strategy_run_hook(self, app_hook):
224
+ """
225
+ Function to add a hook that will be called when a strategy is run.
226
+
227
+ Args:
228
+ app_hook: The hook function to be added.
229
+ """
230
+ # Check if the app_hook inherits from AppHook
231
+ if inspect.isclass(app_hook) and not issubclass(app_hook, AppHook):
232
+ raise OperationalException(
233
+ "App hook should be an instance of AppHook"
234
+ )
235
+
236
+ if inspect.isclass(app_hook):
237
+ app_hook = app_hook()
238
+
239
+ self._on_strategy_run_hooks.append(app_hook)
@@ -0,0 +1,114 @@
1
+ import re
2
+ from .algorithm import Algorithm
3
+ from investing_algorithm_framework.domain import OperationalException
4
+
5
+
6
+ def validate_algorithm_name(name, illegal_chars=r"[\/:*?\"<>|]"):
7
+ """
8
+ Validate an algorithm name for illegal characters and throw an
9
+ exception if any are found.
10
+
11
+ Args:
12
+ name (str): The name to validate.
13
+ illegal_chars (str): A regex pattern for characters considered
14
+ illegal (default: r"[/:*?\"<>|]").
15
+
16
+ Raises:
17
+ ValueError: If illegal characters are found in the filename.
18
+ """
19
+ if re.search(illegal_chars, name):
20
+ raise OperationalException(
21
+ f"Illegal characters detected in filename: {name}. "
22
+ f"Illegal characters: {illegal_chars}"
23
+ )
24
+
25
+
26
+ class AlgorithmFactory:
27
+ """
28
+ Factory class for creating an algorithm instance.
29
+ """
30
+
31
+ @staticmethod
32
+ def create_algorithm_name(algorithm):
33
+ """
34
+ Create a name for the algorithm based on its
35
+ strategies.
36
+
37
+ Args:
38
+ algorithm (Algorithm): Instance of Algorithm.
39
+
40
+ Returns:
41
+ str: Name of the algorithm.
42
+ """
43
+ first_strategy = algorithm.strategies[0] \
44
+ if algorithm.strategies else None
45
+
46
+ if first_strategy is not None:
47
+ return f"{first_strategy.__class__.__name__}"
48
+
49
+ return "DefaultAlgorithm"
50
+
51
+ @staticmethod
52
+ def create_algorithm(
53
+ name=None,
54
+ algorithm=None,
55
+ strategy=None,
56
+ strategies=None,
57
+ tasks=None,
58
+ on_strategy_run_hooks=None,
59
+ ) -> Algorithm:
60
+ """
61
+ Create an instance of the specified algorithm type.
62
+
63
+ Args:
64
+ name (str): Name of the algorithm.
65
+ algorithm (Algorithm): Instance of Algorithm to be used.
66
+ strategy (TradingStrategy): Single TradingStrategy instance.
67
+ strategies (list): List of TradingStrategy instances.
68
+ tasks (list): List of Task instances.
69
+ on_strategy_run_hooks (list): List of hooks to be called
70
+ when a strategy is run.
71
+
72
+ Returns:
73
+ Algorithm: Instance of Algorithm.
74
+ """
75
+ name = name
76
+ strategies = strategies or []
77
+ tasks = tasks or []
78
+ on_strategy_run_hooks = on_strategy_run_hooks or []
79
+ data_sources = []
80
+
81
+ if algorithm is not None and isinstance(algorithm, Algorithm):
82
+ if name is None:
83
+ name = algorithm.name
84
+
85
+ strategies.extend(algorithm.strategies)
86
+ tasks.extend(algorithm.tasks)
87
+ on_strategy_run_hooks.extend(algorithm.on_strategy_run_hooks)
88
+
89
+ if hasattr(algorithm, 'data_sources'):
90
+ data_sources.extend(algorithm.data_sources)
91
+
92
+ if strategy is not None:
93
+ strategies.append(strategy)
94
+ data_sources.extend(strategy.data_sources)
95
+
96
+ for strategy_entry in strategies:
97
+ if strategy_entry.data_sources is not None \
98
+ and len(strategy_entry.data_sources):
99
+ data_sources.extend(strategy_entry.data_sources)
100
+
101
+ algorithm = Algorithm(
102
+ name=name,
103
+ strategies=strategies,
104
+ tasks=tasks,
105
+ on_strategy_run_hooks=on_strategy_run_hooks,
106
+ data_sources=data_sources
107
+ )
108
+
109
+ if algorithm.name is None:
110
+ algorithm.name = AlgorithmFactory.create_algorithm_name(algorithm)
111
+
112
+ # Validate the algorithm name
113
+ validate_algorithm_name(algorithm.name)
114
+ return algorithm
@@ -0,0 +1,15 @@
1
+ from .backtest_data_ranges import select_backtest_date_ranges
2
+ from .ranking import rank_results, create_weights, combine_backtest_metrics
3
+ from .permutation import create_ohlcv_permutation
4
+ from .backtest_utils import load_backtests_from_directory, \
5
+ save_backtests_to_directory
6
+
7
+ __all__ = [
8
+ "select_backtest_date_ranges",
9
+ "rank_results",
10
+ "create_weights",
11
+ "create_ohlcv_permutation",
12
+ "combine_backtest_metrics",
13
+ "load_backtests_from_directory",
14
+ "save_backtests_to_directory"
15
+ ]