investing-algorithm-framework 3.2.0__tar.gz → 3.3.1__tar.gz

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 (141) hide show
  1. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/PKG-INFO +16 -16
  2. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/README.md +15 -15
  3. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/app.py +7 -0
  4. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/dependency_container.py +2 -0
  5. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/config.py +1 -0
  6. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/order.py +1 -5
  7. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/trade/trade.py +44 -9
  8. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/market_data_sources.py +21 -7
  9. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +36 -15
  10. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +46 -53
  11. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +26 -12
  12. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/backtesting/backtest_service.py +5 -2
  13. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +1 -0
  14. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -3
  15. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/order_service/order_service.py +2 -0
  16. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/trade_service/trade_service.py +13 -15
  17. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/pyproject.toml +1 -1
  18. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/LICENSE +0 -0
  19. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/__init__.py +0 -0
  20. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/__init__.py +0 -0
  21. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/algorithm.py +0 -0
  22. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  23. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  24. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  25. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  26. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  27. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  28. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/strategy.py +0 -0
  29. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/task.py +0 -0
  30. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/__init__.py +0 -0
  31. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  32. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  33. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  34. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  35. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/create_app.py +0 -0
  36. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  37. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/responses.py +0 -0
  38. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  39. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  40. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  41. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  42. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  43. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  44. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/create_app.py +0 -0
  45. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/__init__.py +0 -0
  46. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/constants.py +0 -0
  47. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/data_structures.py +0 -0
  48. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  49. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/exceptions.py +0 -0
  50. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/__init__.py +0 -0
  51. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
  52. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -0
  53. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -0
  54. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +0 -0
  55. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
  56. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  57. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
  58. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
  59. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
  60. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/order_fee.py +0 -0
  61. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  62. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
  63. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  64. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
  65. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
  66. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
  67. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  68. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  69. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  70. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  71. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  72. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
  73. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  74. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  75. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
  76. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
  77. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  78. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  79. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/__init__.py +0 -0
  80. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
  81. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/market_service.py +0 -0
  82. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
  83. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
  84. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/singleton.py +0 -0
  85. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  86. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/strategy.py +0 -0
  87. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
  88. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/backtesting.py +0 -0
  89. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  90. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/random.py +0 -0
  91. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  92. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  93. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  94. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
  95. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  96. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  97. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
  98. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  99. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  100. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  101. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
  102. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
  103. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -0
  104. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  105. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
  106. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  107. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  108. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  109. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  110. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
  111. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -0
  112. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  113. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
  114. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  115. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
  116. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  117. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
  118. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
  119. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
  120. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  121. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  122. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
  123. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/__init__.py +0 -0
  124. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
  125. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -0
  126. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/configuration_service.py +0 -0
  127. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/market_credential_service.py +0 -0
  128. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
  129. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -0
  130. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
  131. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
  132. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
  133. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
  134. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
  135. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
  136. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
  137. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/position_service.py +0 -0
  138. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  139. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/repository_service.py +0 -0
  140. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -0
  141. {investing_algorithm_framework-3.2.0 → investing_algorithm_framework-3.3.1}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing-algorithm-framework
3
- Version: 3.2.0
3
+ Version: 3.3.1
4
4
  Summary: A framework for creating trading bots
5
5
  Author: MDUYN
6
6
  Requires-Python: >=3.8.1,<4.0.0
@@ -174,20 +174,20 @@ you will get the following backtesting report:
174
174
  ====================Portfolio overview============================
175
175
  * Number of orders: 10
176
176
  * Initial balance: 400.0000 EUR
177
- * Final balance: 426.7818 EUR
178
- * Total net gain: 23.4238 EUR
179
- * Total net gain percentage: 5.8560%
180
- * Growth rate: 6.6955%
181
- * Growth 26.7818 EUR
177
+ * Final balance: 431.8837 EUR
178
+ * Total net gain: 28.4171 EUR
179
+ * Total net gain percentage: 7.1043%
180
+ * Growth rate: 7.9709%
181
+ * Growth 31.8837 EUR
182
182
  ====================Positions overview========================
183
183
  ╭────────────┬──────────┬──────────────────────┬───────────────────────┬──────────────┬───────────────┬───────────────────────────┬────────────────┬───────────────╮
