investing-algorithm-framework 2.0__tar.gz → 2.0.2__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 (136) hide show
  1. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/PKG-INFO +4 -4
  2. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/README.md +3 -3
  3. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/algorithm.py +17 -3
  4. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/services/market_service.py +1 -1
  5. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +2 -2
  6. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/order_service/order_service.py +21 -24
  7. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/portfolio_service/portfolio_service.py +45 -2
  8. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework.egg-info/PKG-INFO +5 -5
  9. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework.egg-info/SOURCES.txt +0 -1
  10. investing_algorithm_framework-2.0/investing_algorithm_framework/services/portfolio_service.py +0 -207
  11. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/AUTHORS.md +0 -0
  12. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/LICENSE +0 -0
  13. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/__init__.py +0 -0
  14. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/__init__.py +0 -0
  15. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/app.py +0 -0
  16. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  17. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  18. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  19. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  20. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  21. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  22. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/strategy.py +0 -0
  23. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/task.py +0 -0
  24. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/__init__.py +0 -0
  25. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  26. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  27. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  28. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  29. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/create_app.py +0 -0
  30. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  31. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/responses.py +0 -0
  32. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  33. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  34. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  35. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  36. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  37. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  38. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/create_app.py +0 -0
  39. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/dependency_container.py +0 -0
  40. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/__init__.py +0 -0
  41. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/config.py +0 -0
  42. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/constants.py +0 -0
  43. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/data_structures.py +0 -0
  44. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  45. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/exceptions.py +0 -0
  46. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/__init__.py +0 -0
  47. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/backtest_profile.py +0 -0
  48. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  49. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
  50. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
  51. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
  52. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/order.py +0 -0
  53. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/order_fee.py +0 -0
  54. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  55. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
  56. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  57. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
  58. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
  59. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
  60. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  61. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  62. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  63. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  64. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  65. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
  66. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  67. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  68. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/trade.py +0 -0
  69. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  70. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  71. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/services/__init__.py +0 -0
  72. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/services/market_data_sources.py +0 -0
  73. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/singleton.py +0 -0
  74. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  75. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/strategy.py +0 -0
  76. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
  77. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/backtesting.py +0 -0
  78. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  79. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/random.py +0 -0
  80. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  81. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  82. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  83. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
  84. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  85. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  86. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
  87. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  88. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  89. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -0
  90. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  91. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
  92. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
  93. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -0
  94. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  95. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
  96. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  97. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  98. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  99. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  100. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
  101. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -0
  102. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  103. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
  104. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  105. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
  106. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  107. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
  108. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
  109. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
  110. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -0
  111. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  112. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  113. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
  114. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/__init__.py +0 -0
  115. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/backtest_service.py +0 -0
  116. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/configuration_service.py +0 -0
  117. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/market_credential_service.py +0 -0
  118. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
  119. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -0
  120. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -0
  121. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
  122. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -0
  123. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/portfolio_configuration_service.py +0 -0
  124. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/portfolio_service/__init__.py +0 -0
  125. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/portfolio_service/backtest_portfolio_service.py +0 -0
  126. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/portfolio_snapshot_service.py +0 -0
  127. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/position_service.py +0 -0
  128. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  129. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/repository_service.py +0 -0
  130. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -0
  131. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework.egg-info/dependency_links.txt +0 -0
  132. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework.egg-info/requires.txt +0 -0
  133. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/investing_algorithm_framework.egg-info/top_level.txt +0 -0
  134. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/setup.cfg +0 -0
  135. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/setup.py +0 -0
  136. {investing_algorithm_framework-2.0 → investing_algorithm_framework-2.0.2}/tests/test_create_app.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing_algorithm_framework
3
- Version: 2.0
3
+ Version: 2.0.2
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
@@ -259,9 +259,9 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
259
259
  This should allow you to connect to a lot of brokers/exchanges.
260
260
 
261
261
  ```python
262
- from investing_algorithm_framework import App, PortfolioConfiguration, \
263
- MarketCredential
264
- app = App()
262
+ from investing_algorithm_framework import PortfolioConfiguration, \
263
+ MarketCredential, create_app
264
+ app = create_app()
265
265
  app.add_market_credential(
266
266
  MarketCredential(
267
267
  market="<your market>",
@@ -222,9 +222,9 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
222
222
  This should allow you to connect to a lot of brokers/exchanges.
223
223
 
224
224
  ```python
