investing-algorithm-framework 4.1.1__tar.gz → 5.0.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 (169) hide show
  1. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/PKG-INFO +20 -11
  2. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/README.md +17 -9
  3. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/__init__.py +4 -2
  4. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/algorithm.py +248 -21
  5. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/app.py +267 -356
  6. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/strategy.py +76 -15
  7. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/dependency_container.py +26 -19
  8. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/__init__.py +8 -3
  9. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/constants.py +3 -3
  10. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/__init__.py +2 -0
  11. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +4 -1
  12. investing_algorithm_framework-5.0.0/investing_algorithm_framework/domain/models/market_data_type.py +46 -0
  13. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order.py +4 -66
  14. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_status.py +1 -1
  15. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_frame.py +21 -0
  16. investing_algorithm_framework-5.0.0/investing_algorithm_framework/domain/models/trade/trade.py +296 -0
  17. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trade/trade_status.py +1 -0
  18. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_data_sources.py +32 -16
  19. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/backtesting.py +61 -6
  20. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/polars.py +4 -0
  21. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/trend.py +14 -2
  22. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/__init__.py +5 -3
  23. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/__init__.py +2 -0
  24. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +40 -99
  25. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +69 -62
  26. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +6 -44
  27. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/order/order.py +19 -30
  28. investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
  29. investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/models/trade.py +106 -0
  30. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +2 -0
  31. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +7 -0
  32. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +3 -0
  33. investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
  34. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +35 -67
  35. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/backtesting/backtest_service.py +19 -6
  36. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/configuration_service.py +8 -3
  37. investing_algorithm_framework-5.0.0/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +207 -0
  38. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +149 -17
  39. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/order_backtest_service.py +26 -56
  40. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/order_service.py +42 -115
  41. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +8 -39
  42. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +31 -18
  43. investing_algorithm_framework-5.0.0/investing_algorithm_framework/services/trade_service/trade_service.py +347 -0
  44. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/pyproject.toml +2 -2
  45. investing_algorithm_framework-4.1.1/investing_algorithm_framework/domain/models/trade/trade.py +0 -287
  46. investing_algorithm_framework-4.1.1/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -149
  47. investing_algorithm_framework-4.1.1/investing_algorithm_framework/services/trade_service/trade_service.py +0 -401
  48. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/LICENSE +0 -0
  49. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/__init__.py +0 -0
  50. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  51. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  52. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  53. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  54. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  55. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  56. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/task.py +0 -0
  57. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
  58. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  59. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  60. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  61. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  62. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
  63. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  64. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/responses.py +0 -0
  65. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  66. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  67. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  68. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  69. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  70. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  71. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/__init__.py +0 -0
  72. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/create_azure_function_app_skeleton.py +0 -0
  73. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/deploy_to_azure_function.py +0 -0
  74. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_framework_app.py.template +0 -0
  75. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +0 -0
  76. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_host.json.template +0 -0
  77. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +0 -0
  78. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +0 -0
  79. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/create_app.py +0 -0
  80. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/config.py +0 -0
  81. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/data_structures.py +0 -0
  82. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  83. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
  84. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/metrics/__init__.py +0 -0
  85. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/metrics/price_efficiency.py +0 -0
  86. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
  87. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -0
  88. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -0
  89. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -0
  90. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
  91. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  92. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/date_range.py +0 -0
  93. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
  94. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
  95. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
  96. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  97. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  98. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
  99. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
  100. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
  101. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  102. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  103. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  104. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  105. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  106. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  107. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  108. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
  109. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
  110. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
  111. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  112. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  113. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/__init__.py +0 -0
  114. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
  115. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_service.py +0 -0
  116. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
  117. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
  118. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
  119. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/singleton.py +0 -0
  120. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  121. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/strategy.py +0 -0
  122. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
  123. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  124. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
  125. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  126. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  127. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  128. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/__init__.py +0 -0
  129. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/advanced.py +0 -0
  130. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/momentum.py +0 -0
  131. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/utils.py +0 -0
  132. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  133. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  134. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  135. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  136. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -0
  137. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  138. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
  139. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  140. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  141. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/sql_portfolio.py +0 -0
  142. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  143. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  144. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  145. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  146. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
  147. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  148. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  149. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
  150. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/azure/__init__.py +0 -0
  151. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/azure/state_handler.py +0 -0
  152. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
  153. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -0
  154. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  155. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  156. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/__init__.py +0 -0
  157. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
  158. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_credential_service.py +0 -0
  159. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
  160. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
  161. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
  162. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
  163. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
  164. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
  165. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
  166. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/position_service.py +0 -0
  167. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  168. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/repository_service.py +0 -0
  169. {investing_algorithm_framework-4.1.1 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing-algorithm-framework
3
- Version: 4.1.1
3
+ Version: 5.0.0
4
4
  Summary: A framework for creating trading bots
5
5
  Author: MDUYN
6
- Requires-Python: >=3.10
6
+ Requires-Python: >=3.9
7
7
  Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.9
8
9
  Classifier: Programming Language :: Python :: 3.10
9
10
  Classifier: Programming Language :: Python :: 3.11
10
11
  Classifier: Programming Language :: Python :: 3.12
@@ -74,7 +75,8 @@ Features:
74
75
  The following algorithm connects to binance and buys BTC every 5 seconds. It also exposes an REST API that allows you to interact with the algorithm.
75
76
 
76
77
  ```python
77
- import logging
78
+ import logging.config
79
+
78
80
  from investing_algorithm_framework import create_app, PortfolioConfiguration, \
79
81
  TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
80
82
  CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG
@@ -96,7 +98,6 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
96
98
  symbol="BTC/EUR",
97
99
  )
98
100
  app = create_app()
99
- algorithm = Algorithm()
100
101
  # Bitvavo market credentials are read from .env file
101
102
  app.add_market_credential(MarketCredential(market="bitvavo"))
102
103
  app.add_portfolio_configuration(
@@ -106,10 +107,9 @@ app.add_portfolio_configuration(
106
107
  initial_balance=400
107
108
  )
108
109
  )
109
- app.add_algorithm(algorithm)
110
110
 
111
111
  # Run every two hours and register the data sources
112
- @algorithm.strategy(
112
+ @app.strategy(
113
113
  time_unit=TimeUnit.HOUR,
114
114
  interval=2,
115
115
  market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
@@ -117,7 +117,6 @@ app.add_algorithm(algorithm)
117
117
  def perform_strategy(algorithm: Algorithm, market_data: dict):
118
118
  # Access the data sources with the indentifier
119
119
  polars_df = market_data["BTC-ohlcv"]
120
-
121
120
  # Convert the polars dataframe to a pandas dataframe
122
121
  pandas_df = polars_df.to_pandas()
123
122
  ticker_data = market_data["BTC-ticker"]
@@ -128,18 +127,21 @@ def perform_strategy(algorithm: Algorithm, market_data: dict):
128
127
  closed_trades = algorithm.get_closed_trades()
129
128
 
130
129
  # Create a buy oder
131
- algorithm.create_limit_order(
130
+ order = algorithm.create_limit_order(
132
131
  target_symbol="BTC/EUR",
133
132
  order_side="buy",
134
133
  amount=0.01,
135
134
  price=ticker_data["ask"],
136
135
  )
136
+ trade = algorithm.get_trade(order_id=order.id)
137
+ algorithm.add_trailing_stop_loss(trade=trade, percentage=5)
137
138
 
138
139
  # Close a trade
139
- algorithm.close_trade(trades[0].id)
140
+ algorithm.close_trade(trade=trade)
140
141
 
141
142
  # Close a position
142
- algorithm.close_position(positions[0].get_symbol())
143
+ position = algorithm.get_position(symbol="BTC/EUR")
144
+ algorithm.close_position(position)
143
145
 
144
146
  if __name__ == "__main__":
145
147
  app.run()
@@ -151,7 +153,14 @@ if __name__ == "__main__":
151
153
 
152
154
  The framework also supports backtesting and performing backtest experiments. After a backtest, you can print a report that shows the performance of your trading bot.
153
155
 
154
- To run a single backtest you can use the example code that can be found [here](./examples/backtest).
156
+ To run a single backtest you can use the example code that can be found [here](./examples/backtest_example). Simply run:
157
+
158
+ > Its assumed here that you have cloned the repository, installed the framework and
159
+ > are in the root of the project.
160
+
161
+ ```bash
162
+ python examples/backtest_example/run_backtest.py
163
+ ```
155
164
 
156
165
  ### Backtesting report
157
166
 
@@ -37,7 +37,8 @@ Features:
37
37
  The following algorithm connects to binance and buys BTC every 5 seconds. It also exposes an REST API that allows you to interact with the algorithm.
38
38
 
39
39
  ```python
40
- import logging
40
+ import logging.config
41
+
41
42
  from investing_algorithm_framework import create_app, PortfolioConfiguration, \
42
43
  TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
43
44
  CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG
@@ -59,7 +60,6 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
59
60
  symbol="BTC/EUR",
60
61
  )