184
184
  │ Position │ Amount │ Pending buy amount │ Pending sell amount │ Cost (EUR) │ Value (EUR) │ Percentage of portfolio │ Growth (EUR) │ Growth_rate │
185
185
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
186
- │ EUR │ 213.928 │ 0 │ 0 │ 213.928213.92850.1259% │ 0 │ 0.0000% │
186
+ │ EUR │ 214.219 │ 0 │ 0 │ 214.219214.21949.6010% │ 0 │ 0.0000% │
187
187
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
188
- │ BTC │ 0.003 │ 0 │ 0 │ 103.64 106.84 │ 25.0338% │ 3.1999 │ 3.0875% │
188
+ │ BTC │ 0.0031 │ 0 │ 0 │ 107.095 110.401 │ 25.5627% │ 3.3066 │ 3.0875% │
189
189
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
190
- │ DOT │ 21.0805 │ 0 │ 0 │ 105.856106.014 │ 24.8403% │ 0.1581 │ 0.1494% │
190
+ │ DOT │ 21.3291 │ 0 │ 0 │ 107.104107.264 │ 24.8363% │ 0.16 │ 0.1494% │
191
191
  ╰────────────┴──────────┴──────────────────────┴───────────────────────┴──────────────┴───────────────┴───────────────────────────┴────────────────┴───────────────╯
192
192
  ====================Trades overview===========================
193
193
  * Number of trades closed: 4
@@ -195,21 +195,21 @@ you will get the following backtesting report:
195
195
  * Percentage of positive trades: 60.0%
196
196
  * Percentage of negative trades: 20.0%
197
197
  * Average trade size: 98.8728 EUR
198
- * Average trade duration: 191.0 hours
198
+ * Average trade duration: 183.5 hours
199
199
  ╭─────────┬─────────────────────┬─────────────────────┬────────────────────┬──────────────┬──────────────────┬───────────────────────┬────────────────────┬─────────────────────╮
200
200
  │ Pair │ Open date │ Close date │ Duration (hours) │ Size (EUR) │ Net gain (EUR) │ Net gain percentage │ Open price (EUR) │ Close price (EUR) │
201
201
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
202
- │ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2802.99105.856 │ 0 │ 0.0000% │ 5.0215 │ │
202
+ │ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2976.65107.104 │ 0 │ 0.0000% │ 5.0215 │ │
203
203
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
204
- │ BTC-EUR │ 2023-11-29 14:00:00 │ │ 2832.99103.64 │ 0 │ 0.0000% │ 34546.6 │ │
204
+ │ BTC-EUR │ 2023-11-29 14:00:00 │ │ 3006.65107.095 │ 0 │ 0.0000% │ 34546.6 │ │
205
205
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
206
- │ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6
206
+ │ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6
207
207
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
208
- │ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4
208
+ │ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4
209
209
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
210
- │ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-15 06:00:00 │ 384 │ 100.551 │ 19.886119.7771% │ 4.0375 │ 4.836
210
+ │ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-14 00:00:00 │ 354 │ 100.551 │ 24.879424.7430% │ 4.0375 │ 5.0365
211
211
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
212
- │ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5
212
+ │ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5
213
213
  ╰─────────┴─────────────────────┴─────────────────────┴────────────────────┴──────────────┴──────────────────┴───────────────────────┴────────────────────┴─────────────────────╯
214
214
  ==================================================================
