investing-algorithm-framework 7.18.0__py3-none-any.whl → 7.19.1__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.

Potentially problematic release.


This version of investing-algorithm-framework might be problematic. Click here for more details.

@@ -10,7 +10,7 @@ from .app import App, Algorithm, \
10
10
  get_ohlcv_data_completeness_chart, get_equity_curve_chart
11
11
  from .domain import ApiException, combine_backtests, PositionSize, \
12
12
  OrderType, OperationalException, OrderStatus, OrderSide, \
13
- TimeUnit, TimeInterval, Order, Portfolio, Backtest, \
13
+ TimeUnit, TimeInterval, Order, Portfolio, Backtest, DataError, \
14
14
  Position, TimeFrame, INDEX_DATETIME, MarketCredential, \
15
15
  PortfolioConfiguration, RESOURCE_DIRECTORY, AWS_LAMBDA_LOGGING_CONFIG, \
16
16
  Trade, SYMBOLS, RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
@@ -191,5 +191,6 @@ __all__ = [
191
191
  "get_number_of_trades",
192
192
  "BacktestRun",
193
193
  "load_backtests_from_directory",
194
- "save_backtests_to_directory"
194
+ "save_backtests_to_directory",
195
+ "DataError"
195
196
  ]
@@ -5,6 +5,7 @@ import threading
5
5
  from datetime import datetime, timezone
6
6
  from typing import List, Optional, Any, Dict, Tuple
7
7
 
8
+ import pandas as pd
8
9
  from flask import Flask
9
10
 
10
11
  from investing_algorithm_framework.app.algorithm import Algorithm
@@ -16,7 +17,7 @@ from investing_algorithm_framework.domain import DATABASE_NAME, TimeUnit, \
16
17
  SQLALCHEMY_DATABASE_URI, OperationalException, StateHandler, \
17
18
  BACKTESTING_START_DATE, BACKTESTING_END_DATE, APP_MODE, MarketCredential, \
18
19
  AppMode, BacktestDateRange, DATABASE_DIRECTORY_NAME, DataSource, \
19
- BACKTESTING_INITIAL_AMOUNT, SNAPSHOT_INTERVAL, Backtest, \
20
+ BACKTESTING_INITIAL_AMOUNT, SNAPSHOT_INTERVAL, Backtest, DataError, \
20
21
  PortfolioConfiguration, SnapshotInterval, DataType, combine_backtests, \
21
22
  PortfolioProvider, OrderExecutor, ImproperlyConfigured, \
22
23
  DataProvider, INDEX_DATETIME, tqdm, BacktestPermutationTest, \
@@ -32,6 +33,7 @@ from .app_hook import AppHook
32
33
  from .eventloop import EventLoopService
33
34
  from .analysis import create_ohlcv_permutation
34
35
 
36
+
35
37
  logger = logging.getLogger("investing_algorithm_framework")
36
38
  COLOR_RESET = '\033[0m'
37
39
  COLOR_GREEN = '\033[92m'
@@ -789,6 +791,70 @@ class App:
789
791
  .market_credential_service()
790
792
  return market_credential_service.get_all()
791
793
 
