investing-algorithm-framework 3.5.2__tar.gz → 3.6.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 (146) hide show
  1. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/PKG-INFO +1 -1
  2. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/__init__.py +4 -1
  3. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/algorithm.py +47 -7
  4. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/app.py +17 -9
  5. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/dependency_container.py +1 -3
  6. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/__init__.py +5 -3
  7. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/__init__.py +4 -4
  8. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/backtesting/__init__.py +2 -0
  9. investing_algorithm_framework-3.6.0/investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +26 -0
  10. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +14 -0
  11. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +35 -17
  12. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/order/__init__.py +1 -2
  13. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/order/order.py +71 -24
  14. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/trade/trade.py +17 -0
  15. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/__init__.py +2 -1
  16. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/backtesting.py +23 -3
  17. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/__init__.py +2 -4
  18. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/__init__.py +1 -2
  19. investing_algorithm_framework-3.6.0/investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +47 -0
  20. investing_algorithm_framework-3.6.0/investing_algorithm_framework/infrastructure/models/order/__init__.py +3 -0
  21. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/order/order.py +21 -8
  22. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -2
  23. investing_algorithm_framework-3.6.0/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +75 -0
  24. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/backtesting/backtest_service.py +4 -1
  25. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -2
  26. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/order_service/order_service.py +0 -28
  27. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/pyproject.toml +1 -1
  28. investing_algorithm_framework-3.5.2/investing_algorithm_framework/domain/models/order/order_fee.py +0 -49
  29. investing_algorithm_framework-3.5.2/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -4
  30. investing_algorithm_framework-3.5.2/investing_algorithm_framework/infrastructure/models/order/order_fee.py +0 -21
  31. investing_algorithm_framework-3.5.2/investing_algorithm_framework/infrastructure/repositories/order_fee_repository.py +0 -15
  32. investing_algorithm_framework-3.5.2/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -42
  33. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/LICENSE +0 -0
  34. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/README.md +0 -0
  35. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/__init__.py +0 -0
  36. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
  37. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
  38. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
  39. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
  40. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
  41. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
  42. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/strategy.py +0 -0
  43. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/task.py +0 -0
  44. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
  45. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
  46. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
  47. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
  48. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
  49. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
  50. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
  51. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/responses.py +0 -0
  52. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
  53. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
  54. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
  55. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
  56. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
  57. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
  58. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/create_app.py +0 -0
  59. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/config.py +0 -0
  60. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/constants.py +0 -0
  61. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/data_structures.py +0 -0
  62. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
  63. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
  64. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
  65. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
  66. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
  67. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
  68. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
  69. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
  70. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
  71. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
  72. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
  73. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
  74. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
  75. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
  76. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
  77. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
  78. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
  79. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
  80. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
  81. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
  82. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
  83. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
  84. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
  85. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
  86. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
  87. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/__init__.py +0 -0
  88. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
  89. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/market_data_sources.py +0 -0
  90. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/market_service.py +0 -0
  91. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
  92. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
  93. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
  94. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/singleton.py +0 -0
  95. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
  96. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/strategy.py +0 -0
  97. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
  98. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
  99. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
  100. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
  101. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
  102. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
  103. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
  104. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
  105. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
  106. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -0
  107. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -0
  108. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
  109. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
  110. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
  111. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
  112. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
  113. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
  114. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
  115. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
  116. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
  117. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
  118. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
  119. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
  120. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
  121. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
  122. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
  123. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -0
  124. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
  125. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
  126. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
  127. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/__init__.py +0 -0
  128. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
  129. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/configuration_service.py +0 -0
  130. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/market_credential_service.py +0 -0
  131. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
  132. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -0
  133. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -0
  134. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
  135. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
  136. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
  137. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
  138. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
  139. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
  140. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
  141. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/position_service.py +0 -0
  142. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
  143. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/repository_service.py +0 -0
  144. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -0
  145. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
  146. {investing_algorithm_framework-3.5.2 → investing_algorithm_framework-3.6.0}/investing_algorithm_framework/services/trade_service/trade_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing-algorithm-framework
3
- Version: 3.5.2
3
+ Version: 3.6.0
4
4
  Summary: A framework for creating trading bots