215
215
  ```
@@ -147,20 +147,20 @@ you will get the following backtesting report:
147
147
  ====================Portfolio overview============================
148
148
  * Number of orders: 10
149
149
  * Initial balance: 400.0000 EUR
150
- * Final balance: 426.7818 EUR
151
- * Total net gain: 23.4238 EUR
152
- * Total net gain percentage: 5.8560%
153
- * Growth rate: 6.6955%
154
- * Growth 26.7818 EUR
150
+ * Final balance: 431.8837 EUR
151
+ * Total net gain: 28.4171 EUR
152
+ * Total net gain percentage: 7.1043%
153
+ * Growth rate: 7.9709%
154
+ * Growth 31.8837 EUR
155
155
  ====================Positions overview========================
156
156
  ╭────────────┬──────────┬──────────────────────┬───────────────────────┬──────────────┬───────────────┬───────────────────────────┬────────────────┬───────────────╮
157
157
  │ Position │ Amount │ Pending buy amount │ Pending sell amount │ Cost (EUR) │ Value (EUR) │ Percentage of portfolio │ Growth (EUR) │ Growth_rate │
158
158
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
159
- │ EUR │ 213.928 │ 0 │ 0 │ 213.928213.92850.1259% │ 0 │ 0.0000% │
159
+ │ EUR │ 214.219 │ 0 │ 0 │ 214.219214.21949.6010% │ 0 │ 0.0000% │
160
160
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
161
- │ BTC │ 0.003 │ 0 │ 0 │ 103.64 106.84 │ 25.0338% │ 3.1999 │ 3.0875% │
161
+ │ BTC │ 0.0031 │ 0 │ 0 │ 107.095 110.401 │ 25.5627% │ 3.3066 │ 3.0875% │
162
162
  ├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
163
- │ DOT │ 21.0805 │ 0 │ 0 │ 105.856106.014 │ 24.8403% │ 0.1581 │ 0.1494% │
163
+ │ DOT │ 21.3291 │ 0 │ 0 │ 107.104107.264 │ 24.8363% │ 0.16 │ 0.1494% │
164
164
  ╰────────────┴──────────┴──────────────────────┴───────────────────────┴──────────────┴───────────────┴───────────────────────────┴────────────────┴───────────────╯
165
165
  ====================Trades overview===========================
166
166
  * Number of trades closed: 4
@@ -168,21 +168,21 @@ you will get the following backtesting report:
168
168
  * Percentage of positive trades: 60.0%
169
169
  * Percentage of negative trades: 20.0%
170
170
  * Average trade size: 98.8728 EUR
171
- * Average trade duration: 191.0 hours
171
+ * Average trade duration: 183.5 hours
172
172
  ╭─────────┬─────────────────────┬─────────────────────┬────────────────────┬──────────────┬──────────────────┬───────────────────────┬────────────────────┬─────────────────────╮
173
173
  │ Pair │ Open date │ Close date │ Duration (hours) │ Size (EUR) │ Net gain (EUR) │ Net gain percentage │ Open price (EUR) │ Close price (EUR) │
174
174
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
175
- │ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2802.99105.856 │ 0 │ 0.0000% │ 5.0215 │ │
175
+ │ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2976.65107.104 │ 0 │ 0.0000% │ 5.0215 │ │
176
176
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
177
- │ BTC-EUR │ 2023-11-29 14:00:00 │ │ 2832.99103.64 │ 0 │ 0.0000% │ 34546.6 │ │
177
+ │ BTC-EUR │ 2023-11-29 14:00:00 │ │ 3006.65107.095 │ 0 │ 0.0000% │ 34546.6 │ │
178
178
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
179
- │ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6
179
+ │ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6
180
180
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
181
- │ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4
181
+ │ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4
182
182
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
183
- │ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-15 06:00:00 │ 384 │ 100.551 │ 19.886119.7771% │ 4.0375 │ 4.836
183
+ │ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-14 00:00:00 │ 354 │ 100.551 │ 24.879424.7430% │ 4.0375 │ 5.0365
184
184
  ├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
185
- │ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5
185
+ │ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5
186
186
  ╰─────────┴─────────────────────┴─────────────────────┴────────────────────┴──────────────┴──────────────────┴───────────────────────┴────────────────────┴─────────────────────╯
187
187
  ==================================================================
188
188
  ```
@@ -278,7 +278,13 @@ class App:
278
278
  backtest_market_data_sources = [
279
279
  market_data_source.to_backtest_market_data_source()
280
280
  for market_data_source in market_data_sources
281
+ if market_data_source is not None
281
282
  ]
