investing-algorithm-framework 1.7.10__tar.gz → 2.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 (149) hide show
  1. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/PKG-INFO +40 -29
  2. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/README.md +39 -28
  3. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/__init__.py +7 -10
  4. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/algorithm.py +42 -163
  5. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/app.py +124 -61
  6. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/strategy.py +1 -5
  7. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/create_app.py +3 -1
  8. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/dependency_container.py +23 -15
  9. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/__init__.py +15 -12
  10. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/constants.py +3 -0
  11. investing_algorithm_framework-2.0/investing_algorithm_framework/domain/data_structures.py +41 -0
  12. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/__init__.py +3 -8
  13. investing_algorithm_framework-2.0/investing_algorithm_framework/domain/models/market/__init__.py +5 -0
  14. investing_algorithm_framework-2.0/investing_algorithm_framework/domain/models/market/market_credential.py +26 -0
  15. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -2
  16. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +3 -0
  17. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +7 -37
  18. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/services/__init__.py +3 -1
  19. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/services/market_data_sources.py +27 -13
  20. investing_algorithm_framework-2.0/investing_algorithm_framework/domain/services/market_service.py +129 -0
  21. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/__init__.py +1 -4
  22. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +70 -44
  23. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +3 -11
  24. investing_algorithm_framework-2.0/investing_algorithm_framework/infrastructure/services/__init__.py +7 -0
  25. investing_algorithm_framework-2.0/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +5 -0
  26. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +141 -145
  27. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/__init__.py +9 -5
  28. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/backtest_service.py +34 -32
  29. investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_credential_service.py +24 -0
  30. investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/__init__.py +8 -0
  31. investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +113 -0
  32. investing_algorithm_framework-2.0/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +131 -0
  33. investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service/__init__.py +7 -0
  34. {investing_algorithm_framework-1.7.10/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service}/order_backtest_service.py +64 -34
  35. {investing_algorithm_framework-1.7.10/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/order_service}/order_service.py +19 -17
  36. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/portfolio_configuration_service.py +3 -14
  37. investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service/__init__.py +7 -0
  38. investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service/backtest_portfolio_service.py +20 -0
  39. {investing_algorithm_framework-1.7.10/investing_algorithm_framework/services → investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service}/portfolio_service.py +12 -12
  40. investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service.py +207 -0
  41. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/position_service.py +19 -9
  42. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +9 -6
  43. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/PKG-INFO +40 -29
  44. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/SOURCES.txt +14 -13
  45. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/tests/test_create_app.py +1 -3
  46. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/market_data/__init__.py +0 -11
  47. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/market_data/asset_price.py +0 -50
  48. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/market_data/ohlcv.py +0 -105
  49. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/market_data/order_book.py +0 -63
  50. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/market_data/ticker.py +0 -92
  51. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/models/portfolio/backtest_portfolio_configuration.py +0 -21
  52. investing_algorithm_framework-1.7.10/investing_algorithm_framework/domain/services/order_executor_service.py +0 -33
  53. investing_algorithm_framework-1.7.10/investing_algorithm_framework/infrastructure/services/__init__.py +0 -10
  54. investing_algorithm_framework-1.7.10/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -9
  55. investing_algorithm_framework-1.7.10/investing_algorithm_framework/infrastructure/services/market_service/backtest_market_service.py +0 -185
  56. investing_algorithm_framework-1.7.10/investing_algorithm_framework/infrastructure/services/market_service/market_service.py +0 -112
  57. investing_algorithm_framework-1.7.10/investing_algorithm_framework/services/market_data_service.py +0 -80
  58. investing_algorithm_framework-1.7.10/investing_algorithm_framework/services/position_cost_service.py +0 -5
  59. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/AUTHORS.md +0 -0
  60. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/LICENSE +0 -0
  61. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/__init__.py +0 -0
  62. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  63. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  64. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  65. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  66. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  67. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  68. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/task.py +0 -0
  69. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
  70. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  71. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  72. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  73. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  74. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
  75. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  76. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/responses.py +0 -0
  77. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  78. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  79. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  80. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  81. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  82. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  83. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/config.py +0 -0
  84. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  85. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
  86. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/backtest_profile.py +0 -0
  87. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  88. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
  89. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order.py +0 -0
  90. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_fee.py +0 -0
  91. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  92. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
  93. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  94. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  95. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  96. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  97. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  98. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  99. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
  100. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  101. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  102. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trade.py +0 -0
  103. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  104. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  105. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/singleton.py +0 -0
  106. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  107. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/strategy.py +0 -0
  108. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
  109. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/backtesting.py +0 -0
  110. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  111. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
  112. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  113. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  114. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  115. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  116. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  117. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
  118. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  119. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  120. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  121. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
  122. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
  123. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -0
  124. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  125. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
  126. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  127. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  128. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  129. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  130. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
  131. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -0
  132. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  133. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
  134. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  135. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
  136. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  137. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
  138. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  139. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  140. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
  141. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/configuration_service.py +0 -0
  142. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/portfolio_snapshot_service.py +0 -0
  143. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  144. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework/services/repository_service.py +0 -0
  145. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/dependency_links.txt +0 -0
  146. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/requires.txt +0 -0
  147. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/investing_algorithm_framework.egg-info/top_level.txt +0 -0
  148. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/setup.cfg +0 -0
  149. {investing_algorithm_framework-1.7.10 → investing_algorithm_framework-2.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing_algorithm_framework
3
- Version: 1.7.10
3
+ Version: 2.0
4
4
  Summary: A framework for creating an investment algorithm
5
5
  Home-page: https://github.com/coding-kitties/investing-algorithm-framework.git
6
6
  Download-URL: https://github.com/coding-kitties/investing-algorithm-framework/archive/v0.1.1.tar.gz
@@ -64,12 +64,11 @@ import pathlib
64
64
  from datetime import datetime, timedelta
65
65
  from investing_algorithm_framework import create_app, PortfolioConfiguration, \
66
66
  RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
67
- CCXTTickerMarketDataSource
67
+ CCXTTickerMarketDataSource, MarketCredential
68
68
 
69
69
  # Define market data sources
70
- # OHLCV data
71
70
  bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
72
- identifier="BTC",
71
+ identifier="BTC-ohlcv",
73
72
  market="BITVAVO",
74
73
  symbol="BTC/EUR",
75
74
  timeframe="2h",
@@ -77,19 +76,23 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
77
76
  )