61
62
  app = create_app()
62
- algorithm = Algorithm()
63
63
  # Bitvavo market credentials are read from .env file
64
64
  app.add_market_credential(MarketCredential(market="bitvavo"))
65
65
  app.add_portfolio_configuration(
@@ -69,10 +69,9 @@ app.add_portfolio_configuration(
69
69
  initial_balance=400
70
70
  )
71
71
  )
72
- app.add_algorithm(algorithm)
73
72
 
74
73
  # Run every two hours and register the data sources
75
- @algorithm.strategy(
74
+ @app.strategy(
76
75
  time_unit=TimeUnit.HOUR,
77
76
  interval=2,
78
77
  market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
@@ -80,7 +79,6 @@ app.add_algorithm(algorithm)
80
79
  def perform_strategy(algorithm: Algorithm, market_data: dict):
81
80
  # Access the data sources with the indentifier
82
81
  polars_df = market_data["BTC-ohlcv"]
83
-
84
82
  # Convert the polars dataframe to a pandas dataframe
85
83
  pandas_df = polars_df.to_pandas()
86
84
  ticker_data = market_data["BTC-ticker"]
@@ -91,18 +89,21 @@ def perform_strategy(algorithm: Algorithm, market_data: dict):
91
89
  closed_trades = algorithm.get_closed_trades()
92
90
 
93
91
  # Create a buy oder
94
- algorithm.create_limit_order(
92
+ order = algorithm.create_limit_order(
95
93
  target_symbol="BTC/EUR",
96
94
  order_side="buy",
97
95
  amount=0.01,
98
96
  price=ticker_data["ask"],
99
97
  )
98
+ trade = algorithm.get_trade(order_id=order.id)
99
+ algorithm.add_trailing_stop_loss(trade=trade, percentage=5)
100
100
 
101
101
  # Close a trade
102
- algorithm.close_trade(trades[0].id)
102
+ algorithm.close_trade(trade=trade)
103
103
 
104
104
  # Close a position
105
- algorithm.close_position(positions[0].get_symbol())
105
+ position = algorithm.get_position(symbol="BTC/EUR")
106
+ algorithm.close_position(position)
106
107
 
107
108
  if __name__ == "__main__":
108
109
  app.run()
@@ -114,7 +115,14 @@ if __name__ == "__main__":
114
115
 
115
116
  The framework also supports backtesting and performing backtest experiments. After a backtest, you can print a report that shows the performance of your trading bot.
116
117
 
117
- To run a single backtest you can use the example code that can be found [here](./examples/backtest).
118
+ To run a single backtest you can use the example code that can be found [here](./examples/backtest_example). Simply run:
119
+
120
+ > Its assumed here that you have cloned the repository, installed the framework and
121
+ > are in the root of the project.
122
+
123
+ ```bash
124
+ python examples/backtest_example/run_backtest.py
125
+ ```
118
126
 
119
127
  ### Backtesting report
120
128
 
@@ -12,7 +12,7 @@ from investing_algorithm_framework.domain import ApiException, \
12
12
  RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
13
13
  load_backtest_report, BacktestDateRange, convert_polars_to_pandas, \
14
14
  DateRange, get_backtest_report, DEFAULT_LOGGING_CONFIG, \
15
- BacktestReport
15
+ BacktestReport, TradeStatus, MarketDataType
16
16
  from investing_algorithm_framework.infrastructure import \
17
17
  CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
18
18
  CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
@@ -90,5 +90,7 @@ __all__ = [
90
90
  "get_backtest_report",
91
91
  "AzureBlobStorageStateHandler",
92
92
  "DEFAULT_LOGGING_CONFIG",
93
- "BacktestReport"
93
+ "BacktestReport",
94
+ "TradeStatus",
95
+ "MarketDataType"
94
96
  ]
@@ -4,7 +4,7 @@ from typing import List, Dict
4
4
  import re
5
5
 
6
6
  from investing_algorithm_framework.domain import OrderStatus, \
7
- Position, Order, Portfolio, OrderType, OrderSide, \
7
+ Position, Order, Portfolio, OrderType, OrderSide, TradeStatus, \
8
8
  BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, MarketService, TimeUnit, \
9
9
  OperationalException, random_string, RoundingService, Trade
10
10
  from investing_algorithm_framework.services import MarketCredentialService, \
@@ -61,7 +61,7 @@ class Algorithm:
61
61
  self.market_service: MarketService
62
62
  self.configuration_service: ConfigurationService
63
63
  self.portfolio_configuration_service: PortfolioConfigurationService
64
- self.strategy_orchestrator_service: StrategyOrchestratorService
64
+ self.strategy_orchestrator_service: StrategyOrchestratorService = None
65
65
  self._data_sources = {}
66
66
  self._strategies = []
67
67
  self._market_credential_service: MarketCredentialService
@@ -164,6 +164,19 @@ class Algorithm:
164
164
  number_of_iterations=number_of_iterations
165
165
  )
166
166
 
167
+ def stop(self) -> None:
168
+ """
169
+ Function to stop the algorithm. This function will stop the
170
+ algorithm by stopping all jobs in the strategy orchestrator
171
+ service.
172
+
173
+ Returns:
174
+ None
175
+ """
176
+
177
+ if self.strategy_orchestrator_service is not None:
178
+ self.strategy_orchestrator_service.stop()
179
+
167
180
  @property
168
181
  def name(self):
169
182
  return self._name
@@ -186,6 +199,14 @@ class Algorithm:
186
199
  """
187
200
  return self.configuration_service.get_config()
188
201
 
202
+ def get_config(self):
203
+ """
204
+ Function to get a config instance. This allows users when
205
+ having access to the algorithm instance also to read the
206
+ configs of the app.
207
+ """
208
+ return self.configuration_service.get_config()
209
+
189
210
  @property
190
211
  def description(self):
191
212
  """
@@ -329,7 +350,7 @@ class Algorithm:
329
350
  order and execute it if the execute parameter is set to True. If the
330
351
  validate parameter is set to True, the order will be validated
331
352
 
332
- Parameters:
353
+ Args:
333
354
  target_symbol: The symbol of the asset to trade
334
355
  price: The price of the asset
335
356
  order_side: The side of the order
@@ -490,7 +511,7 @@ class Algorithm:
490
511
  """
491
512
 
492
513
  if market is None:
493
- return self.portfolio_service.find({})
514
+ return self.portfolio_service.get_all()[0]
494
515
 
495
516
  return self.portfolio_service.find({{"market": market}})
496
517
 
@@ -511,7 +532,7 @@ class Algorithm:
511
532
  If the market parameter is specified, the unallocated balance
512
533
  of the specified market will be returned.
513
534
 
514
- Parameters:
535
+ Args:
515
536
  market: The market of the portfolio
516
537
 
517
538
  Returns:
@@ -521,7 +542,7 @@ class Algorithm:
521
542
  if market:
522
543
  portfolio = self.portfolio_service.find({{"market": market}})
523
544
  else:
524
- portfolio = self.portfolio_service.find({})
545
+ portfolio = self.portfolio_service.get_all()[0]
525
546
 
526
547
  trading_symbol = portfolio.trading_symbol
527
548
  return self.position_service.find(
@@ -553,6 +574,19 @@ class Algorithm:
553
574
  order_side=None,
554
575
  order_type=None
555
576
  ) -> Order:
577
+ """
578
+ Function to retrieve an order.
579
+
580
+ Exception is thrown when no param has been provided.
581
+
582
+ Args:
583
+ reference_id [optional] (int): id given by the external
584
+ market or exchange.
585
+ market [optional] (str): the market that the order was
586
+ executed on.
587
+ target_symbol [optional] (str): the symbol of the asset
588
+ that the order was executed
589
+ """
556
590
  query_params = {}
557
591
 
558
592
  if reference_id:
@@ -577,6 +611,11 @@ class Algorithm:
577
611
  )
578
612
  query_params["position"] = [position.id for position in positions]
579
613
 
614
+ if not query_params:
615
+ raise OperationalException(
616
+ "No parameters provided to get order."
617
+ )
618
+
580
619
  return self.order_service.find(query_params)
581
620
 
582
621
  def get_orders(
@@ -1183,25 +1222,95 @@ class Algorithm:
1183
1222
  query_params["status"] = OrderStatus.OPEN.value
1184
1223
  return self.order_service.exists(query_params)
1185
1224
 
1186
- def check_pending_orders(self):
1225
+ def get_trade(
1226
+ self,
1227
+ target_symbol=None,
1228
+ trading_symbol=None,
1229
+ market=None,
1230
+ portfolio=None,
1231
+ status=None,
1232
+ order_id=None
1233
+ ) -> List[Trade]:
1187
1234
  """
1188
- Function to check pending orders
1235
+ Function to get all trades. This function will return all trades
1236
+ that match the specified query parameters. If the market parameter
1237
+ is specified, the trades with the specified market will be returned.
1238
+
1239
+ Args:
1240
+ market: The market of the asset
1241
+ portfolio: The portfolio of the asset
1242
+ status: The status of the trade
1243
+ order_id: The order id of the trade
1244
+ target_symbol: The symbol of the asset
1245
+ trading_symbol: The trading symbol of the asset
1246
+
1247
+ Returns:
1248
+ List[Trade]: A list of trades that match the query parameters
1189
1249
  """
1190
- self.order_service.check_pending_orders()
1250
+ query_params = {}
1251
+
1252
+ if market is not None:
1253
+ query_params["market"] = market
1254
+
1255
+ if portfolio is not None:
1256
+ query_params["portfolio"] = portfolio
1257
+
1258
+ if status is not None:
1259
+ query_params["status"] = status
1260
+
1261
+ if order_id is not None:
1262
+ query_params["order_id"] = order_id
1263
+
1264
+ if target_symbol is not None:
1265
+ query_params["target_symbol"] = target_symbol
1266
+
1267
+ if trading_symbol is not None:
1268
+ query_params["trading_symbol"] = trading_symbol
1191
1269
 
1192
- def get_trades(self, market=None) -> List[Trade]:
1270
+ return self.trade_service.find(query_params)
1271
+
1272
+ def get_trades(
1273
+ self,
1274
+ target_symbol=None,
1275
+ trading_symbol=None,
1276
+ market=None,
1277
+ portfolio=None,
1278
+ status=None,
1279
+ ) -> List[Trade]:
1193
1280
  """
1194
1281
  Function to get all trades. This function will return all trades
1195
1282
  that match the specified query parameters. If the market parameter
1196
1283
  is specified, the trades with the specified market will be returned.
1197
1284
 
1198
- Parameters:
1285
+ Args:
1199
1286
  market: The market of the asset
1287
+ portfolio: The portfolio of the asset
1288
+ status: The status of the trade
1289
+ target_symbol: The symbol of the asset
1290
+ trading_symbol: The trading symbol of the asset
1200
1291
 
1201
1292
  Returns:
1202
1293
  List[Trade]: A list of trades that match the query parameters
1203
1294
  """
1204
- return self.trade_service.get_trades(market)
1295
+
1296
+ query_params = {}
1297
+
1298
+ if market is not None:
1299
+ query_params["market"] = market
1300
+
1301
+ if portfolio is not None:
1302
+ query_params["portfolio"] = portfolio
1303
+
1304
+ if status is not None:
1305
+ query_params["status"] = status
1306
+
1307
+ if target_symbol is not None:
1308
+ query_params["target_symbol"] = target_symbol
1309
+
1310
+ if trading_symbol is not None:
1311
+ query_params["trading_symbol"] = trading_symbol
1312
+
1313
+ return self.trade_service.get_all({"market": market})
1205
1314
 
1206
1315
  def get_closed_trades(self) -> List[Trade]:
1207
1316
  """
@@ -1211,7 +1320,44 @@ class Algorithm:
1211
1320
  Returns:
1212
1321
  List[Trade]: A list of closed trades
1213
1322
  """
1214
- return self.trade_service.get_closed_trades()
1323
+ return self.trade_service.get_all({"status": TradeStatus.CLOSED.value})
1324
+
1325
+ def count_trades(
1326
+ self,
1327
+ target_symbol=None,
1328
+ trading_symbol=None,
1329
+ market=None,
1330
+ portfolio=None
1331
+ ) -> int:
1332
+ """
1333
+ Function to count trades. This function will return the number of
1334
+ trades that match the specified query parameters.
1335
+
1336
+ Args:
1337
+ target_symbol: The symbol of the asset
1338
+ trading_symbol: The trading symbol of the asset
1339
+ market: The market of the asset
1340
+ portfolio: The portfolio of the asset
1341
+
1342
+ Returns:
1343
+ int: The number of trades that match the query parameters
1344
+ """
1345
+
1346
+ query_params = {}
1347
+
1348
+ if market is not None:
1349
+ query_params["market"] = market
1350
+
1351
+ if portfolio is not None:
1352
+ query_params["portfolio"] = portfolio
1353
+
1354
+ if target_symbol is not None:
1355
+ query_params["target_symbol"] = target_symbol
1356
+
1357
+ if trading_symbol is not None:
1358
+ query_params["trading_symbol"] = trading_symbol
1359
+
1360
+ return self.trade_service.count(query_params)
1215
1361
 
1216
1362
  def get_open_trades(self, target_symbol=None, market=None) -> List[Trade]:
1217
1363
  """
@@ -1222,32 +1368,107 @@ class Algorithm:
1222
1368
  is specified, the open trades with the specified market will be
1223
1369
  returned.
1224
1370
 
1225
- Parameters:
1371
+ Args:
1226
1372
  target_symbol: The symbol of the asset
1227
1373
  market: The market of the asset
1228
1374
 
1229
1375
  Returns:
1230
1376
  List[Trade]: A list of open trades that match the query parameters
1231
1377
  """
1232
- return self.trade_service.get_open_trades(target_symbol, market)
1378
+ return self.trade_service.get_all(
1379
+ {
1380
+ "status": TradeStatus.OPEN.value,
1381
+ "target_symbol": target_symbol,
1382
+ "market": market
1383
+ }
1384
+ )
1385
+
1386
+ def add_stop_loss(self, trade, percentage: int) -> None:
1387
+ """
1388
+ Function to add a stop loss to a trade. This function will add a
1389
+ stop loss to the specified trade. If the stop loss is triggered,
1390
+ the trade will be closed.
1391
+
1392
+ Args:
1393
+ trade: Trade - The trade to add the stop loss to
1394
+ percentage: int - The stop loss of the trade
1395
+
1396
+ Returns:
1397
+ None
1398
+ """
1399
+ self.trade_service.add_stop_loss(trade, percentage=percentage)
1400
+
1401
+ def add_trailing_stop_loss(self, trade, percentage: int) -> None:
1402
+ """
1403
+ Function to add a trailing stop loss to a trade. This function will
1404
+ add a trailing stop loss to the specified trade. If the trailing
1405
+ stop loss is triggered, the trade will be closed.
1233
1406
 
1234
- def close_trade(self, trade, market=None, precision=None) -> None:
1407
+ Args:
1408
+ trade: Trade - The trade to add the trailing stop loss to
1409
+ trailing_stop_loss: float - The trailing stop loss of the trade
1410
+
1411
+ Returns:
1412
+ None
1413
+ """
1414
+ self.trade_service.add_trailing_stop_loss(trade, percentage=percentage)
1415
+
1416
+ def close_trade(self, trade, precision=None) -> None:
1235
1417
  """
1236
1418
  Function to close a trade. This function will close a trade by
1237
1419
  creating a market order to sell the position. If the precision
1238
1420
  parameter is specified, the amount of the order will be rounded
1239
1421
  down to the specified precision.
1240
1422
 
1241
- Parameters:
1423
+ Args:
1242
1424
  trade: Trade - The trade to close
1243
- market: str - The market of the trade
1244
- precision: float - The precision of the amount
1425
+ precision: int - The precision of the amount
1245
1426
 
1246
1427
  Returns:
1247
1428
  None
1248
1429
  """
1249
- self.trade_service.close_trade(
1250
- trade=trade, market=market, precision=precision
1430
+
1431
+ trade = self.trade_service.get(trade.id)
1432
+
1433
+ if TradeStatus.CLOSED.equals(trade.status):
1434
+ raise OperationalException("Trade already closed.")
1435
+
1436
+ if trade.remaining <= 0:
1437
+ raise OperationalException("Trade has no amount to close.")
1438
+
1439
+ position_id = trade.orders[0].position_id
1440
+ portfolio = self.portfolio_service.find({"position": position_id})
1441
+ position = self.position_service.find(
1442
+ {"portfolio": portfolio.id, "symbol": trade.target_symbol}
1443
+ )
1444
+ amount = trade.remaining
1445
+
1446
+ if precision is not None:
1447
+ amount = RoundingService.round_down(amount, precision)
1448
+
1449
+ if position.get_amount() < amount:
1450
+ logger.warning(
1451
+ f"Order amount {amount} is larger then amount "
1452
+ f"of available {position.symbol} "
1453
+ f"position: {position.get_amount()}, "
1454
+ f"changing order amount to size of position"
1455
+ )
1456
+ amount = position.get_amount()
1457
+
1458
+ ticker = self._market_data_source_service.get_ticker(
1459
+ symbol=trade.symbol, market=portfolio.market
1460
+ )
1461
+
1462
+ self.order_service.create(
1463
+ {
1464
+ "portfolio_id": portfolio.id,
1465
+ "trading_symbol": trade.trading_symbol,
1466
+ "target_symbol": trade.target_symbol,
1467
+ "amount": amount,
1468
+ "order_side": OrderSide.SELL.value,
1469
+ "order_type": OrderType.LIMIT.value,
1470
+ "price": ticker["bid"],
1471
+ }
1251
1472
  )
1252
1473
 
1253
1474
  def get_number_of_positions(self):
@@ -1400,3 +1621,9 @@ class Algorithm:
1400
1621
  [order.get_amount() * order.get_price()
1401
1622
  for order in pending_orders]
1402
1623
  )
1624
+
1625
+ def get_trade_service(self):
1626
+ return self.trade_service
1627
+
1628
+ def get_market_data_source_service(self):
1629
+ return self._market_data_source_service