794
+ def check_data_completeness(
795
+ self,
796
+ strategies: List[TradingStrategy],
797
+ backtest_date_range: BacktestDateRange
798
+ ) -> None:
799
+ """
800
+ Function to check the data completeness for a set of strategies
801
+ over a given backtest date range. This method checks if all data
802
+ sources required by the strategies have complete data for the
803
+ specified date range.
804
+
805
+ Args:
806
+ strategies (List[TradingStrategy]): List of strategy objects
807
+ to check data completeness for.
808
+ backtest_date_range (BacktestDateRange): The date range to
809
+ check data completeness for.
810
+ Returns:
811
+ None
812
+ """
813
+ data_sources = []
814
+
815
+ for strategy in strategies:
816
+ data_sources.extend(strategy.data_sources)
817
+
818
+ self.initialize_data_sources_backtest(
819
+ data_sources,
820
+ backtest_date_range,
821
+ show_progress=True
822
+ )
823
+ data_provider_service = self.container.data_provider_service()
824
+
825
+ for strategy in strategies:
826
+
827
+ for data_source in strategy.data_sources:
828
+
829
+ if DataType.OHLCV.equals(data_source.data_type):
830
+ df = data_provider_service.get_ohlcv_data(
831
+ symbol=data_source.symbol,
832
+ start_date=backtest_date_range.start_date,
833
+ end_date=backtest_date_range.end_date,
834
+ pandas=True
835
+ )
836
+ df = df.copy()
837
+ df['Datetime'] = pd.to_datetime(df['Datetime'])
838
+ df = df.sort_values('Datetime')\
839
+ .tail(data_source.window_size)
840
+ start = df['Datetime'].iloc[0]
841
+ end = df['Datetime'].iloc[-1]
842
+ freq = pd.to_timedelta(data_source.time_frame.value)
843
+ expected = pd.date_range(start, end, freq=freq)
844
+ actual = df['Datetime']
845
+ missing = expected.difference(actual)
846
+
847
+ # Calculate the percentage completeness
848
+ completeness = len(actual) / len(expected) * 100
849
+
850
+ if completeness < 100:
851
+ raise DataError(
852
+ f"Data completeness for data source "
853
+ f"{data_source.identifier} "
854
+ f"({data_source.symbol}) is {completeness:.2f}% "
855
+ f"complete. Missing data points: {len(missing)}"
856
+ )
857
+
792
858
  def run_vector_backtests(
793
859
  self,
794
860
  initial_amount,
@@ -15,7 +15,7 @@ from .constants import ITEMIZE, ITEMIZED, PER_PAGE, PAGE, ENVIRONMENT, \
15
15
  from .data_provider import DataProvider
16
16
  from .data_structures import PeekableQueue
17
17
  from .decimal_parsing import parse_decimal_to_string, parse_string_to_decimal
18
- from .exceptions import OperationalException, ApiException, \
18
+ from .exceptions import OperationalException, ApiException, DataError, \
19
19
  PermissionDeniedApiException, ImproperlyConfigured, NetworkError
20
20
  from .models import OrderStatus, OrderSide, OrderType, TimeInterval, \
21
21
  TimeUnit, TimeFrame, PortfolioConfiguration, Portfolio, Position, \
@@ -143,5 +143,6 @@ __all__ = [
143
143
  "BacktestEvaluationFocus",
144
144
  'combine_backtests',
145
145
  'PositionSize',
146
- 'generate_backtest_summary_metrics'
146
+ 'generate_backtest_summary_metrics',
147
+ 'DataError'
147
148
  ]
@@ -84,3 +84,20 @@ class NetworkError(Exception):
84
84
  "status": "error",
85
85
  "message": self.error_message
86
86
  }