283
+
284
+ for market_data_source in backtest_market_data_sources:
285
+ if market_data_source is not None:
286
+ market_data_source.config = self.config
287
+
282
288
  self.container.market_data_source_service.override(
283
289
  BacktestMarketDataSourceService(
284
290
  market_data_sources=backtest_market_data_sources,
@@ -787,6 +793,7 @@ class App:
787
793
  return reports
788
794
 
789
795
  def add_market_data_source(self, market_data_source):
796
+ market_data_source.config = self.config
790
797
  self._market_data_source_service.add(market_data_source)
791
798
 
792
799
  def add_market_credential(self, market_credential: MarketCredential):
@@ -68,6 +68,7 @@ class DependencyContainer(containers.DeclarativeContainer):
68
68
  )
69
69
  order_service = providers.Factory(
70
70
  OrderService,
71
+ configuration_service=configuration_service,
71
72
  order_repository=order_repository,
72
73
  order_fee_repository=order_fee_repository,
73
74
  portfolio_repository=portfolio_repository,
@@ -125,6 +126,7 @@ class DependencyContainer(containers.DeclarativeContainer):
125
126
  )
126
127
  backtest_service = providers.Factory(
127
128
  BacktestService,
129
+ configuration_service=configuration_service,
128
130
  order_service=order_service,
129
131
  portfolio_repository=portfolio_repository,
130
132
  performance_service=performance_service,
@@ -77,6 +77,7 @@ class Config(dict):
77
77
  SQLITE_INITIALIZED = False
78
78
  BACKTEST_DATA_DIRECTORY_NAME = "backtest_data"
79
79
  SYMBOLS = None
80
+ DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
80
81
 
81
82
  def __init__(self, resource_directory=None):
82
83
  super().__init__()
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
 
3
3
  from dateutil.parser import parse
4
- from dateutil.tz import gettz
5
4
 
6
5
  from investing_algorithm_framework.domain.exceptions import \
7
6
  OperationalException
@@ -308,10 +307,7 @@ class Order(BaseModel):
308
307
  remaining=ccxt_order.get("remaining", None),
309
308
  cost=ccxt_order.get("cost", None),
310
309
  fee=OrderFee.from_ccxt_fee(ccxt_order.get("fee", None)),
311
- created_at=parse(
312
- ccxt_order.get("datetime", None),
313
- tzinfos={"UTC": gettz("UTC")}
314
- )
310
+ created_at=parse(ccxt_order.get("datetime", None))
315
311
  )
316
312
 
317
313
  def __repr__(self):
@@ -1,5 +1,11 @@
1
+ from typing import List
2
+ from polars import DataFrame
3
+ import polars as pl
1
4
  from datetime import datetime
2
5
  from investing_algorithm_framework.domain.models.base_model import BaseModel
6
+ from investing_algorithm_framework.domain.exceptions import \
7
+ OperationalException
8
+ from investing_algorithm_framework.domain.constants import DATETIME_FORMAT
3
9
 
4
10
 
5
11
  class Trade(BaseModel):
@@ -164,22 +170,51 @@ class Trade(BaseModel):
164
170
  return self.absolute_change
165
171
 
166
172
  def is_manual_stop_loss_trigger(
167
- self, current_price, prices, stop_loss_percentage
173
+ self,
174
+ current_price,
175
+ stop_loss_percentage,
176
+ prices: List[float] = None,
177
+ ohlcv_df: DataFrame = None
168
178
  ):
169
- # Stop loss is triggered when the current price is lower than the
170
- # calculated stop loss price. The stop loss price is calculated by
171
- # taking the highest price of the given range. If the highest price
172
- # is lower than the open price, the stop loss price is calculated by
173
- # taking the open price and subtracting the stop loss percentage.
174
- # If the highest price is higher than the open price, the stop loss
175
- # price is calculated by taking the open price and adding the stop
176
- # loss percentage.
179
+ """
180
+ Function to check if the stop loss is triggered for a given trade.
181
+
182
+ You can use either the prices list or the ohlcv_df DataFrame to
183
+ calculate the stop loss. The dataframe needs to be a Polars
184
+ DataFrame with the following columns: "Datetime" and "Close".
185
+
186
+ You can use the default CCXTOHLCVMarketDataSource to get the ohlcv_df
187
+ DataFrame.
188
+
189
+ Stop loss is triggered when the current price is lower than the
190
+ calculated stop loss price. The stop loss price is calculated by
191
+ taking the highest price of the given range. If the highest price
192
+ is lower than the open price, the stop loss price is calculated by
193
+ taking the open price and subtracting the stop loss percentage.
194
+ If the highest price is higher than the open price, the stop loss
195
+ price is calculated by taking the open price and adding the stop
196
+ loss percentage.
197
+ """
198
+
199
+ if prices is None and ohlcv_df is None:
200
+ raise OperationalException(
201
+ "Either prices or a polars ohlcv dataframe must be provided"
202
+ )
177
203
 
178
204
  if current_price < self.open_price:
179
205
  stop_loss_price = self.open_price * \
180
206
  (1 - stop_loss_percentage / 100)
181
207
  return current_price <= stop_loss_price
182
208
  else:
209
+ # If dataframes are provided, we use the dataframe to calculate
210
+ # the stop loss price
211
+ if ohlcv_df is not None:
212
+ filtered_df = ohlcv_df.filter(
213
+ pl.col('Datetime') >= self.opened_at.strftime(
214
+ DATETIME_FORMAT
215
+ )
216
+ )
217
+ prices = filtered_df['Close'].to_numpy()
183
218
  highest_price = max(prices)
184
219
  stop_loss_price = highest_price * (1 - stop_loss_percentage / 100)
185
220
  return current_price <= stop_loss_price
@@ -34,6 +34,14 @@ class BacktestMarketDataSource(ABC):
34
34
  self._backtest_data_start_date = backtest_data_start_date
35
35
  self._backtest_data_index_date = backtest_data_index_date
36
36
 
37
+ @property
38
+ def config(self):
39
+ return self._config
40
+
41
+ @config.setter
42
+ def config(self, value):
43
+ self._config = value
44
+
37
45
  def _data_source_exists(self, file_path):
38
46
  """
39
47
  Function to check if the data source exists.
@@ -60,9 +68,7 @@ class BacktestMarketDataSource(ABC):
60
68
  return False
61
69
 
62
70
  return True
63
- except Exception as e:
64
- logger.error(f"Error reading {file_path}")
65
- logger.error(e)
71
+ except Exception:
66
72
  return False
67
73
 
68
74
  def write_data_to_file_path(self, data_file, data):
@@ -151,10 +157,10 @@ class BacktestMarketDataSource(ABC):
151
157
  class MarketDataSource(ABC):
152
158
 
153
159
  def __init__(
154
- self,
155
- identifier,
156
- market,
157
- symbol,
160
+ self,
161
+ identifier,
162
+ market,
163
+ symbol,
158
164
  ):
159
165
  self._identifier = identifier
160
166
  self._market = market
@@ -168,6 +174,14 @@ class MarketDataSource(ABC):
168
174
  def identifier(self):
169
175
  return self._identifier
170
176
 
177
+ @property
178
+ def config(self):
179
+ return self._config
180
+
181
+ @config.setter
182
+ def config(self, value):
183
+ self._config = value
184
+
171
185
  def get_identifier(self):
172
186
  return self.identifier
173
187
 
@@ -3,6 +3,7 @@ import os
3
3
  from datetime import timedelta
4
4
 
5
5
  import polars
6
+ from dateutil import parser
6
7
 
7
8
  from investing_algorithm_framework.domain import RESOURCE_DIRECTORY, \
8
9
  BACKTEST_DATA_DIRECTORY_NAME, DATETIME_FORMAT_BACKTESTING, \
@@ -59,7 +60,7 @@ class CCXTOHLCVBacktestMarketDataSource(
59
60
  start_date_func=start_date_func,
60
61
  end_date=end_date,
61
62
  end_date_func=end_date_func,
62
- window_size=window_size
63
+ window_size=window_size,
63
64
  )
64
65
 
65
66
  def prepare_data(
@@ -80,7 +81,6 @@ class CCXTOHLCVBacktestMarketDataSource(
80
81
  When downloading the data it will use the ccxt library.
81
82
  """
82
83
  # Calculating the backtest data start date
83
-
84
84
  difference = self.end_date - self.start_date
85
85
  total_minutes = 0
86
86
 
@@ -127,7 +127,10 @@ class CCXTOHLCVBacktestMarketDataSource(
127
127
  )
128
128
 
129
129
  # Get the OHLCV data from the ccxt market service
130
- market_service = CCXTMarketService(self.market_credential_service)
130
+ market_service = CCXTMarketService(
131
+ market_credential_service=self.market_credential_service,
132
+ )
133
+ market_service.config = config
131
134
  ohlcv = market_service.get_ohlcv(
132
135
  symbol=self.symbol,
133
136
  time_frame=self.timeframe,
@@ -171,6 +174,7 @@ class CCXTOHLCVBacktestMarketDataSource(
171
174
  from_timestamp = backtest_index_date - timedelta(
172
175
  minutes=self.total_minutes_timeframe
173
176
  )
177
+ datetime_format = self._config["DATETIME_FORMAT"]
174
178
  self.backtest_data_index_date = backtest_index_date\
175
179
  .replace(microsecond=0)
176
180
  from_timestamp = from_timestamp.replace(microsecond=0)
@@ -193,8 +197,8 @@ class CCXTOHLCVBacktestMarketDataSource(
193
197
  file_path, columns=self.column_names, separator=","
194
198
  )
195
199
  df = df.filter(
196
- (df['Datetime'] >= from_timestamp.strftime(DATETIME_FORMAT))
197
- & (df['Datetime'] <= to_timestamp.strftime(DATETIME_FORMAT))
200
+ (df['Datetime'] >= from_timestamp.strftime(datetime_format))
201
+ & (df['Datetime'] <= to_timestamp.strftime(datetime_format))
198
202
  )
199
203
  return df
200
204
 
@@ -209,6 +213,9 @@ class CCXTOHLCVBacktestMarketDataSource(
209
213
  def file_name(self):
210
214
  return self._create_file_path().split("/")[-1]
211
215
 
216
+ def write_data_to_file_path(self, data_file, data: polars.DataFrame):
217
+ data.write_csv(data_file)
218
+
212
219
 
213
220
  class CCXTTickerBacktestMarketDataSource(
214
221
  TickerMarketDataSource, BacktestMarketDataSource
@@ -304,7 +311,10 @@ class CCXTTickerBacktestMarketDataSource(
304
311
  )
305
312
 
306
313
  # Get the OHLCV data from the ccxt market service
307
- market_service = CCXTMarketService(self.market_credential_service)
314
+ market_service = CCXTMarketService(
315
+ market_credential_service=self.market_credential_service
316
+ )
317
+ market_service.config = config
308
318
  ohlcv = market_service.get_ohlcv(
309
319
  symbol=self.symbol,
310
320
  time_frame=self.timeframe,
@@ -363,13 +373,12 @@ class CCXTTickerBacktestMarketDataSource(
363
373
  # Filter the data based on the backtest index date and the end date
364
374
  df = polars.read_csv(file_path)
365
375
  df = df.filter(
366
- (df['Datetime'] >= backtest_index_date
367
- .strftime(DATETIME_FORMAT))
376
+ (df['Datetime'] >= backtest_index_date.strftime(DATETIME_FORMAT))
368
377
  )
369
-
370
378
  first_row = df.head(1)[0]
379
+ first_row_datetime = parser.parse(first_row["Datetime"][0])
371
380
 
372
- if first_row["Datetime"][0] > end_date.strftime(DATETIME_FORMAT):
381
+ if first_row_datetime > end_date:
373
382
  logger.warning(
374
383
  f"No ticker data available for the given backtest "
375
384
  f"index date {backtest_index_date} and symbol {self.symbol} "
@@ -386,12 +395,17 @@ class CCXTTickerBacktestMarketDataSource(
386
395
  "datetime": first_row["Datetime"][0],
387
396
  }
388
397
 
398
+ def write_data_to_file_path(self, data_file, data: polars.DataFrame):
399
+ data.write_csv(data_file)
400
+
389
401
 
390
402
  class CCXTOHLCVMarketDataSource(OHLCVMarketDataSource):
391
403
 
392
404
  def get_data(self, **kwargs):
393
- market_service = CCXTMarketService(self.market_credential_service)
394
-
405
+ market_service = CCXTMarketService(
406
+ market_credential_service=self.market_credential_service,
407
+ )
408
+ market_service.config = self.config
395
409
  if self.start_date is None:
396
410
  raise OperationalException(
397
411
  "Either start_date or start_date_func should be set "
@@ -422,7 +436,10 @@ class CCXTOHLCVMarketDataSource(OHLCVMarketDataSource):
422
436
  class CCXTOrderBookMarketDataSource(OrderBookMarketDataSource):
423
437
 
424
438
  def get_data(self, **kwargs):
425
- market_service = CCXTMarketService(self.market_credential_service)
439
+ market_service = CCXTMarketService(
440
+ market_credential_service=self.market_credential_service
441
+ )
442
+ market_service.config = self.config
426
443
  return market_service.get_order_book(
427
444
  symbol=self.symbol, market=self.market
428
445
  )
@@ -438,7 +455,8 @@ class CCXTTickerMarketDataSource(TickerMarketDataSource):
438
455
  identifier,
439
456
  market,
440
457
  symbol=None,
441
- backtest_timeframe=None
458
+ backtest_timeframe=None,
459
+
442
460
  ):
443
461
  super().__init__(
444
462
  identifier=identifier,
@@ -448,7 +466,10 @@ class CCXTTickerMarketDataSource(TickerMarketDataSource):
448
466
  self._backtest_timeframe = backtest_timeframe
449
467
 
450
468
  def get_data(self, **kwargs):
451
- market_service = CCXTMarketService(self.market_credential_service)
469
+ market_service = CCXTMarketService(
470
+ market_credential_service=self.market_credential_service
471
+ )
472
+ market_service.config = self.config
452
473
 
453
474
  if self.market is None:
454
475
 
@@ -1,10 +1,14 @@
1
1
  from datetime import datetime
2
+ import polars
3
+ import logging
2
4
 
3
- import pandas as pd
4
5
  from dateutil.parser import parse
5
6
 
6
7
  from investing_algorithm_framework.domain import OHLCVMarketDataSource, \
7
- BacktestMarketDataSource, OperationalException, TickerMarketDataSource
8
+ BacktestMarketDataSource, OperationalException, TickerMarketDataSource, \
9
+ DATETIME_FORMAT
10
+
11
+ logger = logging.getLogger(__name__)
8
12
 
9
13
 
10
14
  class CSVOHLCVMarketDataSource(OHLCVMarketDataSource):
@@ -44,8 +48,9 @@ class CSVOHLCVMarketDataSource(OHLCVMarketDataSource):
44
48
  self._columns = [
45
49
  "Datetime", "Open", "High", "Low", "Close", "Volume"
46
50
  ]
47
- df = pd.read_csv(self._csv_file_path)
51
+ df = polars.read_csv(csv_file_path)
48
52
 
53
+ # Check if all column names are in the csv file
49
54
  if not all(column in df.columns for column in self._columns):
50
55
  # Identify missing columns
51
56
  missing_columns = [column for column in self._columns if
@@ -56,10 +61,10 @@ class CSVOHLCVMarketDataSource(OHLCVMarketDataSource):
56
61
  f"Missing columns: {missing_columns}"
57
62
  )
58
63
 
59
- first_row = df.iloc[0]
60
- last_row = df.iloc[-1]
61
- self._start_date = parse(first_row[0])
62
- self._end_date = parse(last_row[0])
64
+ first_row = df.head(1)
65
+ last_row = df.tail(1)
66
+ self._start_date = parse(first_row["Datetime"][0])
67
+ self._end_date = parse(last_row["Datetime"][0])
63
68
 
64
69
  @property
65
70
  def csv_file_path(self):
@@ -67,40 +72,25 @@ class CSVOHLCVMarketDataSource(OHLCVMarketDataSource):
67
72
 
68
73
  def get_data(
69
74
  self,
70
- from_time_stamp=None,
71
- to_time_stamp=None,
75
+ from_timestamp=None,
76
+ to_timestamp=None,
72
77
  **kwargs
73
78
  ):
74
79
 
75
- if from_time_stamp is None:
76
- from_time_stamp = self.start_date
77
-
78
- if to_time_stamp is None:
79
- to_time_stamp = self.end_date
80
-
81
- df = pd.read_csv(self._csv_file_path)
82
-
83
- # Convert the 'Datetime' column to datetime type if
84
- # it's not already
85
- if 'Datetime' in df.columns and pd.api.types.is_string_dtype(
86
- df['Datetime']):
87
- df['Datetime'] = pd.to_datetime(df['Datetime'], utc=True)
88
-
89
- # Filter rows based on the start and end dates
90
- filtered_df = df[
91
- (df['Datetime'] >= from_time_stamp)
92
- & (df['Datetime'] <= to_time_stamp)
93
- ]
94
-
95
- # Specify the columns you want in the inner lists
96
- selected_columns = ["Datetime", "Open", "High", "Low", "Close",
97
- "Volume"]
80
+ if from_timestamp is None:
81
+ from_timestamp = self.start_date
98
82
 
99
- # Convert DataFrame to a list of lists with selected columns
100
- filtered_list_of_lists = \
101
- self.dataframe_to_list_of_lists(filtered_df, selected_columns)
83
+ if to_timestamp is None:
84
+ to_timestamp = self.end_date
102
85
 
103
- return filtered_list_of_lists
86
+ df = polars.read_csv(
87
+ self.csv_file_path, columns=self._columns, separator=","
88
+ )
89
+ df = df.filter(
90
+ (df['Datetime'] >= from_timestamp.strftime(DATETIME_FORMAT))
91
+ & (df['Datetime'] <= to_timestamp.strftime(DATETIME_FORMAT))
92
+ )
93
+ return df
104
94
 
105
95
  def dataframe_to_list_of_lists(self, dataframe, columns):
106
96
  # Extract selected columns from DataFrame and convert
@@ -130,7 +120,7 @@ class CSVTickerMarketDataSource(TickerMarketDataSource):
130
120
  self._columns = [
131
121
  "Datetime", "Open", "High", "Low", "Close", "Volume"
132
122
  ]
133
- df = pd.read_csv(self._csv_file_path)
123
+ df = polars.read_csv(self._csv_file_path)
134
124
 
135
125
  if not all(column in df.columns for column in self._columns):
136
126
  # Identify missing columns
@@ -151,27 +141,30 @@ class CSVTickerMarketDataSource(TickerMarketDataSource):
151
141
  if index_datetime is None:
152
142
  index_datetime = datetime.utcnow()
153
143
 
154
- index_datetime = pd.to_datetime(index_datetime, utc=True)
155
- df = pd.read_csv(self._csv_file_path)
156
-
157
- # Convert the 'Datetime' column to datetime type if
158
- # it's not already
159
- if 'Datetime' in df.columns and pd.api.types.is_string_dtype(
160
- df['Datetime']):
161
- df['Datetime'] = pd.to_datetime(df['Datetime'], utc=True)
144
+ # Filter the data based on the backtest index date and the end date
145
+ df = polars.read_csv(self._csv_file_path)
146
+ df = df.filter(
147
+ (df['Datetime'] >= index_datetime
148
+ .strftime(DATETIME_FORMAT))
149
+ )
162
150
 
163
- # Filter rows based on the start and end dates
164
- filtered_df = df[(df['Datetime'] <= index_datetime)]
151
+ # Check if the dataframe is empty
152
+ if df.shape[0] == 0:
153
+ raise OperationalException(
154
+ f"No ticker data found for {self.symbol} "
155
+ f"at {index_datetime}"
156
+ )
165
157
 
166
- if len(filtered_df) == 0:
167
- return None
158
+ first_row = df.head(1)[0]
168
159
 
169
- last_row = filtered_df.iloc[-1]
160
+ # Calculate the bid and ask price based on the high and low price
170
161
  return {
171
162
  "symbol": self.symbol,
172
- "bid": (float(last_row[3]) + float(last_row[2])) / 2,
173
- "ask": (float(last_row[3]) + float(last_row[2])) / 2,
174
- "datetime": last_row[0],
163
+ "bid": float((first_row["Low"][0])
164
+ + float(first_row["High"][0])) / 2,
165
+ "ask": float((first_row["Low"][0])
166
+ + float(first_row["High"][0])) / 2,
167
+ "datetime": first_row["Datetime"][0],
175
168
  }
176
169
 
177
170
  def dataframe_to_list_of_lists(self, dataframe, columns):