investing-algorithm-framework 4.0.1__tar.gz → 4.1.0__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 (165) hide show
  1. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/PKG-INFO +1 -1
  2. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/__init__.py +4 -2
  3. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/algorithm.py +12 -11
  4. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/app.py +19 -21
  5. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/dependency_container.py +2 -1
  6. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +4 -10
  7. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +31 -0
  8. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +22 -3
  9. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +1 -1
  10. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +1 -0
  11. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +4 -0
  12. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/backtesting/backtest_service.py +66 -19
  13. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +20 -20
  14. investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +46 -0
  15. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +9 -6
  16. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/portfolios/portfolio_service.py +6 -1
  17. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/pyproject.toml +1 -1
  18. investing_algorithm_framework-4.0.1/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -21
  19. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/LICENSE +0 -0
  20. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/README.md +0 -0
  21. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/__init__.py +0 -0
  22. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  23. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  24. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  25. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  26. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  27. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  28. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/strategy.py +0 -0
  29. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/task.py +0 -0
  30. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
  31. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  32. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  33. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  34. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  35. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
  36. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  37. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/responses.py +0 -0
  38. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  39. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  40. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  41. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  42. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  43. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  44. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/__init__.py +0 -0
  45. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/create_azure_function_app_skeleton.py +0 -0
  46. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/deploy_to_azure_function.py +0 -0
  47. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/templates/azure_function_framework_app.py.template +0 -0
  48. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +0 -0
  49. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/templates/azure_function_host.json.template +0 -0
  50. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +0 -0
  51. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +0 -0
  52. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/create_app.py +0 -0
  53. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/__init__.py +0 -0
  54. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/config.py +0 -0
  55. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/constants.py +0 -0
  56. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/data_structures.py +0 -0
  57. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  58. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
  59. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/metrics/__init__.py +0 -0
  60. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/metrics/price_efficiency.py +0 -0
  61. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/__init__.py +0 -0
  62. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
  63. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -0
  64. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -0
  65. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -0
  66. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
  67. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  68. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/date_range.py +0 -0
  69. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
  70. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
  71. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
  72. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/order/order.py +0 -0
  73. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  74. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
  75. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  76. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
  77. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  78. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  79. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  80. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  81. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  82. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
  83. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  84. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  85. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
  86. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
  87. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
  88. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/trade/trade.py +0 -0
  89. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
  90. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  91. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  92. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/__init__.py +0 -0
  93. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
  94. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/market_data_sources.py +0 -0
  95. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/market_service.py +0 -0
  96. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
  97. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
  98. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
  99. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/singleton.py +0 -0
  100. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  101. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/strategy.py +0 -0
  102. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
  103. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/backtesting.py +0 -0
  104. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  105. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/polars.py +0 -0
  106. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
  107. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  108. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  109. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  110. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/indicators/__init__.py +0 -0
  111. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/indicators/advanced.py +0 -0
  112. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/indicators/momentum.py +0 -0
  113. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/indicators/trend.py +0 -0
  114. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/indicators/utils.py +0 -0
  115. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
  116. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  117. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  118. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
  119. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  120. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  121. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -0
  122. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -0
  123. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +0 -0
  124. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -0
  125. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  126. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
  127. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
  128. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  129. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  130. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/sql_portfolio.py +0 -0
  131. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  132. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  133. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  134. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
  135. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  136. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  137. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
  138. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  139. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
  140. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/azure/__init__.py +0 -0
  141. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/azure/state_handler.py +0 -0
  142. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
  143. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -0
  144. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  145. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  146. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/__init__.py +0 -0
  147. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
  148. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -0
  149. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/backtesting/graphs.py +0 -0
  150. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/configuration_service.py +0 -0
  151. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/market_credential_service.py +0 -0
  152. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
  153. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -0
  154. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
  155. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -0
  156. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/order_service/order_service.py +0 -0
  157. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
  158. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
  159. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
  160. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/position_service.py +0 -0
  161. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  162. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/repository_service.py +0 -0
  163. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -0
  164. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
  165. {investing_algorithm_framework-4.0.1 → investing_algorithm_framework-4.1.0}/investing_algorithm_framework/services/trade_service/trade_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing-algorithm-framework
3
- Version: 4.0.1
3
+ Version: 4.1.0
4
4
  Summary: A framework for creating trading bots