78
77
  # Ticker data for orders, trades and positions
79
78
  bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
80
- identifier="BTC",
79
+ identifier="BTC-ticker",
81
80
  market="BITVAVO",
82
81
  symbol="BTC/EUR",
83
82
  )
84
83
  app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
85
84
  app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
86
85
  app.add_market_data_source(bitvavo_btc_eur_ticker)
86
+ app.add_market_credential(MarketCredential(
87
+ market="bitvavo",
88
+ api_key="<your api key>",
89
+ secret_key="<your secret key>",
90
+ ))
87
91
  app.add_portfolio_configuration(
88
92
  PortfolioConfiguration(
89
- market="BITVAVO",
90
- api_key="<your api key>",
91
- secret_key="<your secret key>",
92
- trading_symbol="EUR"
93
+ market="bitvavo",
94
+ trading_symbol="EUR",
95
+ initial_balance=400
93
96
  )
94
97
  )
95
98
 
@@ -99,12 +102,12 @@ app.add_portfolio_configuration(
99
102
  time_unit=TimeUnit.HOUR,
100
103
  interval=2,
101
104
  # Specify market data sources that need to be passed to the strategy
102
- market_data_sources=[bitvavo_btc_eur_ohlcv_2h, bitvavo_btc_eur_ticker]
105
+ market_data_sources=["BTC-ticker", "BTC-ohlcv"]
103
106
  )
104
- def perform_strategy(algorithm: Algorithm, market_data):
107
+ def perform_strategy(algorithm: Algorithm, market_data: dict):
105
108
  print(
106
109
  f"Performing trading strategy on market " +
107
- f"data {market_data[bitvavo_btc_eur_ohlcv_2h.get_identifier()]}"
110
+ f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
108
111
  )
109
112
 
110
113
  if __name__ == "__main__":
@@ -122,19 +125,19 @@ import pathlib
122
125
  from datetime import datetime, timedelta
123
126
  from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY, \
124
127
  TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, pretty_print_backtest, \