87
+
88
+
89
+ class DataError(Exception):
90
+ """
91
+ Class DataError: Exception class indicating a problem occurred
92
+ during data retrieval or processing
93
+ """
94
+
95
+ def __init__(self, message) -> None:
96
+ super(DataError, self).__init__(message)
97
+ self.error_message = message
98
+
99
+ def to_response(self):
100
+ return {
101
+ "status": "error",
102
+ "message": self.error_message
103
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: investing-algorithm-framework
3
- Version: 7.18.0
3
+ Version: 7.19.1
4
4
  Summary: A framework for creating trading bots
5
5
  Author: MDUYN
6
6
  Requires-Python: >=3.10
@@ -1,4 +1,4 @@
1
- investing_algorithm_framework/__init__.py,sha256=ACNFUkjEf2UxGoBoci9JHeT6hGFISFyy4U-rLnZW8_E,6989
1
+ investing_algorithm_framework/__init__.py,sha256=e5i9FAiyvS1KwuvSkrFC0dPOgKCix9mGoGy-51Mqe1s,7017
2
2
  investing_algorithm_framework/app/__init__.py,sha256=BjVkBQvVuI7ovTpR2Bn8YOHL2p5vsX-LRqpe-aS3ImM,1671
3
3
  investing_algorithm_framework/app/algorithm/__init__.py,sha256=-a9o9bTfAhW9qSW-bKvlLQuMCf-YXxIztudo2TxMjCI,136
4
4
  investing_algorithm_framework/app/algorithm/algorithm.py,sha256=v8AZZ7hr5ZKJbavk242xCUpGHv3mKZ4sqfGV7BwPgdU,6854
@@ -8,7 +8,7 @@ investing_algorithm_framework/app/analysis/backtest_data_ranges.py,sha256=pt8vUj
8
8
  investing_algorithm_framework/app/analysis/backtest_utils.py,sha256=W_X1T8f1UOllUUkaO4ZiQlQ7dSEGi9TqVo_ROyv7XNE,2121
9
9
  investing_algorithm_framework/app/analysis/permutation.py,sha256=NHzyMQ9aCqLiLXyw1CpRZfITLzsRwHmMn8Uj8oV5_1E,3941
10
10
  investing_algorithm_framework/app/analysis/ranking.py,sha256=-XEWmU3rxLvkC9GOW6Zci7E3Y7H2xKwU3id8ljf0n9k,10888
11
- investing_algorithm_framework/app/app.py,sha256=saAfkfWJg-in7qKCOIpN1HljMU2YCuvdqSTWi4a-Ub0,83223
11
+ investing_algorithm_framework/app/app.py,sha256=bubVZeIQx1JLl2CRDRpf0KLhgVWRIwaD_72HN3TG4qo,85834
12
12
  investing_algorithm_framework/app/app_hook.py,sha256=cDiY4x2n06tljpx-fcbIM1oPnjTnEthibvqxUvfEppo,834
13
13
  investing_algorithm_framework/app/context.py,sha256=kWOBZq7E45xoAPbMfn9HPhDQmEcyCqBYWi-NJK5nMXk,58874
14
14
  investing_algorithm_framework/app/eventloop.py,sha256=w9zufVpiHrgsxuh4_AW2DXxOfI4LVcScNHTLfL9-Tws,21736
@@ -83,7 +83,7 @@ investing_algorithm_framework/cli/templates/run_backtest.py.template,sha256=mHwK
83
83
  investing_algorithm_framework/cli/templates/strategy.py.template,sha256=Ox8IZ6XlPDCCgq9T8KO3NazR2UXJs3FgkjbgfPqoad8,4603
84
84
  investing_algorithm_framework/create_app.py,sha256=HN_45Bza5Ro3o-v364m2mjSVjjZnyESOGHn3dcPDfQ4,1372
85
85
  investing_algorithm_framework/dependency_container.py,sha256=LIqK4fH2OdIKpvixzI2eSCXp6EtvEcWAJxJo-7a9qp4,6699
86
- investing_algorithm_framework/domain/__init__.py,sha256=PASQlRGcU_MDIwnLppanXGo-BUXdkhajvpRvcwqxdL0,4903
86
+ investing_algorithm_framework/domain/__init__.py,sha256=o2a3lAaCs4Jir88lSa8ZlwZ8Ghjwy1--S_9KDwny5MU,4931
87
87
  investing_algorithm_framework/domain/backtesting/__init__.py,sha256=q-NejGHzE233w5jXPhSsuLpBZ_yl3m-qb2g6FnxZaps,699
88
88
  investing_algorithm_framework/domain/backtesting/backtest.py,sha256=eRSaujcoggYdX3jmGO8KL4a2gOdYUeWH7Jx5vcLkeYg,17514
89
89
  investing_algorithm_framework/domain/backtesting/backtest_date_range.py,sha256=e_V7HMdtln4uu87jwwa_Yr7ZesgrpFqsEqtr0e0DTto,3186
@@ -98,7 +98,7 @@ investing_algorithm_framework/domain/constants.py,sha256=-ZU0z1DSgJaUQvkp_ELZslq
98
98
  investing_algorithm_framework/domain/data_provider.py,sha256=yMr7RWxHh6I9kSHsrwwukXi0k6UHLwmntIQGv0V0Q1w,11018
99
99
  investing_algorithm_framework/domain/data_structures.py,sha256=ePtdGhVaB16QLUvKQn5MiWM_TBOcBBTj5M0llW8tGEE,989
100
100
  investing_algorithm_framework/domain/decimal_parsing.py,sha256=NtMNkxZyWrFHxGKd6gLIDmWF88BYcTl8tYaAaKO1tlg,823
101
- investing_algorithm_framework/domain/exceptions.py,sha256=CjMPVqA5_hPoyeThH0vP-grGpmWXrKU_Tb19wWUJGqM,2359
101
+ investing_algorithm_framework/domain/exceptions.py,sha256=2BmMmpu3jFW7vJ4KVJw0AAPTS70yQ1NH9OMc-exEBuc,2768
102
102
  investing_algorithm_framework/domain/models/__init__.py,sha256=5SN_d8MTbQzgLIYpt0ySkG2UZ3MsUz_30w40-vxUmk0,1116
103
103
  investing_algorithm_framework/domain/models/app_mode.py,sha256=V1p9QMSNLlz6KjPib8d1J2EaSZh7jmXjZ1V2DFOrIaU,812
104
104
  investing_algorithm_framework/domain/models/base_model.py,sha256=1_DMaDR13gc6l5yWpMgKaAK7OJstc4lmvZV5DhwYM6o,659
@@ -253,8 +253,8 @@ investing_algorithm_framework/services/trade_order_evaluator/default_trade_order
253
253
  investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py,sha256=pNnmgaKMR9RY6Kxq7xS0nURKoaQDe2ehrP5GfElkkcI,1328
254
254
  investing_algorithm_framework/services/trade_service/__init__.py,sha256=AcwPyJjDRdiREnl_MWMkDSc-V-ZjXtvpHD6eQT9mc1o,68
255
255
  investing_algorithm_framework/services/trade_service/trade_service.py,sha256=OtzIS5EebByGcqDvV2AFeBjXSarvrgubMXDaVKg6Rbw,41193
256
- investing_algorithm_framework-7.18.0.dist-info/LICENSE,sha256=wbVEDvoZiMPHufRY3sLEffvAr7GH5hOIngHF8y4HFQg,11343
257
- investing_algorithm_framework-7.18.0.dist-info/METADATA,sha256=_8KvJKynhbGR8VmlZzsG6tY6D2u_EzA8iApv5zCkTjE,19635
258
- investing_algorithm_framework-7.18.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
259
- investing_algorithm_framework-7.18.0.dist-info/entry_points.txt,sha256=jrPF0YksDs27vYzEvj3tXLe3OGWU24EJA05z5xHqmq8,91
260
- investing_algorithm_framework-7.18.0.dist-info/RECORD,,
256
+ investing_algorithm_framework-7.19.1.dist-info/LICENSE,sha256=wbVEDvoZiMPHufRY3sLEffvAr7GH5hOIngHF8y4HFQg,11343
257
+ investing_algorithm_framework-7.19.1.dist-info/METADATA,sha256=NfXQinQSPYQibLY_6KTabg9vi7NUStbMosX5TAtfbew,19635
258
+ investing_algorithm_framework-7.19.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
259
+ investing_algorithm_framework-7.19.1.dist-info/entry_points.txt,sha256=jrPF0YksDs27vYzEvj3tXLe3OGWU24EJA05z5xHqmq8,91
260
+ investing_algorithm_framework-7.19.1.dist-info/RECORD,,