5
5
  Author: MDUYN
6
6
  Requires-Python: >=3.10
@@ -11,7 +11,8 @@ from investing_algorithm_framework.domain import ApiException, \
11
11
  pretty_print_backtest_reports_evaluation, load_backtest_reports, \
12
12
  RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
13
13
  load_backtest_report, BacktestDateRange, convert_polars_to_pandas, \
14
- DateRange, get_backtest_report, DEFAULT_LOGGING_CONFIG
14
+ DateRange, get_backtest_report, DEFAULT_LOGGING_CONFIG, \
15
+ BacktestReport
15
16
  from investing_algorithm_framework.infrastructure import \
16
17
  CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
17
18
  CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
@@ -88,5 +89,6 @@ __all__ = [
88
89
  "is_divergence",
89
90
  "get_backtest_report",
90
91
  "AzureBlobStorageStateHandler",
91
- "DEFAULT_LOGGING_CONFIG"
92
+ "DEFAULT_LOGGING_CONFIG",
93
+ "BacktestReport"
92
94
  ]
@@ -163,15 +163,6 @@ class Algorithm:
163
163
  def data_sources(self):
164
164
  return self._data_sources
165
165
 
166
- @property
167
- def identifier(self):
168
- """
169
- Function to get a config instance. This allows users when
170
- having access to the algorithm instance also to read the
171
- configs of the app.
172
- """
173
- return self.configuration_service.config
174
-
175
166
  @property
176
167
  def config(self):
177
168
  """
@@ -179,7 +170,7 @@ class Algorithm:
179
170
  having access to the algorithm instance also to read the
180
171
  configs of the app.
181
172
  """
182
- return self.configuration_service.config
173
+ return self.configuration_service.get_config()
183
174
 
184
175
  @property
185
176
  def description(self):
@@ -489,6 +480,16 @@ class Algorithm:
489
480
 
490
481
  return self.portfolio_service.find({{"market": market}})
491
482
 
483
+ def get_portfolios(self):
484
+ """
485
+ Function to get all portfolios of the algorithm. This function
486
+ will return all portfolios of the algorithm.
487
+
488
+ Returns:
489
+ List[Portfolio]: A list of all portfolios of the algorithm
490
+ """
491
+ return self.portfolio_service.get_all()
492
+
492
493
  def get_unallocated(self, market=None) -> float:
493
494
  """
494
495
  Function to get the unallocated balance of the portfolio. This
@@ -834,7 +835,7 @@ class Algorithm:
834
835
  return (position.amount * ticker["bid"] / total) * 100
835
836
 
836
837
  def get_position_percentage_of_portfolio_by_net_size(
837
- self, symbol, market=None, identifier=None
838
+ self, symbol, market=None, identifier=None
838
839
  ) -> float:
839
840
  """
840
841
  Returns the percentage of the portfolio that is allocated to a
@@ -518,17 +518,6 @@ class App:
518
518
  trade_service=self.container.trade_service(),
519
519
  )
520
520
 
