investing-algorithm-framework 6.9.1__py3-none-any.whl → 7.19.15__py3-none-any.whl

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 (192) hide show
  1. investing_algorithm_framework/__init__.py +147 -44
  2. investing_algorithm_framework/app/__init__.py +23 -6
  3. investing_algorithm_framework/app/algorithm/algorithm.py +5 -41
  4. investing_algorithm_framework/app/algorithm/algorithm_factory.py +17 -10
  5. investing_algorithm_framework/app/analysis/__init__.py +15 -0
  6. investing_algorithm_framework/app/analysis/backtest_data_ranges.py +121 -0
  7. investing_algorithm_framework/app/analysis/backtest_utils.py +107 -0
  8. investing_algorithm_framework/app/analysis/permutation.py +116 -0
  9. investing_algorithm_framework/app/analysis/ranking.py +297 -0
  10. investing_algorithm_framework/app/app.py +1322 -707
  11. investing_algorithm_framework/app/context.py +196 -88
  12. investing_algorithm_framework/app/eventloop.py +590 -0
  13. investing_algorithm_framework/app/reporting/__init__.py +16 -5
  14. investing_algorithm_framework/app/reporting/ascii.py +57 -202
  15. investing_algorithm_framework/app/reporting/backtest_report.py +284 -170
  16. investing_algorithm_framework/app/reporting/charts/__init__.py +10 -2
  17. investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +66 -0
  18. investing_algorithm_framework/app/reporting/charts/equity_curve.py +37 -0
  19. investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +11 -26
  20. investing_algorithm_framework/app/reporting/charts/line_chart.py +11 -0
  21. investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +51 -0
  22. investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +1 -1
  23. investing_algorithm_framework/app/reporting/generate.py +100 -114
  24. investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +40 -32
  25. investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +34 -27
  26. investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +23 -19
  27. investing_algorithm_framework/app/reporting/tables/trades_table.py +1 -1
  28. investing_algorithm_framework/app/reporting/tables/utils.py +1 -0
  29. investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +10 -16
  30. investing_algorithm_framework/app/strategy.py +315 -175
  31. investing_algorithm_framework/app/task.py +5 -3
  32. investing_algorithm_framework/cli/cli.py +30 -12
  33. investing_algorithm_framework/cli/deploy_to_aws_lambda.py +131 -34
  34. investing_algorithm_framework/cli/initialize_app.py +20 -1
  35. investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +18 -6
  36. investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
  37. investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
  38. investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -2
  39. investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +1 -1
  40. investing_algorithm_framework/create_app.py +3 -5
  41. investing_algorithm_framework/dependency_container.py +25 -39
  42. investing_algorithm_framework/domain/__init__.py +45 -38
  43. investing_algorithm_framework/domain/backtesting/__init__.py +21 -0
  44. investing_algorithm_framework/domain/backtesting/backtest.py +503 -0
  45. investing_algorithm_framework/domain/backtesting/backtest_date_range.py +96 -0
  46. investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +242 -0
  47. investing_algorithm_framework/domain/backtesting/backtest_metrics.py +459 -0
  48. investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
  49. investing_algorithm_framework/domain/backtesting/backtest_run.py +605 -0
  50. investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
  51. investing_algorithm_framework/domain/backtesting/combine_backtests.py +280 -0
  52. investing_algorithm_framework/domain/config.py +27 -0
  53. investing_algorithm_framework/domain/constants.py +6 -34
  54. investing_algorithm_framework/domain/data_provider.py +200 -56
  55. investing_algorithm_framework/domain/exceptions.py +34 -1
  56. investing_algorithm_framework/domain/models/__init__.py +10 -19
  57. investing_algorithm_framework/domain/models/base_model.py +0 -6
  58. investing_algorithm_framework/domain/models/data/__init__.py +7 -0
  59. investing_algorithm_framework/domain/models/data/data_source.py +214 -0
  60. investing_algorithm_framework/domain/models/{market_data_type.py → data/data_type.py} +7 -7
  61. investing_algorithm_framework/domain/models/market/market_credential.py +6 -0
  62. investing_algorithm_framework/domain/models/order/order.py +34 -13
  63. investing_algorithm_framework/domain/models/order/order_status.py +1 -1
  64. investing_algorithm_framework/domain/models/order/order_type.py +1 -1
  65. investing_algorithm_framework/domain/models/portfolio/portfolio.py +14 -1
  66. investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +5 -1
  67. investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +51 -11
  68. investing_algorithm_framework/domain/models/position/__init__.py +2 -1
  69. investing_algorithm_framework/domain/models/position/position.py +9 -0
  70. investing_algorithm_framework/domain/models/position/position_size.py +41 -0
  71. investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
  72. investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
  73. investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
  74. investing_algorithm_framework/domain/models/snapshot_interval.py +0 -1
  75. investing_algorithm_framework/domain/models/strategy_profile.py +19 -151
  76. investing_algorithm_framework/domain/models/time_frame.py +7 -0
  77. investing_algorithm_framework/domain/models/time_interval.py +33 -0
  78. investing_algorithm_framework/domain/models/time_unit.py +63 -1
  79. investing_algorithm_framework/domain/models/trade/__init__.py +0 -2
  80. investing_algorithm_framework/domain/models/trade/trade.py +56 -32
  81. investing_algorithm_framework/domain/models/trade/trade_status.py +8 -2
  82. investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +106 -41
  83. investing_algorithm_framework/domain/models/trade/trade_take_profit.py +161 -99
  84. investing_algorithm_framework/domain/order_executor.py +19 -0
  85. investing_algorithm_framework/domain/portfolio_provider.py +20 -1
  86. investing_algorithm_framework/domain/services/__init__.py +0 -13
  87. investing_algorithm_framework/domain/strategy.py +1 -29
  88. investing_algorithm_framework/domain/utils/__init__.py +5 -1
  89. investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
  90. investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
  91. investing_algorithm_framework/domain/utils/polars.py +17 -14
  92. investing_algorithm_framework/download_data.py +40 -10
  93. investing_algorithm_framework/infrastructure/__init__.py +13 -25
  94. investing_algorithm_framework/infrastructure/data_providers/__init__.py +7 -4
  95. investing_algorithm_framework/infrastructure/data_providers/ccxt.py +811 -546
  96. investing_algorithm_framework/infrastructure/data_providers/csv.py +433 -122
  97. investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
  98. investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
  99. investing_algorithm_framework/infrastructure/database/sql_alchemy.py +81 -0
  100. investing_algorithm_framework/infrastructure/models/__init__.py +0 -13
  101. investing_algorithm_framework/infrastructure/models/order/order.py +9 -3
  102. investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +27 -8
  103. investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +21 -7
  104. investing_algorithm_framework/infrastructure/order_executors/__init__.py +2 -0
  105. investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
  106. investing_algorithm_framework/infrastructure/repositories/repository.py +16 -2
  107. investing_algorithm_framework/infrastructure/repositories/trade_repository.py +2 -2
  108. investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +6 -0
  109. investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +6 -0
  110. investing_algorithm_framework/infrastructure/services/__init__.py +0 -4
  111. investing_algorithm_framework/services/__init__.py +105 -8
  112. investing_algorithm_framework/services/backtesting/backtest_service.py +536 -476
  113. investing_algorithm_framework/services/configuration_service.py +14 -4
  114. investing_algorithm_framework/services/data_providers/__init__.py +5 -0
  115. investing_algorithm_framework/services/data_providers/data_provider_service.py +850 -0
  116. investing_algorithm_framework/{app/reporting → services}/metrics/__init__.py +48 -17
  117. investing_algorithm_framework/{app/reporting → services}/metrics/drawdown.py +10 -10
  118. investing_algorithm_framework/{app/reporting → services}/metrics/equity_curve.py +2 -2
  119. investing_algorithm_framework/{app/reporting → services}/metrics/exposure.py +60 -2
  120. investing_algorithm_framework/services/metrics/generate.py +358 -0
  121. investing_algorithm_framework/{app/reporting → services}/metrics/profit_factor.py +36 -0
  122. investing_algorithm_framework/{app/reporting → services}/metrics/recovery.py +2 -2
  123. investing_algorithm_framework/{app/reporting → services}/metrics/returns.py +146 -147
  124. investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
  125. investing_algorithm_framework/{app/reporting/metrics/sharp_ratio.py → services/metrics/sharpe_ratio.py} +6 -10
  126. investing_algorithm_framework/{app/reporting → services}/metrics/sortino_ratio.py +3 -7
  127. investing_algorithm_framework/services/metrics/trades.py +500 -0
  128. investing_algorithm_framework/services/metrics/volatility.py +97 -0
  129. investing_algorithm_framework/{app/reporting → services}/metrics/win_rate.py +70 -3
  130. investing_algorithm_framework/services/order_service/order_backtest_service.py +21 -31
  131. investing_algorithm_framework/services/order_service/order_service.py +9 -71
  132. investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +0 -2
  133. investing_algorithm_framework/services/portfolios/portfolio_service.py +3 -13
  134. investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +62 -96
  135. investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -3
  136. investing_algorithm_framework/services/repository_service.py +5 -2
  137. investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
  138. investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +113 -0
  139. investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
  140. investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
  141. investing_algorithm_framework/services/trade_service/__init__.py +7 -1
  142. investing_algorithm_framework/services/trade_service/trade_service.py +51 -29
  143. investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
  144. investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
  145. investing_algorithm_framework-7.19.15.dist-info/METADATA +537 -0
  146. {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/RECORD +159 -148
  147. investing_algorithm_framework/app/reporting/evaluation.py +0 -243
  148. investing_algorithm_framework/app/reporting/metrics/risk_free_rate.py +0 -8
  149. investing_algorithm_framework/app/reporting/metrics/volatility.py +0 -69
  150. investing_algorithm_framework/cli/templates/requirements_azure_function.txt.template +0 -3
  151. investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -9
  152. investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -47
  153. investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -120
  154. investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
  155. investing_algorithm_framework/domain/models/backtesting/backtest_results.py +0 -440
  156. investing_algorithm_framework/domain/models/data_source.py +0 -21
  157. investing_algorithm_framework/domain/models/date_range.py +0 -64
  158. investing_algorithm_framework/domain/models/trade/trade_risk_type.py +0 -34
  159. investing_algorithm_framework/domain/models/trading_data_types.py +0 -48
  160. investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
  161. investing_algorithm_framework/domain/services/market_data_sources.py +0 -543
  162. investing_algorithm_framework/domain/services/market_service.py +0 -153
  163. investing_algorithm_framework/domain/services/observable.py +0 -51
  164. investing_algorithm_framework/domain/services/observer.py +0 -19
  165. investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -16
  166. investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -746
  167. investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -270
  168. investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +0 -312
  169. investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -5
  170. investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -471
  171. investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -7
  172. investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -2
  173. investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -322
  174. investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -10
  175. investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -269
  176. investing_algorithm_framework/services/market_data_source_service/data_provider_service.py +0 -350
  177. investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -377
  178. investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -296
  179. investing_algorithm_framework-6.9.1.dist-info/METADATA +0 -440
  180. /investing_algorithm_framework/{app/reporting → services}/metrics/alpha.py +0 -0
  181. /investing_algorithm_framework/{app/reporting → services}/metrics/beta.py +0 -0
  182. /investing_algorithm_framework/{app/reporting → services}/metrics/cagr.py +0 -0
  183. /investing_algorithm_framework/{app/reporting → services}/metrics/calmar_ratio.py +0 -0
  184. /investing_algorithm_framework/{app/reporting → services}/metrics/mean_daily_return.py +0 -0
  185. /investing_algorithm_framework/{app/reporting → services}/metrics/price_efficiency.py +0 -0
  186. /investing_algorithm_framework/{app/reporting → services}/metrics/standard_deviation.py +0 -0
  187. /investing_algorithm_framework/{app/reporting → services}/metrics/treynor_ratio.py +0 -0
  188. /investing_algorithm_framework/{app/reporting → services}/metrics/ulcer.py +0 -0
  189. /investing_algorithm_framework/{app/reporting → services}/metrics/value_at_risk.py +0 -0
  190. {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/LICENSE +0 -0
  191. {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/WHEEL +0 -0
  192. {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/entry_points.txt +0 -0
@@ -13,10 +13,12 @@ class OrderExecutor(ABC):
13
13
  other order executors. The lower the number, the higher the
14
14
  priority. The framework will use this priority when searching
15
15
  for an order executor for a specific market.
16
+ _config (dict): Reference to the application configuration.
16
17
  """
17
18
 
18
19
  def __init__(self, priority=1):
19
20
  self._priority = priority
21
+ self._config = None
20
22
 
21
23
  @property
22
24
  def priority(self):
@@ -25,6 +27,23 @@ class OrderExecutor(ABC):
25
27
  """
26
28
  return self._priority
27
29
 
30
+ @property
31
+ def config(self):
32
+ """
33
+ Returns the configuration of the order executor.
34
+ This can be used to store any configuration that is needed
35
+ for the order executor.
36
+ """
37
+ return self._config
38
+
39
+ @config.setter
40
+ def config(self, config):
41
+ """
42
+ Setter for the app config. This will be used to set a reference
43
+ to the config of the Application when the app is started.
44
+ """
45
+ self._config = config
46
+
28
47
  @abstractmethod
29
48
  def execute_order(self, portfolio, order, market_credential) -> Order:
30
49
  """
@@ -10,14 +10,16 @@ class PortfolioProvider(ABC):
10
10
  is responsible for managing and providing access to trading portfolios.
11
11
 
12
12
  Attributes:
13
- priority (int): The priority of the portfolio provider compared to
13
+ _priority (int): The priority of the portfolio provider compared to
14
14
  other portfolio providers. The lower the number, the higher the
15
15
  priority. The framework will use this priority when searching
16
16
  for a portfolio provider for a specific symbol or market.
17
+ _config (dict): Reference to the application configuration.
17
18
  """
18
19
 
19
20
  def __init__(self, priority=1):
20
21
  self._priority = priority
22
+ self._config = None
21
23
 
22
24
  @property
23
25
  def priority(self):
@@ -33,6 +35,23 @@ class PortfolioProvider(ABC):
33
35
  """
34
36
  self._priority = value
35
37
 
38
+ @property
39
+ def config(self):
40
+ """
41
+ Returns the configuration of the order executor.
42
+ This can be used to store any configuration that is needed
43
+ for the order executor.
44
+ """
45
+ return self._config
46
+
47
+ @config.setter
48
+ def config(self, config):
49
+ """
50
+ Setter for the app config. This will be used to set a reference
51
+ to the config of the Application when the app is started.
52
+ """
53
+ self._config = config
54
+
36
55
  @abstractmethod
37
56
  def get_order(
38
57
  self, portfolio, order, market_credential
@@ -1,24 +1,11 @@
1
1
  from .market_credential_service import MarketCredentialService
2
- from .market_data_sources import MarketDataSource, TickerMarketDataSource, \
3
- OHLCVMarketDataSource, OrderBookMarketDataSource, BacktestMarketDataSource
4
- from .market_service import MarketService
5
2
  from .portfolios import AbstractPortfolioSyncService
6
3
  from .rounding_service import RoundingService
7
4
  from .state_handler import StateHandler
8
- from .observer import Observer
9
- from .observable import Observable
10
5
 
11
6
  __all__ = [
12
- "MarketDataSource",
13
- "TickerMarketDataSource",
14
- "OHLCVMarketDataSource",
15
- "OrderBookMarketDataSource",
16
- "BacktestMarketDataSource",
17
- "MarketService",
18
7
  "MarketCredentialService",
19
8
  "AbstractPortfolioSyncService",
20
9
  "RoundingService",
21
10
  "StateHandler",
22
- "Observer",
23
- "Observable"
24
11
  ]
@@ -1,4 +1,4 @@
1
- from .models import TradingTimeFrame, TradingDataType, TimeUnit
1
+ from .models import TimeUnit
2
2
 
3
3
 
4
4
  class Strategy:
@@ -11,9 +11,6 @@ class Strategy:
11
11
  worker_id=None,
12
12
  symbols=None,
13
13
  limit=None,
14
- trading_data_type=None,
15
- trading_data_types=None,
16
- trading_time_frame=None,
17
14
  ):
18
15
  self._market = market
19
16
  self._time_unit = TimeUnit.from_value(time_unit).value
@@ -22,19 +19,6 @@ class Strategy:
22
19
  self._limit = limit
23
20
  self._worker_id = worker_id
24
21
 
25
- if trading_data_type is not None:
26
- self._trading_data_type = TradingDataType \
27
- .from_value(trading_data_type)
28
-
29
- if trading_data_types is not None:
30
- trading_data_types = [TradingDataType.from_value(trading_data_type)
31
- for trading_data_type in trading_data_types]
32
- self._trading_data_types = trading_data_types
33
-
34
- if trading_time_frame is not None:
35
- self._trading_time_frame = TradingTimeFrame \
36
- .from_value(trading_time_frame)
37
-
38
22
  @property
39
23
  def market(self):
40
24
  return self._market
@@ -55,18 +39,6 @@ class Strategy:
55
39
  def limit(self):
56
40
  return self._limit
57
41
 
58
- @property
59
- def trading_data_type(self):
60
- return self._trading_data_type
61
-
62
- @property
63
- def trading_data_types(self):
64
- return self._trading_data_types
65
-
66
- @property
67
- def trading_time_frame(self):
68
- return self._trading_time_frame
69
-
70
42
  @property
71
43
  def worker_id(self):
72
44
  return self._worker_id
@@ -5,6 +5,8 @@ from .stoppable_thread import StoppableThread
5
5
  from .synchronized import synchronized
6
6
  from .polars import convert_polars_to_pandas
7
7
  from .dates import is_timezone_aware, sync_timezones, get_timezone
8
+ from .jupyter_notebook_detection import is_jupyter_notebook
9
+ from .custom_tqdm import tqdm
8
10
 
9
11
  __all__ = [
10
12
  'synchronized',
@@ -19,5 +21,7 @@ __all__ = [
19
21
  'convert_polars_to_pandas',
20
22
  'is_timezone_aware',
21
23
  'sync_timezones',
22
- 'get_timezone'
24
+ 'get_timezone',
25
+ 'is_jupyter_notebook',
26
+ 'tqdm'
23
27
  ]
@@ -0,0 +1,22 @@
1
+ from tqdm.notebook import tqdm as tqdm_notebook
2
+ from tqdm import tqdm as tqdm_terminal
3
+
4
+ from .jupyter_notebook_detection import is_jupyter_notebook
5
+
6
+
7
+ def tqdm(*args, **kwargs):
8
+ """
9
+ Returns a tqdm progress bar that adapts to the
10
+ environment (Jupyter Notebook or terminal).
11
+
12
+ Args:
13
+ *args: Positional arguments for tqdm.
14
+ **kwargs: Keyword arguments for tqdm.
15
+
16
+ Returns:
17
+ tqdm object: A tqdm progress bar.
18
+ """
19
+ if is_jupyter_notebook():
20
+ return tqdm_notebook(*args, **kwargs)
21
+ else:
22
+ return tqdm_terminal(*args, **kwargs)
@@ -0,0 +1,19 @@
1
+ def is_jupyter_notebook():
2
+ """
3
+ Check if the code is running in a Jupyter Notebook environment.
4
+
5
+ Returns:
6
+ bool: True if running in a Jupyter Notebook, False otherwise.
7
+ """
8
+ try:
9
+ # Check for the presence of the 'IPython' module
10
+ from IPython import get_ipython
11
+ return 'IPKernelApp' in get_ipython().config
12
+ except ImportError:
13
+ return False
14
+ except AttributeError:
15
+ # If get_ipython() does not have 'config', it is not a Jupyter Notebook
16
+ return False
17
+ except Exception:
18
+ # Catch any other exceptions and return False
19
+ return False
@@ -1,4 +1,4 @@
1
- from pandas import to_datetime
1
+ import pandas as pd
2
2
  from polars import DataFrame as PolarsDataFrame
3
3
 
4
4
 
@@ -6,17 +6,24 @@ def convert_polars_to_pandas(
6
6
  data: PolarsDataFrame,
7
7
  remove_duplicates=True,
8
8
  add_index=True,
9
+ add_datetime_column=True,
9
10
  datetime_column_name="Datetime"
10
11
  ):
11
12
  """
12
13
  Function to convert polars dataframe to pandas dataframe.
13
14
 
15
+ The function will set the index to the datetime column. The reason
16
+ for this is that You can filter with clean, readable code in a faster way
17
+ then with filtering on a column that is not the index.
18
+
14
19
  Args:
15
20
  data:Polars Dataframe - The original polars dataframe
16
21
  remove_duplicates: Boolean - If set to true, all duplicate
17
22
  dates will be removed from the dataframe
18
23
  add_index: Boolean - If set to true, an index will
19
24
  be added to the dataframe
25
+ add_datetime_column: Boolean - If set to true, a datetime
26
+ column will be added to the dataframe
20
27
  datetime_column_name: String - the column name that has the
21
28
  datetime object. By default this is set to column name Datetime
22
29
  This is only used if add_index is set to True
@@ -29,22 +36,18 @@ def convert_polars_to_pandas(
29
36
  if not isinstance(data, PolarsDataFrame):
30
37
  raise ValueError("Data must be a Polars DataFrame")
31
38
 
32
- data = data.to_pandas().copy()
39
+ df = data.to_pandas().copy()
33
40
 
34
- if add_index:
35
- # Convert 'Datetime' column to datetime format if it's not already
36
- data[datetime_column_name] = to_datetime(data[datetime_column_name])
41
+ if add_datetime_column and datetime_column_name not in df.columns:
42
+ df[datetime_column_name] = pd.to_datetime(df.index)
37
43
 
38
- # Set 'Datetime' column as the index
39
- data.set_index(datetime_column_name, inplace=True)
44
+ # Ensure datetime column is datetime type
45
+ df[datetime_column_name] = pd.to_datetime(df[datetime_column_name])
40
46
 
41
47
  if remove_duplicates:
48
+ df = df.drop_duplicates(subset=datetime_column_name, keep="first")
42
49
 
43
- # Remove duplicate dates
44
- data = data[~data.index.duplicated(keep='first')]
45
-
46
- # Make sure that the datetime column is still in the dataframe
47
- if datetime_column_name not in data.columns:
48
- data[datetime_column_name] = data.index
50
+ if add_index:
51
+ df.set_index(datetime_column_name, inplace=True)
49
52
 
50
- return data
53
+ return df
@@ -1,25 +1,29 @@
1
+ from pathlib import Path
1
2
  from dateutil import parser
3
+ from datetime import timezone, datetime
2
4
  import pandas
3
5
  import polars
4
6
  from typing import Union
5
7
  from investing_algorithm_framework.services import DataProviderService, \
6
8
  ConfigurationService, MarketCredentialService
7
9
  from investing_algorithm_framework.infrastructure import \
8
- get_default_data_providers, get_default_ohlcv_data_providers
10
+ get_default_data_providers
11
+ from investing_algorithm_framework.domain import DataSource, \
12
+ OperationalException, DataType
9
13
 
10
14
 
11
15
  def download(
12
16
  symbol: str,
13
- market=None,
14
- date=None,
17
+ market: str = None,
18
+ date: Union[datetime, str] = None,
15
19
  time_frame: str = None,
16
- data_type: str = "ohlcv",
17
- start_date: str = None,
18
- end_date: str = None,
20
+ data_type: Union[str, DataType] = DataType.OHLCV,
21
+ start_date: Union[datetime, str] = None,
22
+ end_date: Union[datetime, str] = None,
19
23
  window_size: int = 200,
20
24
  pandas: bool = True,
21
25
  save: bool = True,
22
- storage_path: str = None,
26
+ storage_path: Union[str, Path] = None,
23
27
  ) -> Union[pandas.DataFrame, polars.DataFrame]:
24
28
  """
25
29
  Download market data from the specified source. This function
@@ -50,20 +54,37 @@ def download(
50
54
  data_provider_service = DataProviderService(
51
55
  default_data_providers=get_default_data_providers(),
52
56
  configuration_service=configuration_service,
53
- market_credentials_service=market_credential_service,
54
- default_ohlcv_data_providers=get_default_ohlcv_data_providers()
57
+ market_credential_service=market_credential_service,
55
58
  )
56
59
 
57
60
  if start_date is not None and isinstance(start_date, str):
58
61
  start_date = parser.parse(start_date)
62
+ start_date = start_date.replace(tzinfo=timezone.utc)
59
63
 
60
64
  if end_date is not None and isinstance(end_date, str):
61
65
  end_date = parser.parse(end_date)
66
+ end_date = end_date.replace(tzinfo=timezone.utc)
62
67
 
63
68
  if date is not None and isinstance(date, str):
64
69
  date = parser.parse(date)
70
+ date = date.replace(tzinfo=timezone.utc)
65
71
 
66
- return data_provider_service.get_data(
72
+ # Check if all the datetime parameters are in UTC
73
+ if date is not None \
74
+ and (date.tzinfo is None or date.tzinfo != timezone.utc):
75
+ raise OperationalException("Date must be a UTC datetime object")
76
+
77
+ if start_date is not None \
78
+ and (
79
+ start_date.tzinfo is None or start_date.tzinfo != timezone.utc
80
+ ):
81
+ raise OperationalException("Start date must be a UTC datetime object")
82
+
83
+ if end_date is not None \
84
+ and (end_date.tzinfo is None or end_date.tzinfo != timezone.utc):
85
+ raise OperationalException("End date must be a UTC datetime object")
86
+
87
+ data_source = DataSource(
67
88
  symbol=symbol,
68
89
  market=market,
69
90
  data_type=data_type,
@@ -76,3 +97,12 @@ def download(
76
97
  save=save,
77
98
  storage_path=storage_path
78
99
  )
100
+ data_provider_service.index_data_providers(
101
+ data_sources=[data_source]
102
+ )
103
+ return data_provider_service.get_data(
104
+ data_source=data_source,
105
+ date=date,
106
+ start_date=start_date,
107
+ end_date=end_date,
108
+ )
@@ -1,25 +1,22 @@
1
1
  from .database import setup_sqlalchemy, Session, \
2
- create_all_tables
2
+ create_all_tables, clear_db
3
3
  from .models import SQLPortfolio, SQLOrder, SQLPosition, \
4
4
  SQLPortfolioSnapshot, SQLPositionSnapshot, SQLTrade, \
5
- CCXTOHLCVBacktestMarketDataSource, CCXTOrderBookMarketDataSource, \
6
- CCXTTickerMarketDataSource, CCXTOHLCVMarketDataSource, \
7
- CSVOHLCVMarketDataSource, CSVTickerMarketDataSource, SQLTradeTakeProfit, \
8
- SQLTradeStopLoss, PandasOHLCVBacktestMarketDataSource, \
9
- PandasOHLCVMarketDataSource
5
+ SQLTradeTakeProfit, SQLTradeStopLoss
10
6
  from .repositories import SQLOrderRepository, SQLPositionRepository, \
11
7
  SQLPortfolioRepository, SQLTradeRepository, \
12
8
  SQLPortfolioSnapshotRepository, SQLPositionSnapshotRepository, \
13
9
  SQLTradeTakeProfitRepository, SQLTradeStopLossRepository, \
14
10
  SQLOrderMetadataRepository
15
- from .services import PerformanceService, CCXTMarketService, \
16
- AzureBlobStorageStateHandler, AWSS3StorageStateHandler
17
- from .data_providers import CCXTDataProvider, get_default_data_providers, \
18
- get_default_ohlcv_data_providers
19
- from .order_executors import CCXTOrderExecutor
11
+ from .services import AzureBlobStorageStateHandler, AWSS3StorageStateHandler
12
+ from .data_providers import CSVOHLCVDataProvider, get_default_data_providers, \
13
+ get_default_ohlcv_data_providers, CCXTOHLCVDataProvider, \
14
+ PandasOHLCVDataProvider
15
+ from .order_executors import CCXTOrderExecutor, BacktestOrderExecutor
20
16
  from .portfolio_providers import CCXTPortfolioProvider
21
17
 
22
18
  __all__ = [
19
+ "clear_db",
23
20
  "create_all_tables",
24
21
  "SQLPositionRepository",
25
22
  "SQLPortfolioRepository",
@@ -32,18 +29,8 @@ __all__ = [
32
29
  "SQLTrade",
33
30
  "SQLOrder",
34
31
  "SQLPosition",
35
- "PerformanceService",
36
32
  "SQLPortfolioSnapshot",
37
33
  "SQLPositionSnapshot",
38
- "CCXTOHLCVMarketDataSource",
39
- "CCXTOrderBookMarketDataSource",
40
- "CCXTTickerMarketDataSource",
41
- "CCXTOHLCVMarketDataSource",
42
- "CCXTMarketService",
43
- "CSVOHLCVMarketDataSource",
44
- "CSVTickerMarketDataSource",
45
- "CCXTOHLCVBacktestMarketDataSource",
46
- "CCXTOrderBookMarketDataSource",
47
34
  "AzureBlobStorageStateHandler",
48
35
  "SQLTradeRepository",
49
36
  "SQLTradeTakeProfit",
@@ -51,12 +38,13 @@ __all__ = [
51
38
  "SQLTradeTakeProfitRepository",
52
39
  "SQLTradeStopLossRepository",
53
40
  "SQLOrderMetadataRepository",
54
- "CCXTDataProvider",
41
+ "CSVOHLCVDataProvider",
55
42
  "CCXTOrderExecutor",
56
43
  "CCXTPortfolioProvider",
57
44
  "get_default_data_providers",
58
45
  "get_default_ohlcv_data_providers",
59
- "PandasOHLCVBacktestMarketDataSource",
60
- "PandasOHLCVMarketDataSource",
61
- "AWSS3StorageStateHandler"
46
+ "AWSS3StorageStateHandler",
47
+ "CCXTOHLCVDataProvider",
48
+ "BacktestOrderExecutor",
49
+ "PandasOHLCVDataProvider",
62
50
  ]
@@ -1,4 +1,6 @@
1
- from .ccxt import CCXTDataProvider, CCXTOHLCVDataProvider
1
+ from .ccxt import CCXTOHLCVDataProvider
2
+ from .csv import CSVOHLCVDataProvider
3
+ from .pandas import PandasOHLCVDataProvider
2
4
 
3
5
 
4
6
  def get_default_data_providers():
@@ -9,7 +11,7 @@ def get_default_data_providers():
9
11
  list: List of default data providers.
10
12
  """
11
13
  return [
12
- CCXTDataProvider(),
14
+ CCXTOHLCVDataProvider(),
13
15
  ]
14
16
 
15
17
 
@@ -26,8 +28,9 @@ def get_default_ohlcv_data_providers():
26
28
 
27
29
 
28
30
  __all__ = [
29
- 'CCXTDataProvider',
31
+ 'CSVOHLCVDataProvider',
30
32
  'CCXTOHLCVDataProvider',
31
33
  'get_default_data_providers',
32
- 'get_default_ohlcv_data_providers'
34
+ 'get_default_ohlcv_data_providers',
35
+ 'PandasOHLCVDataProvider',
33
36
  ]