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.
- investing_algorithm_framework/__init__.py +3 -2
- investing_algorithm_framework/app/app.py +67 -1
- investing_algorithm_framework/domain/__init__.py +3 -2
- investing_algorithm_framework/domain/exceptions.py +17 -0
- {investing_algorithm_framework-7.18.0.dist-info → investing_algorithm_framework-7.19.1.dist-info}/METADATA +1 -1
- {investing_algorithm_framework-7.18.0.dist-info → investing_algorithm_framework-7.19.1.dist-info}/RECORD +9 -9
- {investing_algorithm_framework-7.18.0.dist-info → investing_algorithm_framework-7.19.1.dist-info}/LICENSE +0 -0
- {investing_algorithm_framework-7.18.0.dist-info → investing_algorithm_framework-7.19.1.dist-info}/WHEEL +0 -0
- {investing_algorithm_framework-7.18.0.dist-info → investing_algorithm_framework-7.19.1.dist-info}/entry_points.txt +0 -0
|
@@ -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,4 +1,4 @@
|
|
|
1
|
-
investing_algorithm_framework/__init__.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
257
|
-
investing_algorithm_framework-7.
|
|
258
|
-
investing_algorithm_framework-7.
|
|
259
|
-
investing_algorithm_framework-7.
|
|
260
|
-
investing_algorithm_framework-7.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|