125
- CCXTTickerMarketDataSource, BacktestPortfolioConfiguration
128
+ CCXTTickerMarketDataSource, PortfolioConfiguration
126
129
 
127
130
  # Define market data sources
128
131
  bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
129
- identifier="BTC",
130
- market="BITVAVO",
132
+ identifier="BTC-ohlcv",
133
+ market="bitvavo",
131
134
  symbol="BTC/EUR",
132
135
  timeframe="2h",
133
136
  start_date_func=lambda : datetime.utcnow() - timedelta(days=17)
134
137
  )
135
138
  bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
136
- identifier="BTC",
137
- market="BITVAVO",
139
+ identifier="BTC-ticker",
140
+ market="bitvavo",
138
141
  symbol="BTC/EUR",
139
142
  backtest_timeframe="2h" # We want the ticker data to
140
143
  # be sampled every 2 hours, inline with the strategy interval
@@ -142,24 +145,25 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
142
145
  app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
143
146
  app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
144
147
  app.add_market_data_source(bitvavo_btc_eur_ticker)
148
+ app.add_portfolio_configuration(PortfolioConfiguration(
149
+ initial_balance=400,
150
+ market="bitvavo",
151
+ trading_symbol="EUR",
152
+ ))
153
+
145
154
 
146
155
  @app.strategy(
147
156
  time_unit=TimeUnit.HOUR,
148
157
  interval=2,
149
- market_data_sources=[bitvavo_btc_eur_ohlcv_2h]
158
+ market_data_sources=["BTC-ticker", "BTC-ohlcv"]
150
159
  )
151
- def perform_strategy(algorithm: Algorithm, market_data):
160
+ def perform_strategy(algorithm: Algorithm, market_data: dict):
152
161
  print(
153
162
  f"Performing trading strategy on market " +
154
- f"data {market_data[bitvavo_btc_eur_ohlcv_2h.get_identifier()]}"
163
+ f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
155
164
  )
156
165
 
157
166
  if __name__ == "__main__":