5
5
  Author: MDUYN
6
6
  Requires-Python: >=3.8.1,<4.0.0
@@ -9,7 +9,8 @@ from investing_algorithm_framework.domain import ApiException, \
9
9
  Trade, OHLCVMarketDataSource, OrderBookMarketDataSource, SYMBOLS, \
10
10
  TickerMarketDataSource, MarketService, BacktestReportsEvaluation, \
11
11
  pretty_print_backtest_reports_evaluation, load_backtest_reports, \
12
- RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT
12
+ RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
13
+ load_backtest_report, BacktestDateRange
13
14
  from investing_algorithm_framework.infrastructure import \
14
15
  CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
15
16
  CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
@@ -61,4 +62,6 @@ __all__ = [
61
62
  "APP_MODE",
62
63
  "AppMode",
63
64
  "DATETIME_FORMAT",
65
+ "load_backtest_report",
66
+ "BacktestDateRange",
64
67
  ]
@@ -1,8 +1,8 @@
1
1
  import inspect
2
2
  import logging
3
- from typing import List
3
+ from typing import List, Dict
4
4
 
5
- from investing_algorithm_framework.domain import OrderStatus, OrderFee, \
5
+ from investing_algorithm_framework.domain import OrderStatus, \
6
6
  Position, Order, Portfolio, OrderType, OrderSide, \
7
7
  BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, MarketService, TimeUnit, \
8
8
  OperationalException, random_string, RoundingService
@@ -16,8 +16,22 @@ logger = logging.getLogger("investing_algorithm_framework")
16
16
 
17
17
 
18
18
  class Algorithm:
19
-
20
- def __init__(self, name=None, description=None):
19
+ """
20
+ Class to represent an algorithm. An algorithm is a collection of
21
+ strategies that are executed in a specific order. The algorithm
22
+ class is responsible for managing the strategies and executing
23
+ them in the correct order.
24
+
25
+ :param name: The name of the algorithm
26
+ :param description: The description of the algorithm
27
+ :param context: The context of the algorithm, for backtest references
28
+ """
29
+ def __init__(
30
+ self,
31
+ name: str = None,
32
+ description: str = None,
33
+ context: Dict[str, str] = None
34
+ ):
21
35
  self._name = name
22
36
 
23
37
  if name is None:
@@ -28,6 +42,21 @@ class Algorithm:
28
42
  if description is not None:
29
43
  self._description = description
30
44
 
45
+ self._context = context
46
+
47
+ if self.context is None:
48
+ self._context = {}
49
+
50
+ # Check if the context is a dictionary with only string,
51
+ # float or int values
52
+ for key, value in self.context.items():
53
+ if not isinstance(key, str) or \
54
+ not isinstance(value, (str, float, int)):
55
+ raise OperationalException(
56
+ "The context of the algorithm must be a dictionary with "
57
+ "only string, float or int values."
58
+ )
59
+
31
60
  self._strategies = []
32
61
  self._tasks = []
33
62
  self.portfolio_service: PortfolioService
@@ -108,6 +137,20 @@ class Algorithm:
108
137
  """
109
138
  return self.configuration_service.config
110
139
 
140
+ @property
141
+ def description(self):
142
+ """
143
+ Function to get the description of the algorithm
144
+ """
145
+ return self._description
146
+
147
+ @property
148
+ def context(self):
149
+ """
150
+ Function to get the context of the algorithm
151
+ """
152
+ return self._context
153
+
111
154
  @property
112
155
  def running(self) -> bool:
113
156
  """
@@ -362,9 +405,6 @@ class Algorithm:
362
405
  }
363
406
  )
364
407
 