521
- # Create all portfolios
522
- portfolio_configuration_service = self.container \
523
- .portfolio_configuration_service()
524
- portfolio_configurations = portfolio_configuration_service.get_all()
525
- portfolio_service = self.container.portfolio_service()
526
-
527
- for portfolio_configuration in portfolio_configurations:
528
- portfolio_service.create_portfolio_from_configuration(
529
- portfolio_configuration
530
- )
531
-
532
521
  def run(
533
522
  self,
534
523
  payload: dict = None,
@@ -774,20 +763,24 @@ class App:
774
763
 
775
764
  def run_backtest(
776
765
  self,
777
- algorithm,
778
766
  backtest_date_range: BacktestDateRange,
767
+ initial_amount=None,
779
768
  pending_order_check_interval=None,
780
- output_directory=None
769
+ output_directory=None,
770
+ algorithm: Algorithm = None
781
771
  ) -> BacktestReport:
782
772
  """
783
773
  Run a backtest for an algorithm. This method should be called when
784
774
  running a backtest.
785
775
 
786
776
  Parameters:
787
- algorithm: The algorithm to run a backtest for (instance of
788
- Algorithm)
789
777
  backtest_date_range: The date range to run the backtest for
790
778
  (instance of BacktestDateRange)
779
+ initial_amount: The initial amount to start the backtest with.
780
+ This will be the amount of trading currency that the backtest
781
+ portfolio will start with.
782
+ algorithm: The algorithm to run a backtest for (instance of
783
+ Algorithm)
791
784
  pending_order_check_interval: str - pending_order_check_interval:
792
785
  The interval at which to check pending orders (e.g. 1h, 1d, 1w)
793
786
  output_directory: str - The directory to
@@ -796,8 +789,11 @@ class App:
796
789
  Returns:
797
790
  Instance of BacktestReport
798
791
  """
799
- logger.info("Initializing backtest")
800
- self.algorithm = algorithm
792
+ if algorithm is not None:
793
+ self.algorithm = algorithm
794
+
795
+ if self.algorithm is None:
796
+ raise OperationalException("No algorithm registered")
801
797
 
802
798
  self._initialize_app_for_backtest(
803
799
  backtest_date_range=backtest_date_range,
@@ -807,18 +803,20 @@ class App:
807
803
  self._initialize_algorithm_for_backtest(
808
804
  algorithm=self.algorithm
809
805
  )
806
+
810
807
  backtest_service = self.container.backtest_service()
811
- configuration_service = self.container.configuration_service()
812
- config = configuration_service.get_config()
813
- backtest_service.resource_directory = config[RESOURCE_DIRECTORY]
814
808
 
815
809
  # Run the backtest with the backtest_service and collect the report
816
810
  report = backtest_service.run_backtest(
817
- algorithm=self.algorithm, backtest_date_range=backtest_date_range
811
+ algorithm=self.algorithm,
812
+ initial_amount=initial_amount,
813
+ backtest_date_range=backtest_date_range
818
814
  )
819
815
  backtest_report_writer_service = self.container \
820
816
  .backtest_report_writer_service()
821
817
 
818
+ config = self.container.configuration_service().get_config()
819
+
822
820
  if output_directory is None:
823
821
  output_directory = os.path.join(
824
822
  config[RESOURCE_DIRECTORY], "backtest_reports"
@@ -126,10 +126,11 @@ class DependencyContainer(containers.DeclarativeContainer):
126
126
  BacktestService,
127
127
  configuration_service=configuration_service,
128
128
  order_service=order_service,
129
- portfolio_repository=portfolio_repository,
129
+ portfolio_service=portfolio_service,
130
130
  performance_service=performance_service,
131
131
  position_repository=position_repository,
132
132
  market_data_source_service=market_data_source_service,
133
+ portfolio_configuration_service=portfolio_configuration_service,
133
134
  )
134
135
  backtest_report_writer_service = providers.Factory(
135
136
  BacktestReportWriterService,
@@ -9,7 +9,6 @@ from investing_algorithm_framework.domain.metrics import \
9
9
  from investing_algorithm_framework.domain.models \
10
10
  .backtesting.backtest_date_range import BacktestDateRange
11
11
  from investing_algorithm_framework.domain.models.base_model import BaseModel
12
- from investing_algorithm_framework.domain.models.time_unit import TimeUnit
13
12
  from investing_algorithm_framework.domain.models.position import Position
14
13
  from investing_algorithm_framework.domain.models.trade import Trade
15
14
  from investing_algorithm_framework.domain.models.order import Order
@@ -358,15 +357,7 @@ class BacktestReport(BaseModel):
358
357
  self._time_unit = value
359
358
 
360
359
  def get_runs_per_day(self):
361
-
362
- if self.time_unit is None:
363
- return 0
364
- elif TimeUnit.SECOND.equals(self.time_unit):
365
- return 86400 / self.interval
366
- elif TimeUnit.MINUTE.equals(self.time_unit):
367
- return 1440 / self.interval
368
- else:
369
- return 24 / self.interval
360
+ return self.number_of_runs / self.number_of_days
370
361
 
371
362
  @property
372
363
  def backtest_start_date(self):
@@ -525,6 +516,9 @@ class BacktestReport(BaseModel):
525
516
  def get_trading_symbol(self) -> str:
526
517
  return self.trading_symbol
527
518
 
519
+ def get_initial_unallocated(self) -> float:
520
+ return self.initial_unallocated
521
+
528
522
  def add_symbol(self, symbol):
529
523
 
530
524
  if symbol not in self.symbols:
@@ -2,6 +2,37 @@ from investing_algorithm_framework.domain.models.base_model import BaseModel
2
2
 
3
3
 
4
4
  class Portfolio(BaseModel):
5
+ """
6
+ Portfolio base class.
7
+
8
+ A portfolio is a collection of positions that are managed by an algorithm.
9
+
10
+ Attributes:
11
+ * identifier: str, unique identifier of the portfolio
12
+ * trading_symbol: str, trading symbol of the portfolio
13
+ * unallocated: float, the size of the trading symbol that is not
14
+ allocated. For example, if the trading symbol is USDT and the unallocated
15
+ is 1000, it means that the portfolio has 1000 USDT that is not
16
+ allocated to any position.
17
+ * net_size: float, net size of the portfolio is the initial balance of the
18
+ portfolio plus the all the net gains of the trades. The
19
+ * realized: float, the realized gain of the portfolio is the sum of all the
20
+ realized gains of the trades.
21
+ * total_revenue: float, the total revenue of the portfolio is the sum
22
+ of all the orders (price * size)
23
+ * total_cost: float, the total cost of the portfolio is the sum of all the
24
+ costs of the trades (price * size (for buy orders)
25
+ or -price * size (for sell orders))
26
+ * total_net_gain: float, the total net gain of the portfolio is the sum of
27
+ all the net gains of the trades
28
+ * total_trade_volume: float, the total trade volume of the
29
+ portfolio is the sum of all the sizes of the trades
30
+ * market: str, the market of the portfolio (e.g. BITVAVO, BINANCE)
31
+ * created_at: datetime, the datetime when the portfolio was created
32
+ * updated_at: datetime, the datetime when the portfolio was last updated
33
+ * initialized: bool, whether the portfolio is initialized or not
34
+ * initial_balance: float, the initial balance of the portfolio
35
+ """
5
36
 
6
37
  def __init__(
7
38
  self,
@@ -6,6 +6,23 @@ from investing_algorithm_framework.domain.models.base_model import BaseModel
6
6
 
7
7
 
8
8
  class PortfolioConfiguration(BaseModel):
9
+ """
10
+ This class represents a portfolio configuration. It is used to
11
+ configure the portfolio that the user wants to create.
12
+
13
+ The portfolio configuration will have the following attributes:
14
+ - market: The market where the portfolio will be created
15
+ - trading_symbol: The trading symbol of the portfolio
16
+ - track_from: The date from which the portfolio will be tracked
17
+ - identifier: The identifier of the portfolio
18
+ - initial_balance: The initial balance of the portfolio
19
+
20
+ For backtesting, a portfolio configuration is used to create a
21
+ portfolio that will be used to simulate the trading of the algorithm. if
22
+ the user does not provide an initial balance, the portfolio will be created
23
+ with a balance of according to the initial balanace of
24
+ the PortfolioConfiguration class.
25
+ """
9
26
 
10
27
  def __init__(
11
28
  self,
@@ -22,7 +39,9 @@ class PortfolioConfiguration(BaseModel):
22
39
  self._initial_balance = initial_balance
23
40
 
24
41
  if self.identifier is None:
25
- self._identifier = market.lower()
42
+ self._identifier = market.upper()
43
+ else:
44
+ self._identifier = identifier.upper()
26
45
 
27
46
  if track_from:
28
47
  self._track_from = parse(track_from)
@@ -35,8 +54,8 @@ class PortfolioConfiguration(BaseModel):
35
54
  @property
36
55
  def market(self):
37
56
 
38
- if hasattr(self._market, "lower"):
39
- return self._market.lower()
57
+ if hasattr(self._market, "upper"):
58
+ return self._market.upper()
40
59
 
41
60
  return self._market
42
61
 
@@ -20,7 +20,7 @@ class SQLPortfolioRepository(Repository):
20
20
  query = query.filter_by(market=market_query_param.upper())
21
21
 
22
22
  if identifier_query_param:
23
- query = query.filter_by(identifier=identifier_query_param.lower())
23
+ query = query.filter_by(identifier=identifier_query_param.upper())
24
24
 
25
25
  if position_query_param:
26
26
  position = db.query(SQLPosition)\
@@ -71,6 +71,7 @@ class Repository(ABC):
71
71
  try:
72
72
  delete_object = self.get(object_id)
73
73
  db.delete(delete_object)
74
+ db.commit()
74
75
  return delete_object
75
76
  except SQLAlchemyError as e:
76
77
  logger.error(e)
@@ -193,6 +193,10 @@ class PerformanceService:
193
193
  return: The total net gain percentage of the backtest
194
194
  """
195
195
  portfolio = self.portfolio_repository.find({"id": portfolio_id})
196
+
197
+ if portfolio.total_net_gain == 0:
198
+ return 0
199
+
196
200
  return portfolio.total_net_gain \
197
201
  / backtest_profile.initial_unallocated * 100
198
202
 
@@ -1,11 +1,11 @@
1
1
  from datetime import datetime, timedelta
2
-
3
2
  import re
4
3
  import os
5
4
  import json
6
5
  import pandas as pd
7
6
  from dateutil import parser
8
7
  from tqdm import tqdm
8
+ import logging
9
9
 
10
10
  from investing_algorithm_framework.domain import BacktestReport, \
11
11
  BACKTESTING_INDEX_DATETIME, TimeUnit, BacktestPosition, \
@@ -15,6 +15,7 @@ from investing_algorithm_framework.services.market_data_source_service import \
15
15
  MarketDataSourceService
16
16
 
17
17
 
18
+ logger = logging.getLogger(__name__)
18
19
  BACKTEST_REPORT_FILE_NAME_PATTERN = (
19
20
  r"^report_\w+_backtest-start-date_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}_"
20
21
  r"backtest-end-date_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}_"
@@ -28,17 +29,18 @@ class BacktestService:
28
29
  """
29
30
 
30
31
  def __init__(
31
- self,
32
- market_data_source_service: MarketDataSourceService,
33
- order_service,
34
- portfolio_repository,
35
- position_repository,
36
- performance_service,
37
- configuration_service
32
+ self,
33
+ market_data_source_service: MarketDataSourceService,
34
+ order_service,
35
+ portfolio_service,
36
+ position_repository,
37
+ performance_service,
38
+ configuration_service,
39
+ portfolio_configuration_service
38
40
  ):
39
41
  self._resource_directory = None
40
42
  self._order_service = order_service
41
- self._portfolio_repository = portfolio_repository
43
+ self._portfolio_service = portfolio_service
42
44
  self._data_index = {
43
45
  TradingDataType.OHLCV: {},
44
46
  TradingDataType.TICKER: {}
@@ -49,6 +51,7 @@ class BacktestService:
49
51
  = market_data_source_service
50
52
  self._backtest_market_data_sources = []
51
53
  self._configuration_service = configuration_service
54
+ self._portfolio_configuration_service = portfolio_configuration_service
52
55
 
53
56
  @property
54
57
  def resource_directory(self):
@@ -59,7 +62,10 @@ class BacktestService:
59
62
  self._resource_directory = resource_directory
60
63
 
61
64
  def run_backtest(
62
- self, algorithm, backtest_date_range: BacktestDateRange
65
+ self,
66
+ algorithm,
67
+ backtest_date_range: BacktestDateRange,
68
+ initial_amount=None
63
69
  ) -> BacktestReport:
64
70
  """
65
71
  Run a backtest for the given algorithm. This function will run
@@ -73,15 +79,40 @@ class BacktestService:
73
79
 
74
80
  At the end of the run all traces
75
81
 
76
- Parameters:
82
+ Args:
77
83
  algorithm: The algorithm to run the backtest for
78
84
  backtest_date_range: The backtest date range
85
+ initial_amount: The initial amount of the backtest portfolio
79
86
 
80
87
  Returns:
81
88
  BacktestReport - The backtest report
82
89
  """
90
+ logging.info(
91
+ f"Running backtest for algorithm with name {algorithm.name}"
92
+ )
93
+
94
+ # Create backtest portfolio
95
+ portfolio_configurations = \
96
+ self._portfolio_configuration_service.get_all()
97
+
98
+ for portfolio_configuration in portfolio_configurations:
99
+
100
+ if self._portfolio_service.exists(
101
+ {"identifier": portfolio_configuration.identifier}
102
+ ):
103
+ # Delete existing portfolio
104
+ portfolio = self._portfolio_service.find(
105
+ {"identifier": portfolio_configuration.identifier}
106
+ )
107
+ self._portfolio_service.delete(portfolio.id)
108
+
109
+ # Check if the portfolio configuration has a initial balance
110
+ self._portfolio_service.create_portfolio_from_configuration(
111
+ portfolio_configuration, initial_amount=initial_amount
112
+ )
113
+
83
114
  strategy_profiles = []
84
- portfolios = self._portfolio_repository.get_all()
115
+ portfolios = self._portfolio_service.get_all()
85
116
  initial_unallocated = 0
86
117
 
87
118
  for portfolio in portfolios:
@@ -114,10 +145,23 @@ class BacktestService:
114
145
  strategy=algorithm.get_strategy(strategy_profile.strategy_id),
115
146
  index_date=index_date,
116
147
  )
117
- return self.create_backtest_report(
148
+
149
+ report = self.create_backtest_report(
118
150
  algorithm, len(schedule), backtest_date_range, initial_unallocated
119
151
  )
120
152
 
153
+ # Cleanup backtest portfolio
154
+ portfolio_configurations = \
155
+ self._portfolio_configuration_service.get_all()
156
+
157
+ for portfolio_configuration in portfolio_configurations:
158
+ portfolio = self._portfolio_service.find(
159
+ {"identifier": portfolio_configuration.identifier}
160
+ )
161
+ self._portfolio_service.delete(portfolio.id)
162
+
163
+ return report
164
+
121
165
  def run_backtests(
122
166
  self, algorithms, backtest_date_range: BacktestDateRange
123
167
  ):
@@ -126,9 +170,9 @@ class BacktestService:
126
170
  backtests for the given algorithms and return a list of backtest
127
171
  reports.
128
172
 
129
- Parameters
130
- - algorithms: The algorithms to run the backtests for
131
- - backtest_date_range: The backtest date range of the backtests
173
+ Args:
174
+ algorithms: The algorithms to run the backtests for
175
+ backtest_date_range: The backtest date range of the backtests
132
176
 
133
177
  Returns:
134
178
  List - A list of backtest reports
@@ -146,6 +190,9 @@ class BacktestService:
146
190
  return backtest_reports
147
191
 
148
192
  def run_backtest_for_profile(self, algorithm, strategy, index_date):
193
+ self._configuration_service.add_value(
194
+ BACKTESTING_INDEX_DATETIME, index_date
195
+ )
149
196
  algorithm.config[BACKTESTING_INDEX_DATETIME] = index_date
150
197
  market_data = {}
151
198
 
@@ -173,7 +220,7 @@ class BacktestService:
173
220
  calculate when the strategies should run based on the given start
174
221
  and end date. The schedule will be stored in a pandas DataFrame.
175
222
 
176
- Parameters:
223
+ Args:
177
224
  strategies: The strategies to generate the schedule for
178
225
  start_date: The start date of the schedule
179
226
  end_date: The end date of the schedule
@@ -207,6 +254,7 @@ class BacktestService:
207
254
  raise ValueError(f"Unsupported time unit: {time_unit}")
208
255
 
209
256
  schedule_df = pd.DataFrame(data)
257
+
210
258
  if schedule_df.empty:
211
259
  raise OperationalException(
212
260
  "Could not generate schedule "
@@ -253,7 +301,7 @@ class BacktestService:
253
301
  BacktestReport: The backtest report instance of BacktestReport
254
302
  """
255
303
 
256
- for portfolio in self._portfolio_repository.get_all():
304
+ for portfolio in self._portfolio_service.get_all():
257
305
  ids = [strategy.strategy_id for strategy in algorithm.strategies]
258
306
 
259
307
  # Check if strategy_id is None
@@ -440,7 +488,6 @@ class BacktestService:
440
488
  if a ticker market data source is registered for the symbol and market.
441
489
  """
442
490
  symbols = self._configuration_service.config[SYMBOLS]
443
- print(symbols)
444
491
 
445
492
  if symbols is not None:
446
493
 
@@ -107,13 +107,13 @@ class MarketDataSourceService:
107
107
  if isinstance(market_data_source, TickerMarketDataSource):
108
108
 
109
109
  if market is not None:
110
- if market_data_source.market.lower() == market.lower()\
111
- and market_data_source.symbol.lower() \
112
- == symbol.lower():
110
+ if market_data_source.market.upper() == market.upper()\
111
+ and market_data_source.symbol.upper() \
112
+ == symbol.upper():
113
113
  return market_data_source
114
114
  else:
115
- if market_data_source.symbol.lower() \
116
- == symbol.lower():
115
+ if market_data_source.symbol.upper() \
116
+ == symbol.upper():
117
117
  return market_data_source
118
118
 
119
119
  return None
@@ -143,28 +143,28 @@ class MarketDataSourceService:
143
143
  if isinstance(market_data_source, OHLCVMarketDataSource):
144
144
 
145
145
  if market is not None and time_frame is not None:
146
- if market_data_source.market.lower() == market.lower()\
147
- and market_data_source.symbol.lower() \
148
- == symbol.lower() and \
146
+ if market_data_source.market.upper() == market.upper()\
147
+ and market_data_source.symbol.upper() \
148
+ == symbol.upper() and \
149
149
  time_frame.equals(
150
150
  market_data_source.time_frame
151
151
  ):
152
152
  return market_data_source
153
153
  elif market is not None:
154
- if market_data_source.market.lower() == market.lower()\
155
- and market_data_source.symbol.lower() \
156
- == symbol.lower():
154
+ if market_data_source.market.upper() == market.upper()\
155
+ and market_data_source.symbol.upper() \
156
+ == symbol.upper():
157
157
  return market_data_source
158
158
  elif time_frame is not None:
159
- if market_data_source.symbol.lower() \
160
- == symbol.lower() and \
159
+ if market_data_source.symbol.upper() \
160
+ == symbol.upper() and \
161
161
  time_frame.equals(
162
162
  market_data_source.time_frame
163
163
  ):
164
164
  return market_data_source
165
165
  else:
166
- if market_data_source.symbol.lower() \
167
- == symbol.lower():
166
+ if market_data_source.symbol.upper() \
167
+ == symbol.upper():
168
168
  return market_data_source
169
169
 
170
170
  return None
@@ -176,13 +176,13 @@ class MarketDataSourceService:
176
176
  if isinstance(market_data_source, OrderBookMarketDataSource):
177
177
 
178
178
  if market is not None:
179
- if market_data_source.market.lower() == market.lower()\
180
- and market_data_source.symbol.lower() \
181
- == symbol.lower():
179
+ if market_data_source.market.upper() == market.upper()\
180
+ and market_data_source.symbol.upper() \
181
+ == symbol.upper():
182
182
  return market_data_source
183
183
  else:
184
- if market_data_source.symbol.lower() \
185
- == symbol.lower():
184
+ if market_data_source.symbol.upper() \
185
+ == symbol.upper():
186
186
  return market_data_source
187
187
 
188
188
  return None
@@ -0,0 +1,46 @@
1
+ from investing_algorithm_framework.domain import PortfolioConfiguration, \
2
+ OperationalException
3
+ from .portfolio_service import PortfolioService
4
+
5
+
6
+ class BacktestPortfolioService(PortfolioService):
7
+ """
8
+ BacktestPortfolioService is a subclass of PortfolioService.
9
+ It is used to create a portfolio for backtesting. This class does
10
+ not check if the initial balance is present on the exchange or broker.
11
+ """
12
+ def create_portfolio_from_configuration(
13
+ self, portfolio_configuration: PortfolioConfiguration,
14
+ initial_amount=None
15
+ ):
16
+ """
17
+ Wil create a portfolio from a portfolio configuration for backtesting.
18
+
19
+ Args:
20
+ portfolio_configuration (PortfolioConfiguration):
21
+ Portfolio configuration to create the portfolio from
22
+ initial_amount (Decimal): Initial balance for the portfolio
23
+
24
+ Returns:
25
+ Portfolio: The created portfolio
26
+ """
27
+ amount = portfolio_configuration.initial_balance
28
+
29
+ if initial_amount is not None:
30
+ amount = initial_amount
31
+
32
+ if amount is None:
33
+ raise OperationalException(
34
+ "Initial amount is required as a parameter or the " +
35
+ "'initial_balance' attribute needs to be set on the "
36
+ "portfolio configuration before running the backtest."
37
+ )
38
+
39
+ data = {
40
+ "identifier": portfolio_configuration.identifier,
41
+ "market": portfolio_configuration.market,
42
+ "trading_symbol": portfolio_configuration.trading_symbol,
43
+ "unallocated": amount,
44
+ "initialized": True
45
+ }
46
+ return self.create(data)