225
- from investing_algorithm_framework import App, PortfolioConfiguration, \
226
- MarketCredential
227
- app = App()
225
+ from investing_algorithm_framework import PortfolioConfiguration, \
226
+ MarketCredential, create_app
227
+ app = create_app()
228
228
  app.add_market_credential(
229
229
  MarketCredential(
230
230
  market="<your market>",
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import decimal
2
3
  from typing import List
3
4
 
4
5
  from investing_algorithm_framework.domain import OrderStatus, OrderFee, \
@@ -718,9 +719,22 @@ class Algorithm:
718
719
  if order.get_trade_closed_at() is not None
719
720
  ]
720
721
 
721
- def round_down(self, value, decimals):
722
- factor = 1 / (10 ** decimals)
723
- return (value // factor) * factor
722
+ def round_down(self, value, amount_of_decimals):
723
+
724
+ if self.count_decimals(value) <= amount_of_decimals:
725
+ return value
726
+
727
+ with decimal.localcontext() as ctx:
728
+ d = decimal.Decimal(value)
729
+ ctx.rounding = decimal.ROUND_DOWN
730
+ return float(round(d, amount_of_decimals))
731
+
732
+ def count_decimals(self, number):
733
+ decimal_str = str(number)
734
+ if '.' in decimal_str:
735
+ return len(decimal_str.split('.')[1])
736
+ else:
737
+ return 0
724
738
 
725
739
  def get_open_trades(self, target_symbol=None):
726
740
  portfolios = self.portfolio_service.get_all()
@@ -123,7 +123,7 @@ class MarketService(ABC):
123
123
  return None
124
124
 
125
125
  for market_data_credentials in self.market_credentials:
126
- if market_data_credentials.market == market:
126
+ if market_data_credentials.market.lower() == market.lower():
127
127
  return market_data_credentials
128
128
 
129
129
  return None
@@ -405,8 +405,8 @@ class CCXTTickerBacktestMarketDataSource(
405
405
 
406
406
  class CCXTOHLCVMarketDataSource(OHLCVMarketDataSource):
407
407
 
408
- def get_data(self, **kwargs):
409
- market_service = CCXTMarketService(None)
408
+ def get_data(self, market_credential_service, **kwargs):
409
+ market_service = CCXTMarketService(market_credential_service)
410
410
 
411
411
  if self.start_date is None:
412
412
  raise OperationalException(
@@ -153,7 +153,7 @@ class OrderService(RepositoryService):
153
153
  if OrderType.LIMIT.equals(order.get_order_type()):
154
154
 
155
155
  if OrderSide.BUY.equals(order.get_order_side()):
156
- self.market_service.create_limit_buy_order(
156
+ external_order = self.market_service.create_limit_buy_order(
157
157
  target_symbol=order.get_target_symbol(),
158
158
  trading_symbol=order.get_trading_symbol(),
159
159
  amount=order.get_amount(),
@@ -161,33 +161,30 @@ class OrderService(RepositoryService):
161
161
  market=portfolio.get_market()
162
162
  )
163
163
  else:
164
- self.market_service.create_limit_sell_order(
165
- target_symbol=order.get_target_symbol(),
166
- trading_symbol=order.get_trading_symbol(),
167
- amount=order.get_amount(),
168
- price=order.get_price(),
169
- market=portfolio.get_market()
170
- )
164
+ external_order = self.market_service\
165
+ .create_limit_sell_order(
166
+ target_symbol=order.get_target_symbol(),
167
+ trading_symbol=order.get_trading_symbol(),
168
+ amount=order.get_amount(),
169
+ price=order.get_price(),
170
+ market=portfolio.get_market()
171
+ )
171
172
  else:
172
173
  if OrderSide.BUY.equals(order.get_order_side()):
173
174
  raise OperationalException("Market buy order not supported")
174
175
  else:
175
- self.market_service.create_market_sell_order(
176
- target_symbol=order.get_target_symbol(),
177
- trading_symbol=order.get_trading_symbol(),
178
- amount=order.get_amount(),
179
- market=portfolio.get_market()
180
- )
181
-
182
- order = self.update(
183
- order_id,
184
- {
185
- "status": OrderStatus.OPEN.value,
186
- "remaining": order.remaining,
187
- "updated_at": datetime.now()
188
- }
189
- )
190
- return order
176
+ external_order = self.market_service\
177
+ .create_market_sell_order(
178
+ target_symbol=order.get_target_symbol(),
179
+ trading_symbol=order.get_trading_symbol(),
180
+ amount=order.get_amount(),
181
+ market=portfolio.get_market()
182
+ )
183
+
184
+ data = external_order.to_dict()
185
+ data["status"] = OrderStatus.OPEN.value
186
+ data["updated_at"] = datetime.now()
187
+ return self.update(order_id, data)
191
188
  except Exception as e:
192
189
  logger.error("Error executing order: {}".format(e))
193
190
  return self.update(
@@ -99,7 +99,6 @@ class PortfolioService(RepositoryService):
99
99
  }
100
100
  )
101
101
 
102
-
103
102
  for position in self.position_repository.get_all(
104
103
  {"portfolio_id": portfolio.id}
105
104
  ):
@@ -168,9 +167,11 @@ class PortfolioService(RepositoryService):
168
167
  if self.repository.exists(
169
168
  {"identifier": portfolio_configuration.identifier}
170
169
  ):
171
- return self.repository.find(
170
+ portfolio = self.repository.find(
172
171
  {"identifier": portfolio_configuration.identifier}
173
172
  )
173
+ self.sync_portfolio(portfolio, portfolio_configuration)
174
+ return portfolio
174
175
 
175
176
  balances = self.market_service\
176
177
  .get_balance(market=portfolio_configuration.market)
@@ -185,6 +186,19 @@ class PortfolioService(RepositoryService):
185
186
  balances[portfolio_configuration.trading_symbol.upper()]
186
187
  ["free"]
187
188
  )
189
+
190
+ if portfolio_configuration.initial_balance is not None and \
191
+ unallocated < portfolio_configuration.initial_balance:
192
+ raise OperationalException(
193
+ f"Insufficient balance on market "
194
+ f"{portfolio_configuration.market} "
195
+ f"for trading symbol "
196
+ f"{portfolio_configuration.trading_symbol}. "
197
+ f"Portfolio configuration initial balance: "
198
+ f"{portfolio_configuration.initial_balance} "
199
+ f"Available balance: {unallocated}"
200
+ )
201
+
188
202
  creation_data = {
189
203
  "unallocated": unallocated,
190
204
  "identifier": portfolio_configuration.identifier,
@@ -202,3 +216,32 @@ class PortfolioService(RepositoryService):
202
216
  }
203
217
  )
204
218
  self.create_snapshot(portfolio.id, created_at=portfolio.created_at)
219
+
220
+ def sync_portfolio(self, portfolio, portfolio_configuration):
221
+ balances = self.market_service \
222
+ .get_balance(market=portfolio_configuration.market)
223
+
224
+ if portfolio_configuration.trading_symbol.upper() not in balances:
225
+ raise OperationalException(
226
+ f"Trading symbol balance not available "
227
+ f"in portfolio on market {portfolio_configuration.market}"
228
+ )
229
+
230
+ unallocated = float(
231
+ balances[portfolio_configuration.trading_symbol.upper()]
232
+ ["free"]
233
+ )
234
+
235
+ if unallocated < portfolio.unallocated:
236
+ raise OperationalException(
237
+ "There seems to be a mismatch between the portfolio of this "
238
+ "algorithm and the portfolio on the exchange. "
239
+ f"Please make sure that the available "
240
+ f"{portfolio.trading_symbol} "
241
+ f"of your portfolio on the market {portfolio.market} "
242
+ "matches the portfolio of this algorithm."
243
+ f"Current portfolio: {portfolio.unallocated} "
244
+ f"{portfolio.trading_symbol}"
245
+ f"Available on market: {unallocated} "
246
+ f"{portfolio.trading_symbol}"
247
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
- Name: investing-algorithm-framework
3
- Version: 2.0
2
+ Name: investing_algorithm_framework
3
+ Version: 2.0.2
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
@@ -259,9 +259,9 @@ The framework has by default support for [ccxt](https://github.com/ccxt/ccxt).
259
259
  This should allow you to connect to a lot of brokers/exchanges.
260
260
 
261
261
  ```python
262
- from investing_algorithm_framework import App, PortfolioConfiguration, \
263
- MarketCredential
264
- app = App()
262
+ from investing_algorithm_framework import PortfolioConfiguration, \
263
+ MarketCredential, create_app
264
+ app = create_app()
265
265
  app.add_market_credential(
266
266
  MarketCredential(
267
267
  market="<your market>",
@@ -117,7 +117,6 @@ investing_algorithm_framework/services/backtest_service.py
117
117
  investing_algorithm_framework/services/configuration_service.py
118
118
  investing_algorithm_framework/services/market_credential_service.py
119
119
  investing_algorithm_framework/services/portfolio_configuration_service.py
120
- investing_algorithm_framework/services/portfolio_service.py
121
120
  investing_algorithm_framework/services/portfolio_snapshot_service.py
122
121
  investing_algorithm_framework/services/position_service.py
123
122
  investing_algorithm_framework/services/position_snapshot_service.py
@@ -1,207 +0,0 @@
1
- import logging
2
- from datetime import datetime
3
-
4
- from investing_algorithm_framework.domain import OrderSide, OrderStatus, \
5
- OperationalException, MarketService
6
- from investing_algorithm_framework.services.repository_service \
7
- import RepositoryService
8
-
9
- logger = logging.getLogger("investing_algorithm_framework")
10
-
11
-
12
- class PortfolioService(RepositoryService):
13
-
14
- def __init__(
15
- self,
16
- market_service: MarketService,
17
- market_credential_service,
18
- position_repository,
19
- order_service,
20
- portfolio_repository,
21
- portfolio_configuration_service,
22
- portfolio_snapshot_service,
23
- ):
24
- self.market_service = market_service
25
- self.position_repository = position_repository
26
- self.portfolio_configuration_service = portfolio_configuration_service
27
- self.order_service = order_service
28
- self.portfolio_snapshot_service = portfolio_snapshot_service
29
- self.market_credentials_service = market_credential_service
30
- super(PortfolioService, self).__init__(portfolio_repository)
31
-
32
- def find(self, query_params):
33
- portfolio = self.repository.find(query_params)
34
- portfolio_configuration = self.portfolio_configuration_service\
35
- .get(portfolio.identifier)
36
- portfolio.configuration = portfolio_configuration
37
- return portfolio
38
-
39
- def create(self, data):
40
- unallocated = data.get("unallocated", 0)
41
- portfolio = super(PortfolioService, self).create(data)
42
- self.position_repository.create(
43
- {
44
- "symbol": portfolio.get_trading_symbol(),
45
- "amount": unallocated,
46
- "portfolio_id": portfolio.id,
47
- "cost": unallocated
48
- }
49
- )
50
- self.create_snapshot(portfolio.id, created_at=portfolio.created_at)
51
- return portfolio
52
-
53
- def sync_portfolios(self):
54
-
55
- for portfolio in self.get_all():
56
- portfolio_configuration = self.portfolio_configuration_service\
57
- .get(portfolio.identifier)
58
-
59
- self.market_service.market_data_credentials = \
60
- self.market_credentials_service.get_all()
61
- balances = self.market_service.get_balance(portfolio.market)
62
-
63
- for symbol in balances["free"]:
64
- balance = balances["free"][symbol]
65
- logger.info(f"Syncing {symbol} balance")
66
-
67
- if self.position_repository.exists(
68
- {"portfolio_id": portfolio.id, "symbol": symbol}
69
- ):
70
- position = self.position_repository.find(
71
- {
72
- "portfolio_id": portfolio.id,
73
- "symbol": symbol
74
- }
75
- )
76
- self.position_repository.update(
77
- position.id,
78
- {"amount": balance}
79
- )
80
- else:
81
- self.position_repository.create(
82
- {
83
- "symbol": symbol,
84
- "amount": balance,
85
- "portfolio_id": portfolio.id
86
- }
87
- )
88
-
89
- if symbol == portfolio.trading_symbol:
90
- if portfolio.unallocated != balance:
91
- logger.info(
92
- "Updating unallocated balance "
93
- f"from {portfolio.unallocated} "
94
- f"to {balance}"
95
- )
96
- difference = balance - portfolio.get_unallocated()
97
- self.update(
98
- portfolio.id,
99
- {
100
- "unallocated": portfolio.get_unallocated() + difference,
101
- "net_size": portfolio.get_net_size() + difference
102
- }
103
- )
104
-
105
-
106
- for position in self.position_repository.get_all(
107
- {"portfolio_id": portfolio.id}
108
- ):
109
- if position.symbol == portfolio.trading_symbol:
110
- continue
111
-
112
- logger.info(f"Syncing {position.symbol} orders")
113
-
114
- external_orders = self.market_service\
115
- .get_orders(
116
- f"{position.symbol}/{portfolio.trading_symbol}",
117
- since=portfolio_configuration.track_from,
118
- market=portfolio.market
119
- )
120
-
121
- logger.info(
122
- f"Found {len(external_orders)} external orders "
123
- f"for position {position.symbol}"
124
- )
125
-
126
- for external_order in external_orders:
127
-
128
- if self.order_service.exists(
129
- {"external_id": external_order.external_id}
130
- ):
131
- logger.info("Updating existing order")
132
- order = self.order_service.find(
133
- {"external_id": external_order.external_id}
134
- )
135
- self.order_service.update(
136
- order.id, external_order.to_dict()
137
- )
138
- else:
139
- logger.info(
140
- "Creating new order based on external order"
141
- )
142
- data = external_order.to_dict()
143
- data["position_id"] = position.id
144
- data["portfolio_id"] = portfolio.id
145
- self.order_service.create(
146
- data, execute=False, validate=False, sync=False
147
- )
148
-
149
- def create_snapshot(self, portfolio_id, created_at=None):
150
-
151
- if created_at is None:
152
- created_at = datetime.utcnow()
153
-
154
- portfolio = self.get(portfolio_id)
155
- pending_orders = self.order_service.get_all(
156
- {
157
- "order_side": OrderSide.BUY.value,
158
- "status": OrderStatus.OPEN.value,
159
- "portfolio_id": portfolio.id
160
- }
161
- )
162
- return self.portfolio_snapshot_service.create_snapshot(
163
- portfolio,
164
- pending_orders=pending_orders,
165
- created_at=created_at
166
- )
167
-
168
- def create_portfolio_from_configuration(self, portfolio_configuration):
169
- logger.info("Creating portfolios")
170
-
171
- if self.repository.exists(
172
- {"identifier": portfolio_configuration.identifier}
173
- ):
174
- return self.repository.find(
175
- {"identifier": portfolio_configuration.identifier}
176
- )
177
-
178
- balances = self.market_service\
179
- .get_balance(market=portfolio_configuration.market)
180
-
181
- if portfolio_configuration.trading_symbol.upper() not in balances:
182
- raise OperationalException(
183
- f"Trading symbol balance not available "
184
- f"in portfolio on market {portfolio_configuration.market}"
185
- )
186
-
187
- unallocated = float(
188
- balances[portfolio_configuration.trading_symbol.upper()]
189
- ["free"]
190
- )
191
- creation_data = {
192
- "unallocated": unallocated,
193
- "identifier": portfolio_configuration.identifier,
194
- "trading_symbol": portfolio_configuration.trading_symbol.upper(),
195
- "market": portfolio_configuration.market.upper(),
196
- }
197
-
198
- portfolio = self.repository.create(creation_data)
199
- self.position_repository.create(
200
- {
201
- "symbol": portfolio.get_trading_symbol(),
202
- "amount": unallocated,
203
- "portfolio_id": portfolio.id,
204
- "cost": unallocated
205
- }
206
- )
207
- self.create_snapshot(portfolio.id, created_at=portfolio.created_at)