365
- def get_order_fee(self, order_id) -> OrderFee:
366
- return self.order_service.get_order_fee(order_id)
367
-
368
408
  def get_positions(
369
409
  self,
370
410
  market=None,
@@ -7,7 +7,7 @@ from abc import abstractmethod
7
7
  from datetime import datetime
8
8
  from distutils.sysconfig import get_python_lib
9
9
  from time import sleep
10
- from typing import List, Optional, Tuple
10
+ from typing import List, Optional
11
11
 
12
12
  from flask import Flask
13
13
 
@@ -20,7 +20,7 @@ from investing_algorithm_framework.domain import DATABASE_NAME, TimeUnit, \
20
20
  SQLALCHEMY_DATABASE_URI, OperationalException, BACKTESTING_FLAG, \
21
21
  BACKTESTING_START_DATE, BACKTESTING_END_DATE, BacktestReport, \
22
22
  BACKTESTING_PENDING_ORDER_CHECK_INTERVAL, APP_MODE, MarketCredential, \
23
- AppMode
23
+ AppMode, BacktestDateRange
24
24
  from investing_algorithm_framework.infrastructure import setup_sqlalchemy, \
25
25
  create_all_tables
26
26
  from investing_algorithm_framework.services import OrderBacktestService, \
@@ -319,7 +319,6 @@ class App:
319
319
  self.container.order_service.override(
320
320
  OrderBacktestService(
321
321
  order_repository=self.container.order_repository(),
322
- order_fee_repository=self.container.order_fee_repository(),
323
322
  position_repository=self.container.position_repository(),
324
323
  portfolio_repository=self.container.portfolio_repository(),
325
324
  portfolio_configuration_service=self.container
@@ -729,7 +728,7 @@ class App:
729
728
  "backtest_reports"
730
729
  )
731
730
 
732
- backtest_report_writer_service.write_report_to_csv(
731
+ backtest_report_writer_service.write_report_to_json(
733
732
  report=report, output_directory=output_directory
734
733
  )
735
734
 
@@ -740,7 +739,7 @@ class App:
740
739
  algorithms,
741
740
  start_date: Optional[datetime] = None,
742
741
  end_date: Optional[datetime] = None,
743
- date_ranges: Optional[Tuple[datetime, datetime]] = None,
742
+ date_ranges: Optional[List[BacktestDateRange]] = None,
744
743
  pending_order_check_interval=None,
745
744
  output_directory=None
746
745
  ) -> List[BacktestReport]:
@@ -754,7 +753,7 @@ class App:
754
753
  :param end_date: The end date of the backtest
755
754
  :param pending_order_check_interval: The interval at which to check
756
755
  :param date_ranges: The date ranges to run the backtests for (list of
757
- tuples of start and end dates)
756
+ BacktestDateRange instances representing a start and end date)
758
757
  pending orders
759
758
  :param output_directory: The directory to write the backtest report to
760
759
  :return: List of BacktestReport intances
@@ -767,7 +766,9 @@ class App:
767
766
  if end_date is None:
768
767
  end_date = datetime.utcnow()
769
768
 
770
- date_ranges = [(start_date, end_date)]
769
+ date_ranges = [
770
+ BacktestDateRange(start_date=start_date, end_date=end_date)
771
+ ]
771
772
  else:
772
773
  if date_ranges is None:
773
774
  raise OperationalException("No date ranges specified")
@@ -776,7 +777,9 @@ class App:
776
777
  .get_market_data_sources()
777
778
 
778
779
  for date_range in date_ranges:
779
- start_date, end_date = date_range
780
+ date_range: BacktestDateRange = date_range
781
+ start_date = date_range.start_date
782
+ end_date = date_range.end_date
780
783
  self._initialize_app_for_backtest(
781
784
  backtest_start_date=start_date,
782
785
  backtest_end_date=end_date,
@@ -804,6 +807,11 @@ class App:
804
807
  start_date=start_date,
805
808
  end_date=end_date
806
809
  )
810
+
811
+ # Add date range name to report if present
812
+ if date_range.name is not None:
813
+ report.date_range_name = date_range.name
814
+
807
815
  backtest_report_writer_service = self.container \
808
816
  .backtest_report_writer_service()
809
817
 
@@ -813,7 +821,7 @@ class App:
813
821
  "backtest_reports"
814
822
  )
815
823
 