158
- app.add_portfolio_configuration(BacktestPortfolioConfiguration(
159
- unallocated=400,
160
- market="BITVAVO",
161
- trading_symbol="EUR",
162
- ))
163
167
  backtest_report = app.backtest(
164
168
  start_date=datetime(2023, 11, 12) - timedelta(days=10),
165
169
  end_date=datetime(2023, 11, 12),
@@ -255,13 +259,20 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
255
259
  This should allow you to connect to a lot of brokers/exchanges.
256
260
 
257
261
  ```python
258
- from investing_algorithm_framework import App, PortfolioConfiguration
262
+ from investing_algorithm_framework import App, PortfolioConfiguration, \
263
+ MarketCredential
259
264
  app = App()
265
+ app.add_market_credential(
266
+ MarketCredential(
267
+ market="<your market>",
268
+ api_key="<your api key>",
269
+ secret_key="<your secret key>",
270
+ )
271
+ )
260
272
  app.add_portfolio_configuration(
261
273
  PortfolioConfiguration(
262
- market="BITVAVO",
263
- api_key="xxxx",
264
- secret_key="xxxx",
274
+ market="<your market>",
275
+ initial_balance=400,
265
276
  track_from="01/01/2022",
266
277
  trading_symbol="EUR"
267
278
  )
@@ -27,12 +27,11 @@ import pathlib
27
27
  from datetime import datetime, timedelta
28
28
  from investing_algorithm_framework import create_app, PortfolioConfiguration, \
29
29
  RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
30
- CCXTTickerMarketDataSource
30
+ CCXTTickerMarketDataSource, MarketCredential
31
31
 
32
32
  # Define market data sources
33
- # OHLCV data
34
33
  bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
35
- identifier="BTC",
34
+ identifier="BTC-ohlcv",
36
35
  market="BITVAVO",
37
36
  symbol="BTC/EUR",
38
37
  timeframe="2h",
@@ -40,19 +39,23 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
40
39
  )
41
40
  # Ticker data for orders, trades and positions
42
41
  bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
43
- identifier="BTC",
42
+ identifier="BTC-ticker",
44
43
  market="BITVAVO",
45
44
  symbol="BTC/EUR",
46
45
  )
47
46
  app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
48
47
  app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
49
48
  app.add_market_data_source(bitvavo_btc_eur_ticker)
49
+ app.add_market_credential(MarketCredential(
50
+ market="bitvavo",
51
+ api_key="<your api key>",
52
+ secret_key="<your secret key>",
53
+ ))
50
54
  app.add_portfolio_configuration(
51
55
  PortfolioConfiguration(
52
- market="BITVAVO",
53
- api_key="<your api key>",
54
- secret_key="<your secret key>",
55
- trading_symbol="EUR"
56
+ market="bitvavo",
57
+ trading_symbol="EUR",
58
+ initial_balance=400
56
59
  )
57
60
  )
58
61
 
@@ -62,12 +65,12 @@ app.add_portfolio_configuration(
62
65
  time_unit=TimeUnit.HOUR,
63
66
  interval=2,
64
67
  # Specify market data sources that need to be passed to the strategy
65
- market_data_sources=[bitvavo_btc_eur_ohlcv_2h, bitvavo_btc_eur_ticker]
68
+ market_data_sources=["BTC-ticker", "BTC-ohlcv"]
66
69
  )
67
- def perform_strategy(algorithm: Algorithm, market_data):
70
+ def perform_strategy(algorithm: Algorithm, market_data: dict):
68
71
  print(
69
72
  f"Performing trading strategy on market " +
70
- f"data {market_data[bitvavo_btc_eur_ohlcv_2h.get_identifier()]}"
73
+ f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
71
74
  )
72
75
 
73
76
  if __name__ == "__main__":
@@ -85,19 +88,19 @@ import pathlib
85
88
  from datetime import datetime, timedelta
86
89
  from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY, \
87
90
  TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, pretty_print_backtest, \
88
- CCXTTickerMarketDataSource, BacktestPortfolioConfiguration
91
+ CCXTTickerMarketDataSource, PortfolioConfiguration
89
92
 
90
93
  # Define market data sources
91
94
  bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
92
- identifier="BTC",
93
- market="BITVAVO",
95
+ identifier="BTC-ohlcv",
96
+ market="bitvavo",
94
97
  symbol="BTC/EUR",
95
98
  timeframe="2h",
96
99
  start_date_func=lambda : datetime.utcnow() - timedelta(days=17)
97
100
  )
98
101
  bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
99
- identifier="BTC",
100
- market="BITVAVO",
102
+ identifier="BTC-ticker",
103
+ market="bitvavo",
101
104
  symbol="BTC/EUR",
102
105
  backtest_timeframe="2h" # We want the ticker data to
103
106
  # be sampled every 2 hours, inline with the strategy interval
@@ -105,24 +108,25 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
105
108
  app = create_app({RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()})
106
109
  app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
107
110
  app.add_market_data_source(bitvavo_btc_eur_ticker)
111
+ app.add_portfolio_configuration(PortfolioConfiguration(
112
+ initial_balance=400,
113
+ market="bitvavo",
114
+ trading_symbol="EUR",
115
+ ))
116
+
108
117
 
109
118
  @app.strategy(
110
119
  time_unit=TimeUnit.HOUR,
111
120
  interval=2,
112
- market_data_sources=[bitvavo_btc_eur_ohlcv_2h]
121
+ market_data_sources=["BTC-ticker", "BTC-ohlcv"]
113
122
  )
114
- def perform_strategy(algorithm: Algorithm, market_data):
123
+ def perform_strategy(algorithm: Algorithm, market_data: dict):
115
124
  print(
116
125
  f"Performing trading strategy on market " +
117
- f"data {market_data[bitvavo_btc_eur_ohlcv_2h.get_identifier()]}"
126
+ f"data {market_data['BTC-ohlcv'] and market_data['BTC-ticker']}"
118
127
  )
119
128
 
120
129
  if __name__ == "__main__":
121
- app.add_portfolio_configuration(BacktestPortfolioConfiguration(
122
- unallocated=400,
123
- market="BITVAVO",
124
- trading_symbol="EUR",
125
- ))
126
130
  backtest_report = app.backtest(
127
131
  start_date=datetime(2023, 11, 12) - timedelta(days=10),
128
132
  end_date=datetime(2023, 11, 12),
@@ -218,13 +222,20 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
218
222
  This should allow you to connect to a lot of brokers/exchanges.
219
223
 
220
224
  ```python
221
- from investing_algorithm_framework import App, PortfolioConfiguration
225
+ from investing_algorithm_framework import App, PortfolioConfiguration, \
226
+ MarketCredential
222
227
  app = App()
228
+ app.add_market_credential(
229
+ MarketCredential(
230
+ market="<your market>",
231
+ api_key="<your api key>",
232
+ secret_key="<your secret key>",
233
+ )
234
+ )
223
235
  app.add_portfolio_configuration(
224
236
  PortfolioConfiguration(
225
- market="BITVAVO",
226
- api_key="xxxx",
227
- secret_key="xxxx",
237
+ market="<your market>",
238
+ initial_balance=400,
228
239
  track_from="01/01/2022",
229
240
  trading_symbol="EUR"
230
241
  )
@@ -1,13 +1,12 @@
1
1
  from investing_algorithm_framework.app import App, Algorithm
2
2
  from .create_app import create_app
3
3
  from investing_algorithm_framework.domain import ApiException, \
4
- TradingDataType, OrderBook, Ticker, TradingTimeFrame, OHLCV, OrderType,\
4
+ TradingDataType, TradingTimeFrame, OrderType,\
5
5
  OrderStatus, OrderSide, Config, TimeUnit, TimeInterval, Order, Portfolio, \
6
- Position, TimeFrame, BACKTESTING_INDEX_DATETIME
7
- from investing_algorithm_framework.domain import PortfolioConfiguration, \
8
- RESOURCE_DIRECTORY, pretty_print_backtest, Trade, OHLCVMarketDataSource, \
9
- OrderBookMarketDataSource, TickerMarketDataSource, \
10
- BacktestPortfolioConfiguration
6
+ Position, TimeFrame, BACKTESTING_INDEX_DATETIME, MarketCredential, \
7
+ PortfolioConfiguration, RESOURCE_DIRECTORY, pretty_print_backtest, \
8
+ Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, \
9
+ TickerMarketDataSource, MarketService
11
10
  from investing_algorithm_framework.app import TradingStrategy, \
12
11
  StatelessAction, Task
13
12
  from investing_algorithm_framework.infrastructure import \
@@ -22,10 +21,7 @@ __all__ = [
22
21
  "create_app",
23
22
  "ApiException",
24
23
  "TradingDataType",
25
- "OrderBook",
26
- "Ticker",
27
24
  "TradingTimeFrame",
28
- "OHLCV",
29
25
  "OrderType",
30
26
  "OrderStatus",
31
27
  "OrderSide",
@@ -49,7 +45,8 @@ __all__ = [
49
45
  "OHLCVMarketDataSource",
50
46
  "OrderBookMarketDataSource",
51
47
  "TickerMarketDataSource",
52
- "BacktestPortfolioConfiguration",
53
48
  "CSVOHLCVMarketDataSource",
54
49
  "CSVTickerMarketDataSource",
50
+ "MarketCredential",
51
+ "MarketService"
55
52
  ]
@@ -1,58 +1,16 @@
1
1
  import logging
2
2
  from typing import List
3
- from queue import Queue
4
3
 
5
4
  from investing_algorithm_framework.domain import OrderStatus, OrderFee, \
6
5
  Position, Order, Portfolio, OrderType, OrderSide, ApiException, \
7
- BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, Trade, \
8
- TickerMarketDataSource, OHLCVMarketDataSource, OrderBookMarketDataSource
6
+ BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, Trade, PeekableQueue, \
7
+ MarketService
8
+ from investing_algorithm_framework.services import MarketCredentialService, \
9
+ MarketDataSourceService
9
10
 
10
11
  logger = logging.getLogger("investing_algorithm_framework")
11
12
 
12
13
 
13
- class PeekableQueue:
14
- def __init__(self):
15
- self.queue = []
16
- self.index = 0
17
-
18
- def enqueue(self, item):
19
- self.queue.append(item)
20
-
21
- def dequeue(self):
22
- if not self.is_empty():
23
- return self.queue.pop(0)
24
- else:
25
- raise IndexError("Queue is empty")
26
-
27
- def peek(self):
28
- if not self.is_empty():
29
- return self.queue[0]
30
- else:
31
- raise IndexError("Queue is empty")
32
-
33
- def is_empty(self):
34
- return len(self.queue) == 0
35
-
36
- def __len__(self):
37
- return len(self.queue)
38
-
39
- def size(self):
40
- return len(self.queue)
41
-
42
- def __iter__(self):
43
- self.index = 0
44
- return self
45
-
46
- def __next__(self):
47
- if self.index < len(self.queue):
48
- result = self.queue[self.index]
49
- self.index += 1
50
- return result
51
- else:
52
- self.index = 0 # Reset index for next iteration
53
- raise StopIteration
54
-
55
-
56
14
  class Algorithm:
57
15
 
58
16
  def __init__(
@@ -64,16 +22,22 @@ class Algorithm:
64
22
  order_service,
65
23
  market_service,
66
24
  strategy_orchestrator_service,
25
+ market_credential_service,
26
+ market_data_source_service
67
27
  ):
68
28
  self.portfolio_service = portfolio_service
69
29
  self.position_service = position_service
70
30
  self.order_service = order_service
71
- self.market_service = market_service
31
+ self._market_service: MarketService = market_service
72
32
  self.configuration_service = configuration_service
73
33
  self.portfolio_configuration_service = portfolio_configuration_service
74
34
  self.strategy_orchestrator_service = strategy_orchestrator_service
75
- self._market_data_sources = []
35
+ self._market_data_sources = {}
76
36
  self._strategies = []
37
+ self._market_credential_service: MarketCredentialService \
38
+ = market_credential_service
39
+ self._market_data_source_service: MarketDataSourceService \
40
+ = market_data_source_service
77
41
 
78
42
  def start(self, number_of_iterations=None, stateless=False):
79
43
 
@@ -95,16 +59,16 @@ class Algorithm:
95
59
  self.strategy_orchestrator_service.run_pending_jobs()
96
60
 
97
61
  def create_order(
98
- self,
99
- target_symbol,
100
- price,
101
- order_type,
102
- order_side,
103
- amount,
104
- market=None,
105
- execute=True,
106
- validate=True,
107
- sync=True
62
+ self,
63
+ target_symbol,
64
+ price,
65
+ order_type,
66
+ order_side,
67
+ amount,
68
+ market=None,
69
+ execute=True,
70
+ validate=True,
71
+ sync=True
108
72
  ):
109
73
  portfolio = self.portfolio_service.find({"market": market})
110
74
  order_data = {
@@ -128,18 +92,18 @@ class Algorithm:
128
92
  )
129
93
 
130
94
  def create_limit_order(
131
- self,
132
- target_symbol,
133
- price,
134
- order_side,
135
- amount=None,
136
- percentage_of_portfolio=None,
137
- percentage_of_position=None,
138
- precision=None,
139
- market=None,
140
- execute=True,
141
- validate=True,
142
- sync=True
95
+ self,
96
+ target_symbol,
97
+ price,
98
+ order_side,
99
+ amount=None,
100
+ percentage_of_portfolio=None,
101
+ percentage_of_position=None,
102
+ precision=None,
103
+ market=None,
104
+ execute=True,
105
+ validate=True,
106
+ sync=True
143
107
  ):
144
108
  portfolio = self.portfolio_service.find({"market": market})
145
109
 
@@ -499,10 +463,6 @@ class Algorithm:
499
463
  portfolio = self.portfolio_service.find(
500
464
  {"market": market, "identifier": identifier}
501
465
  )
502
- portfolio_config = self.portfolio_configuration_service.find(
503
- {"portfolio": portfolio.id}
504
- )
505
- self.market_service.initialize(portfolio_config)
506
466
  position = self.position_service.find(
507
467
  {"portfolio": portfolio.id, "symbol": symbol}
508
468
  )
@@ -520,10 +480,8 @@ class Algorithm:
520
480
  self.order_service.cancel_order(order)
521
481
 
522
482
  symbol = f"{symbol.upper()}/{portfolio.trading_symbol.upper()}"
523
- ticker = self.get_ticker_market_data_source(portfolio.market, symbol)\
524
- .get_data(
525
- backtest_index_date=self.config.get(BACKTESTING_INDEX_DATETIME)
526
- )
483
+ ticker = self._market_data_source_service\
484
+ .get_ticker(market=portfolio.market, symbol=symbol)
527
485
  self.create_limit_order(
528
486
  target_symbol=position.symbol,
529
487
  amount=position.get_amount(),
@@ -722,11 +680,8 @@ class Algorithm:
722
680
 
723
681
  for buy_order in buy_orders:
724
682
  symbol = buy_order.get_symbol()
725
- ticker = self.get_ticker_market_data_source(
726
- portfolio.market, symbol
727
- ).get_data(
728
- backtest_index_date=self.config
729
- .get(BACKTESTING_INDEX_DATETIME)
683
+ ticker = self._market_data_source_service.get_ticker(
684
+ symbol=symbol, market=portfolio.market
730
685
  )
731
686
  trades.append(
732
687
  Trade(
@@ -828,11 +783,8 @@ class Algorithm:
828
783
  symbol = buy_order.get_symbol()
829
784
 
830
785
  try:
831
- ticker = self.get_ticker_market_data_source(
832
- portfolio.market, symbol
833
- ).get_data(
834
- backtest_index_date=self.config
835
- .get(BACKTESTING_INDEX_DATETIME)
786
+ ticker = self._market_data_source_service.get_ticker(
787
+ symbol=symbol, market=portfolio.market
836
788
  )
837
789
  except Exception as e:
838
790
  logger.error(e)
@@ -888,84 +840,11 @@ class Algorithm:
888
840
 
889
841
  symbol = f"{order.get_target_symbol().upper()}" \
890
842
  f"/{order.get_trading_symbol().upper()}"
891
- ticker = self.get_ticker_market_data_source(portfolio.market, symbol)\
892
- .get_data(
893
- backtest_index_date=self.config
894
- .get(BACKTESTING_INDEX_DATETIME)
895
- )
843
+ ticker = self._market_data_source_service\
844
+ .get_ticker(symbol=symbol, market=portfolio.market)
896
845
  self.create_limit_order(
897
846
  target_symbol=order.target_symbol,
898
847
  amount=amount,
899
848
  order_side=OrderSide.SELL.value,
900
849
  price=ticker["bid"],
901
850
  )
902
-
903
- def get_market_data_sources(self):
904
- market_data_sources = []
905
-
906
- for key in self._market_data_sources.keys():
907
- market_data_sources.append(self._market_data_sources[key])
908
-
909
- return market_data_sources
910
-
911
- def get_market_data_source(self, identifier):
912
-
913
- if identifier in self._market_data_sources:
914
- return self._market_data_sources[identifier]
915
-
916
- raise ApiException(
917
- f"No market data source found for with identifier {identifier}."
918
- )
919
-
920
- def set_market_data_sources(self, market_data_sources):
921
- self._market_data_sources = {}
922
-
923
- for market_data_source in market_data_sources:
924
- self._market_data_sources[market_data_source.identifier] = \
925
- market_data_source
926
-
927
- def get_ticker_market_data_source(self, market, symbol):
928
-
929
- for identifier in self._market_data_sources:
930
- market_data_source = self._market_data_sources[identifier]
931
-
932
- if isinstance(market_data_source, TickerMarketDataSource):
933
-
934
- if market_data_source.symbol == symbol \
935
- and market_data_source.market == market:
936
- return market_data_source
937
-
938
- raise ApiException(
939
- f"No ticker market data source found for with symbol {symbol} "
940
- f"and market {market}."
941
- )
942
-
943
- def get_ohlcv_market_data_source(self, market, symbol):
944
-
945
- for market_data_source in self._market_data_sources.values():
946
-
947
- if isinstance(market_data_source, OHLCVMarketDataSource):
948
-
949
- if market_data_source.symbol == symbol \
950
- and market_data_source.market == market:
951
- return market_data_source
952
-
953
- raise ApiException(
954
- f"No OHLCV market data source found for with symbol {symbol} "
955
- f"and market {market}."
956
- )
957
-
958
- def get_order_book_market_data_source(self, market, symbol):
959
-
960
- for market_data_source in self._market_data_sources.values():
961
-
962
- if isinstance(market_data_source, OrderBookMarketDataSource):
963
-
964
- if market_data_source.symbol == symbol \
965
- and market_data_source.market == market:
966
- return market_data_source
967
-
968
- raise ApiException(
969
- f"No OHLCV market data source found for with symbol {symbol} "
970
- f"and market {market}."
971
- )