816
- backtest_report_writer_service.write_report_to_csv(
824
+ backtest_report_writer_service.write_report_to_json(
817
825
  report=report, output_directory=output_directory
818
826
  )
819
827
  reports.append(report)
@@ -3,7 +3,7 @@ from dependency_injector import containers, providers
3
3
  from investing_algorithm_framework.app.algorithm import Algorithm
4
4
  from investing_algorithm_framework.infrastructure import SQLOrderRepository, \
5
5
  SQLPositionRepository, SQLPortfolioRepository, \
6
- SQLOrderFeeRepository, SQLPortfolioSnapshotRepository, \
6
+ SQLPortfolioSnapshotRepository, \
7
7
  SQLPositionSnapshotRepository, PerformanceService, CCXTMarketService
8
8
  from investing_algorithm_framework.services import OrderService, \
9
9
  PositionService, PortfolioService, StrategyOrchestratorService, \
@@ -33,7 +33,6 @@ class DependencyContainer(containers.DeclarativeContainer):
33
33
  MarketCredentialService
34
34
  )
35
35
  order_repository = providers.Factory(SQLOrderRepository)
36
- order_fee_repository = providers.Factory(SQLOrderFeeRepository)
37
36
  position_repository = providers.Factory(SQLPositionRepository)
38
37
  portfolio_repository = providers.Factory(SQLPortfolioRepository)
39
38
  position_snapshot_repository = providers.Factory(
@@ -70,7 +69,6 @@ class DependencyContainer(containers.DeclarativeContainer):
70
69
  OrderService,
71
70
  configuration_service=configuration_service,
72
71
  order_repository=order_repository,
73
- order_fee_repository=order_fee_repository,
74
72
  portfolio_repository=portfolio_repository,
75
73
  position_repository=position_repository,
76
74
  market_service=market_service,
@@ -15,9 +15,9 @@ from .exceptions import OperationalException, ApiException, \
15
15
  from .models import OrderStatus, OrderSide, OrderType, TimeInterval, \
16
16
  TimeUnit, TimeFrame, TradingTimeFrame, TradingDataType, \
17
17
  PortfolioConfiguration, Portfolio, Position, Order, TradeStatus, \
18
- OrderFee, BacktestReport, PortfolioSnapshot, StrategyProfile, \
18
+ BacktestReport, PortfolioSnapshot, StrategyProfile, \
19
19
  BacktestPosition, Trade, MarketCredential, PositionSnapshot, \
20
- BacktestReportsEvaluation, AppMode
20
+ BacktestReportsEvaluation, AppMode, BacktestDateRange
21
21
  from .services import TickerMarketDataSource, OrderBookMarketDataSource, \
22
22
  OHLCVMarketDataSource, BacktestMarketDataSource, MarketDataSource, \
23
23
  MarketService, MarketCredentialService, AbstractPortfolioSyncService, \
@@ -27,6 +27,7 @@ from .stateless_actions import StatelessActions
27
27
  from .strategy import Strategy
28
28
  from .utils import random_string, append_dict_as_row_to_csv, \
29
29
  add_column_headers_to_csv, get_total_amount_of_rows, \
30
+ load_backtest_report, \
30
31
  csv_to_list, StoppableThread, pretty_print_backtest_reports_evaluation, \
31
32
  pretty_print_backtest, load_csv_into_dict, load_backtest_reports
32
33
 
@@ -70,7 +71,6 @@ __all__ = [
70
71
  "Strategy",
71
72
  "DATETIME_FORMAT",
72
73
  "StatelessActions",
73
- "OrderFee",
74
74
  "parse_decimal_to_string",
75
75
  "parse_string_to_decimal",
76
76
  "BacktestReport",
@@ -112,4 +112,6 @@ __all__ = [
112
112
  "APP_MODE",
113
113
  "AppMode",
114
114
  "RoundingService",
115
+ "BacktestDateRange",
116
+ "load_backtest_report",
115
117
  ]
@@ -1,8 +1,8 @@
1
1
  from .app_mode import AppMode
2
2
  from .backtesting import BacktestReport, BacktestPosition, \
3
- BacktestReportsEvaluation
3
+ BacktestReportsEvaluation, BacktestDateRange
4
4
  from .market import MarketCredential
5
- from .order import OrderStatus, OrderSide, OrderType, Order, OrderFee
5
+ from .order import OrderStatus, OrderSide, OrderType, Order
6
6
  from .portfolio import PortfolioConfiguration, Portfolio, PortfolioSnapshot
7
7
  from .position import Position, PositionSnapshot
8
8
  from .strategy_profile import StrategyProfile
@@ -26,7 +26,6 @@ __all__ = [
26
26
  "PortfolioConfiguration",
27
27
  "Position",
28
28
  "Portfolio",
29
- "OrderFee",
30
29
  "BacktestReport",
31
30
  "PositionSnapshot",
32
31
  "PortfolioSnapshot",
@@ -36,5 +35,6 @@ __all__ = [
36
35
  "MarketCredential",
37
36
  "TradeStatus",
38
37
  "BacktestReportsEvaluation",
39
- "AppMode"
38
+ "AppMode",
39
+ "BacktestDateRange"
40
40
  ]
@@ -1,9 +1,11 @@
1
1
  from .backtest_position import BacktestPosition
2
2
  from .backtest_report import BacktestReport
3
3
  from .backtest_reports_evaluation import BacktestReportsEvaluation
4
+ from .backtest_date_range import BacktestDateRange
4
5
 
5
6
  __all__ = [
6
7
  "BacktestReport",
7
8
  "BacktestPosition",
8
9
  "BacktestReportsEvaluation",
10
+ "BacktestDateRange"
9
11
  ]
@@ -0,0 +1,26 @@
1
+ from datetime import datetime
2
+
3
+
4
+ class BacktestDateRange:
5
+ """
6
+ Represents a date range for a backtest
7
+ """
8
+ def __init__(self, start_date, end_date=None, name=None):
9
+ self._start_date = start_date
10
+ self._end_date = end_date
11
+ self._name = name
12
+
13
+ if end_date is None:
14
+ self._end_date = datetime.now()
15
+
16
+ @property
17
+ def start_date(self):
18
+ return self._start_date
19
+
20
+ @property
21
+ def end_date(self):
22
+ return self._end_date
23
+
24
+ @property
25
+ def name(self):
26
+ return self._name
@@ -104,3 +104,17 @@ class BacktestPosition(BaseModel):
104
104
  return 0.0
105
105
 
106
106
  return self.value / self._total_value_portfolio * 100
107
+
108
+ def to_dict(self):
109
+ return {
110
+ "symbol": self.symbol,
111
+ "amount": self.amount,
112
+ "cost": self.cost,
113
+ "price": self.price,
114
+ "value": self.value,
115
+ "growth": self.growth,
116
+ "growth_rate": self.growth_rate,
117
+ "amount_pending_buy": self.amount_pending_buy,
118
+ "amount_pending_sell": self.amount_pending_sell,
119
+ "percentage_of_portfolio": self.percentage_of_portfolio
120
+ }
@@ -2,6 +2,7 @@ from datetime import datetime
2
2
 
3
3
  from investing_algorithm_framework.domain.models.base_model import BaseModel
4
4
  from investing_algorithm_framework.domain.models.time_unit import TimeUnit
5
+ from investing_algorithm_framework.domain.constants import DATETIME_FORMAT
5
6
 
6
7
 
7
8
  class BacktestReport(BaseModel):
@@ -18,7 +19,6 @@ class BacktestReport(BaseModel):
18
19
  backtest_data_index_date=None,
19
20
  backtest_start_date=None,
20
21
  backtest_end_date=None,
21
- backtest_index_date=None,
22
22
  trading_time_frame=None,
23
23
  trading_time_frame_start_date=None,
24
24
  symbols=None,
@@ -42,14 +42,15 @@ class BacktestReport(BaseModel):
42
42
  average_trade_duration=0,
43
43
  average_trade_size=0.0,
44
44
  trades=None,
45
- created_at: datetime = None
45
+ orders=None,
46
+ created_at: datetime = None,
47
+ context=None,
46
48
  ):
47
49
  self._name = name
48
50
  self._strategy_identifiers = strategy_identifiers
49
51
  self._backtest_start_date_data = backtest_start_date_data
50
52
  self._backtest_start_date = backtest_start_date
51
53
  self._backtest_end_date = backtest_end_date
52
- self._backtest_index_date = backtest_index_date
53
54
  self._number_of_runs = number_of_runs
54
55
  self._trading_time_frame = trading_time_frame
55
56
  self._trading_time_frame_start_date = trading_time_frame_start_date
@@ -72,13 +73,15 @@ class BacktestReport(BaseModel):
72
73
  self._total_net_gain = total_net_gain
73
74
  self._backtest_data_index_date = backtest_data_index_date
74
75
  self._total_value = total_value
75
- self.positions = positions
76
+ self._positions = positions
77
+ self._orders = orders
76
78
  self._average_trade_duration = average_trade_duration
77
79
  self._average_trade_size = average_trade_size
78
80
  self._trades = trades
79
81
  self._created_at: datetime = created_at
80
82
  self._interval = interval
81
83
  self._time_unit = time_unit
84
+ self._context = context
82
85
 
83
86
  @property
84
87
  def name(self):
@@ -116,10 +119,6 @@ class BacktestReport(BaseModel):
116
119
  def backtest_end_date(self):
117
120
  return self._backtest_end_date
118
121
 
119
- @property
120
- def backtest_index_date(self):
121
- return self._backtest_index_date
122
-
123
122
  @property
124
123
  def trading_time_frame(self):
125
124
  return self._trading_time_frame
@@ -160,10 +159,6 @@ class BacktestReport(BaseModel):
160
159
  def backtest_end_date(self, value):
161
160
  self._backtest_end_date = value
162
161
 
163
- @backtest_index_date.setter
164
- def backtest_index_date(self, value):
165
- self._backtest_index_date = value
166
-
167
162
  @number_of_runs.setter
168
163
  def number_of_runs(self, value):
169
164
  self._number_of_runs = value
@@ -316,6 +311,14 @@ class BacktestReport(BaseModel):
316
311
  def positions(self, value):
317
312
  self._positions = value
318
313
 
314
+ @property
315
+ def orders(self):
316
+ return self._orders
317
+
318
+ @orders.setter
319
+ def orders(self, value):
320
+ self._orders = value
321
+
319
322
  @property
320
323
  def average_trade_duration(self):
321
324
  return self._average_trade_duration
@@ -348,6 +351,14 @@ class BacktestReport(BaseModel):
348
351
  def interval(self, value):
349
352
  self._interval = value
350
353
 
354
+ @property
355
+ def context(self):
356
+ return self._context
357
+
358
+ @context.setter
359
+ def context(self, value):
360
+ self._context = value
361
+
351
362
  @property
352
363
  def time_unit(self):
353
364
  return self._time_unit
@@ -372,7 +383,6 @@ class BacktestReport(BaseModel):
372
383
  name=self.name,
373
384
  start_date=self.backtest_start_date,
374
385
  end_date=self.backtest_end_date,
375
- backtest_index_date=self.backtest_index_date,
376
386
  start_date_data=self.backtest_start_date_data,
377
387
  )
378
388
 
@@ -383,9 +393,12 @@ class BacktestReport(BaseModel):
383
393
  """
384
394
  return {
385
395
  "name": self.name,
396
+ "context": self.context if self.context is not None else {},
386
397
  "strategy_identifiers": self.strategy_identifiers,
387
- "backtest_start_date": self.backtest_start_date,
388
- "backtest_end_date": self.backtest_end_date,
398
+ "backtest_start_date": self.backtest_start_date
399
+ .strftime(DATETIME_FORMAT),
400
+ "backtest_end_date": self.backtest_end_date
401
+ .strftime(DATETIME_FORMAT),
389
402
  "number_of_runs": self.number_of_runs,
390
403
  "symbols": self.symbols,
391
404
  "market": self.market,
@@ -404,10 +417,16 @@ class BacktestReport(BaseModel):
404
417
  "trading_symbol": self.trading_symbol,
405
418
  "total_net_gain_percentage": self.total_net_gain_percentage,
406
419
  "total_net_gain": self.total_net_gain,
407
- "backtest_data_index_date": self.backtest_data_index_date,
408
420
  "total_value": self.total_value,
409
421
  "average_trade_duration": self.average_trade_duration,
410
422
  "average_trade_size": self.average_trade_size,
423
+ "positions": [position.to_dict() for position in self.positions],
424
+ "trades": [trade.to_dict() for trade in self.trades],
425
+ "orders": [
426
+ order.to_dict(datetime_format=DATETIME_FORMAT)
427
+ for order in self.orders
428
+ ],
429
+ "created_at": self.created_at.strftime(DATETIME_FORMAT),
411
430
  }
412
431
 
413
432
  @staticmethod
@@ -438,7 +457,6 @@ class BacktestReport(BaseModel):
438
457
  trading_symbol=data["trading_symbol"],
439
458
  total_net_gain_percentage=float(data["total_net_gain_percentage"]),
440
459
  total_net_gain=float(data["total_net_gain"]),
441
- backtest_data_index_date=data["backtest_data_index_date"],
442
460
  total_value=float(data["total_value"]),
443
461
  average_trade_duration=data["average_trade_duration"],
444
462
  average_trade_size=float(data["average_trade_size"]),
@@ -1,7 +1,6 @@
1
1
  from .order import Order
2
- from .order_fee import OrderFee
3
2
  from .order_side import OrderSide
4
3
  from .order_status import OrderStatus
5
4
  from .order_type import OrderType
6
5
 
7
- __all__ = ["OrderType", "OrderStatus", "OrderSide", "Order", "OrderFee"]
6
+ __all__ = ["OrderType", "OrderStatus", "OrderSide", "Order"]
@@ -5,20 +5,20 @@ from dateutil.parser import parse
5
5
  from investing_algorithm_framework.domain.exceptions import \
6
6
  OperationalException
7
7
  from investing_algorithm_framework.domain.models.base_model import BaseModel
8
+ from investing_algorithm_framework.domain.models.order.order_side import \
9
+ OrderSide
8
10
  from investing_algorithm_framework.domain.models.order.order_status import \
9
11
  OrderStatus
10
12
  from investing_algorithm_framework.domain.models.order.order_type import \
11
13
  OrderType
12
- from investing_algorithm_framework.domain.models.order.order_side import \
13
- OrderSide
14
- from investing_algorithm_framework.domain.models.order.order_fee import \
15
- OrderFee
16
14
 
17
15
  logger = logging.getLogger("investing_algorithm_framework")
18
16
 
19
17
 
20
18
  class Order(BaseModel):
21
-
19
+ """
20
+ Order model class to represent an order of the trading bot
21
+ """
22
22
  def __init__(
23
23
  self,
24
24
  order_type,
@@ -40,10 +40,9 @@ class Order(BaseModel):
40
40
  cost=None,
41
41
  fee=None,
42
42
  position_id=None,
43
- stop_loss=None,
44
- stop_loss_percentage=None,
45
- trailing_stop_loss=None,
46
- trailing_stop_loss_percentage=None,
43
+ order_fee=None,
44
+ order_fee_currency=None,
45
+ order_fee_rate=None
47
46
  ):
48
47
  if target_symbol is None:
49
48
  raise OperationalException("Target symbol is not specified")
@@ -80,11 +79,10 @@ class Order(BaseModel):
80
79
  self.remaining = remaining
81
80
  self.cost = cost
82
81
  self.fee = fee
83
- self.stop_loss = stop_loss
84
- self.stop_loss_percentage = stop_loss_percentage
85
- self.trailing_stop_loss = trailing_stop_loss
86
- self.trailing_stop_loss_percentage = trailing_stop_loss_percentage
87
82
  self._available_amount = self.filled
83
+ self.order_fee = order_fee
84
+ self.order_fee_currency = order_fee_currency
85
+ self.order_fee_rate = order_fee_rate
88
86
 
89
87
  def get_id(self):
90
88
  return self.id
@@ -107,6 +105,24 @@ class Order(BaseModel):
107
105
  def set_price(self, price):
108
106
  self.price = price
109
107
 
108
+ def get_order_fee_currency(self):
109
+ return self.order_fee_currency
110
+
111
+ def set_order_fee_currency(self, order_fee_currency):
112
+ self.order_fee_currency = order_fee_currency
113
+
114
+ def get_order_fee_rate(self):
115
+ return self.order_fee_rate
116
+
117
+ def set_order_fee_rate(self, order_fee_rate):
118
+ self.order_fee_rate = order_fee_rate
119
+
120
+ def get_order_fee(self):
121
+ return self.order_fee
122
+
123
+ def set_order_fee(self, order_fee):
124
+ self.order_fee = order_fee
125
+
110
126
  def get_order_size(self):
111
127
  return self.order_side
112
128
 
@@ -232,7 +248,20 @@ class Order(BaseModel):
232
248
  def available_amount(self, available_amount):
233
249
  self.set_available_amount(available_amount)
234
250
 
235
- def to_dict(self):
251
+ def to_dict(self, datetime_format=None):
252
+
253
+ if datetime_format is not None:
254
+ created_at = self.created_at.strftime(datetime_format) \
255
+ if self.created_at else None
256
+ updated_at = self.updated_at.strftime(datetime_format) \
257
+ if self.updated_at else None
258
+ trade_closed_at = self.trade_closed_at.strftime(datetime_format) \
259
+ if self.trade_closed_at else None
260
+ else:
261
+ created_at = self.created_at
262
+ updated_at = self.updated_at
263
+ trade_closed_at = self.trade_closed_at
264
+
236
265
  return {
237
266
  "external_id": self.external_id,
238
267
  "target_symbol": self.target_symbol,
@@ -243,18 +272,16 @@ class Order(BaseModel):
243
272
  "price": self.price,
244
273
  "amount": self.amount,
245
274
  "net_gain": self.net_gain,
246
- "trade_closed_at": self.trade_closed_at,
275
+ "trade_closed_at": trade_closed_at,
247
276
  "trade_closed_price": self.trade_closed_price,
248
- "created_at": self.created_at,
249
- "updated_at": self.updated_at,
277
+ "created_at": created_at,
278
+ "updated_at": updated_at,
250
279
  "filled": self.filled,
251
280
  "remaining": self.remaining,
252
281
  "cost": self.cost,
253
- "fee": self.fee.to_dict() if self.fee is not None else None,
254
- "stop_loss": self.stop_loss,
255
- "stop_loss_percentage": self.stop_loss_percentage,
256
- "trailing_stop_loss": self.trailing_stop_loss,
257
- "trailing_stop_loss_percentage": self.trailing_stop_loss_percentage
282
+ "order_fee_currency": self.order_fee_currency,
283
+ "order_fee_rate": self.order_fee_rate,
284
+ "order_fee": self.order_fee,
258
285
  }
259
286
 
260
287
  @staticmethod
@@ -290,14 +317,32 @@ class Order(BaseModel):
290
317
  cost=data.get("cost", None),
291
318
  fee=data.get("fee", None),
292
319
  created_at=created_at,
293
- updated_at=updated_at
320
+ updated_at=updated_at,
321
+ order_fee=data.get("order_fee", None),
322
+ order_fee_currency=data.get("order_fee_currency", None),
323
+ order_fee_rate=data.get("order_fee_rate", None),
294
324
  )
295
325
 
296
326
  @staticmethod
297
327
  def from_ccxt_order(ccxt_order):
328
+ """
329
+ Create an Order object from a ccxt order object
330
+ :param ccxt_order: ccxt order object
331
+ :return: Order object
332
+ """
298
333
  status = OrderStatus.from_value(ccxt_order["status"])
299
334
  target_symbol = ccxt_order.get("symbol").split("/")[0]
300
335
  trading_symbol = ccxt_order.get("symbol").split("/")[1]
336
+ ccxt_fee = ccxt_order.get("fee", None)
337
+ order_fee = None
338
+ order_fee_currency = None
339
+ order_fee_rate = None
340
+
341
+ if ccxt_fee is not None:
342
+ order_fee = ccxt_fee.get("cost", None)
343
+ order_fee_currency = ccxt_fee.get("currency", None)
344
+ order_fee_rate = ccxt_fee.get("rate", None)
345
+
301
346
  return Order(
302
347
  external_id=ccxt_order.get("id", None),
303
348
  target_symbol=target_symbol,
@@ -310,7 +355,9 @@ class Order(BaseModel):
310
355
  filled=ccxt_order.get("filled", None),
311
356
  remaining=ccxt_order.get("remaining", None),
312
357
  cost=ccxt_order.get("cost", None),
313
- fee=OrderFee.from_ccxt_fee(ccxt_order.get("fee", None)),
358
+ order_fee=order_fee,
359
+ order_fee_currency=order_fee_currency,
360
+ order_fee_rate=order_fee_rate,
314
361
  created_at=parse(ccxt_order.get("datetime", None))
315
362
  )
316
363