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.
- investing_algorithm_framework/__init__.py +147 -44
- investing_algorithm_framework/app/__init__.py +23 -6
- investing_algorithm_framework/app/algorithm/algorithm.py +5 -41
- investing_algorithm_framework/app/algorithm/algorithm_factory.py +17 -10
- investing_algorithm_framework/app/analysis/__init__.py +15 -0
- investing_algorithm_framework/app/analysis/backtest_data_ranges.py +121 -0
- investing_algorithm_framework/app/analysis/backtest_utils.py +107 -0
- investing_algorithm_framework/app/analysis/permutation.py +116 -0
- investing_algorithm_framework/app/analysis/ranking.py +297 -0
- investing_algorithm_framework/app/app.py +1322 -707
- investing_algorithm_framework/app/context.py +196 -88
- investing_algorithm_framework/app/eventloop.py +590 -0
- investing_algorithm_framework/app/reporting/__init__.py +16 -5
- investing_algorithm_framework/app/reporting/ascii.py +57 -202
- investing_algorithm_framework/app/reporting/backtest_report.py +284 -170
- investing_algorithm_framework/app/reporting/charts/__init__.py +10 -2
- investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +66 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve.py +37 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +11 -26
- investing_algorithm_framework/app/reporting/charts/line_chart.py +11 -0
- investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +51 -0
- investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +1 -1
- investing_algorithm_framework/app/reporting/generate.py +100 -114
- investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +40 -32
- investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +34 -27
- investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +23 -19
- investing_algorithm_framework/app/reporting/tables/trades_table.py +1 -1
- investing_algorithm_framework/app/reporting/tables/utils.py +1 -0
- investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +10 -16
- investing_algorithm_framework/app/strategy.py +315 -175
- investing_algorithm_framework/app/task.py +5 -3
- investing_algorithm_framework/cli/cli.py +30 -12
- investing_algorithm_framework/cli/deploy_to_aws_lambda.py +131 -34
- investing_algorithm_framework/cli/initialize_app.py +20 -1
- investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +18 -6
- investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
- investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
- investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -2
- investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +1 -1
- investing_algorithm_framework/create_app.py +3 -5
- investing_algorithm_framework/dependency_container.py +25 -39
- investing_algorithm_framework/domain/__init__.py +45 -38
- investing_algorithm_framework/domain/backtesting/__init__.py +21 -0
- investing_algorithm_framework/domain/backtesting/backtest.py +503 -0
- investing_algorithm_framework/domain/backtesting/backtest_date_range.py +96 -0
- investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +242 -0
- investing_algorithm_framework/domain/backtesting/backtest_metrics.py +459 -0
- investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
- investing_algorithm_framework/domain/backtesting/backtest_run.py +605 -0
- investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
- investing_algorithm_framework/domain/backtesting/combine_backtests.py +280 -0
- investing_algorithm_framework/domain/config.py +27 -0
- investing_algorithm_framework/domain/constants.py +6 -34
- investing_algorithm_framework/domain/data_provider.py +200 -56
- investing_algorithm_framework/domain/exceptions.py +34 -1
- investing_algorithm_framework/domain/models/__init__.py +10 -19
- investing_algorithm_framework/domain/models/base_model.py +0 -6
- investing_algorithm_framework/domain/models/data/__init__.py +7 -0
- investing_algorithm_framework/domain/models/data/data_source.py +214 -0
- investing_algorithm_framework/domain/models/{market_data_type.py → data/data_type.py} +7 -7
- investing_algorithm_framework/domain/models/market/market_credential.py +6 -0
- investing_algorithm_framework/domain/models/order/order.py +34 -13
- investing_algorithm_framework/domain/models/order/order_status.py +1 -1
- investing_algorithm_framework/domain/models/order/order_type.py +1 -1
- investing_algorithm_framework/domain/models/portfolio/portfolio.py +14 -1
- investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +5 -1
- investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +51 -11
- investing_algorithm_framework/domain/models/position/__init__.py +2 -1
- investing_algorithm_framework/domain/models/position/position.py +9 -0
- investing_algorithm_framework/domain/models/position/position_size.py +41 -0
- investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
- investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
- investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
- investing_algorithm_framework/domain/models/snapshot_interval.py +0 -1
- investing_algorithm_framework/domain/models/strategy_profile.py +19 -151
- investing_algorithm_framework/domain/models/time_frame.py +7 -0
- investing_algorithm_framework/domain/models/time_interval.py +33 -0
- investing_algorithm_framework/domain/models/time_unit.py +63 -1
- investing_algorithm_framework/domain/models/trade/__init__.py +0 -2
- investing_algorithm_framework/domain/models/trade/trade.py +56 -32
- investing_algorithm_framework/domain/models/trade/trade_status.py +8 -2
- investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +106 -41
- investing_algorithm_framework/domain/models/trade/trade_take_profit.py +161 -99
- investing_algorithm_framework/domain/order_executor.py +19 -0
- investing_algorithm_framework/domain/portfolio_provider.py +20 -1
- investing_algorithm_framework/domain/services/__init__.py +0 -13
- investing_algorithm_framework/domain/strategy.py +1 -29
- investing_algorithm_framework/domain/utils/__init__.py +5 -1
- investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
- investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
- investing_algorithm_framework/domain/utils/polars.py +17 -14
- investing_algorithm_framework/download_data.py +40 -10
- investing_algorithm_framework/infrastructure/__init__.py +13 -25
- investing_algorithm_framework/infrastructure/data_providers/__init__.py +7 -4
- investing_algorithm_framework/infrastructure/data_providers/ccxt.py +811 -546
- investing_algorithm_framework/infrastructure/data_providers/csv.py +433 -122
- investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
- investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
- investing_algorithm_framework/infrastructure/database/sql_alchemy.py +81 -0
- investing_algorithm_framework/infrastructure/models/__init__.py +0 -13
- investing_algorithm_framework/infrastructure/models/order/order.py +9 -3
- investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +27 -8
- investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +21 -7
- investing_algorithm_framework/infrastructure/order_executors/__init__.py +2 -0
- investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
- investing_algorithm_framework/infrastructure/repositories/repository.py +16 -2
- investing_algorithm_framework/infrastructure/repositories/trade_repository.py +2 -2
- investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +6 -0
- investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +6 -0
- investing_algorithm_framework/infrastructure/services/__init__.py +0 -4
- investing_algorithm_framework/services/__init__.py +105 -8
- investing_algorithm_framework/services/backtesting/backtest_service.py +536 -476
- investing_algorithm_framework/services/configuration_service.py +14 -4
- investing_algorithm_framework/services/data_providers/__init__.py +5 -0
- investing_algorithm_framework/services/data_providers/data_provider_service.py +850 -0
- investing_algorithm_framework/{app/reporting → services}/metrics/__init__.py +48 -17
- investing_algorithm_framework/{app/reporting → services}/metrics/drawdown.py +10 -10
- investing_algorithm_framework/{app/reporting → services}/metrics/equity_curve.py +2 -2
- investing_algorithm_framework/{app/reporting → services}/metrics/exposure.py +60 -2
- investing_algorithm_framework/services/metrics/generate.py +358 -0
- investing_algorithm_framework/{app/reporting → services}/metrics/profit_factor.py +36 -0
- investing_algorithm_framework/{app/reporting → services}/metrics/recovery.py +2 -2
- investing_algorithm_framework/{app/reporting → services}/metrics/returns.py +146 -147
- investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
- investing_algorithm_framework/{app/reporting/metrics/sharp_ratio.py → services/metrics/sharpe_ratio.py} +6 -10
- investing_algorithm_framework/{app/reporting → services}/metrics/sortino_ratio.py +3 -7
- investing_algorithm_framework/services/metrics/trades.py +500 -0
- investing_algorithm_framework/services/metrics/volatility.py +97 -0
- investing_algorithm_framework/{app/reporting → services}/metrics/win_rate.py +70 -3
- investing_algorithm_framework/services/order_service/order_backtest_service.py +21 -31
- investing_algorithm_framework/services/order_service/order_service.py +9 -71
- investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +0 -2
- investing_algorithm_framework/services/portfolios/portfolio_service.py +3 -13
- investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +62 -96
- investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -3
- investing_algorithm_framework/services/repository_service.py +5 -2
- investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
- investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +113 -0
- investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
- investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
- investing_algorithm_framework/services/trade_service/__init__.py +7 -1
- investing_algorithm_framework/services/trade_service/trade_service.py +51 -29
- investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
- investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
- investing_algorithm_framework-7.19.15.dist-info/METADATA +537 -0
- {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/RECORD +159 -148
- investing_algorithm_framework/app/reporting/evaluation.py +0 -243
- investing_algorithm_framework/app/reporting/metrics/risk_free_rate.py +0 -8
- investing_algorithm_framework/app/reporting/metrics/volatility.py +0 -69
- investing_algorithm_framework/cli/templates/requirements_azure_function.txt.template +0 -3
- investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -9
- investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -47
- investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -120
- investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
- investing_algorithm_framework/domain/models/backtesting/backtest_results.py +0 -440
- investing_algorithm_framework/domain/models/data_source.py +0 -21
- investing_algorithm_framework/domain/models/date_range.py +0 -64
- investing_algorithm_framework/domain/models/trade/trade_risk_type.py +0 -34
- investing_algorithm_framework/domain/models/trading_data_types.py +0 -48
- investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
- investing_algorithm_framework/domain/services/market_data_sources.py +0 -543
- investing_algorithm_framework/domain/services/market_service.py +0 -153
- investing_algorithm_framework/domain/services/observable.py +0 -51
- investing_algorithm_framework/domain/services/observer.py +0 -19
- investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -16
- investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -746
- investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -270
- investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +0 -312
- investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -5
- investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -471
- investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -7
- investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -2
- investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -322
- investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -10
- investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -269
- investing_algorithm_framework/services/market_data_source_service/data_provider_service.py +0 -350
- investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -377
- investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -296
- investing_algorithm_framework-6.9.1.dist-info/METADATA +0 -440
- /investing_algorithm_framework/{app/reporting → services}/metrics/alpha.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/beta.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/cagr.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/calmar_ratio.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/mean_daily_return.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/price_efficiency.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/standard_deviation.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/treynor_ratio.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/ulcer.py +0 -0
- /investing_algorithm_framework/{app/reporting → services}/metrics/value_at_risk.py +0 -0
- {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/LICENSE +0 -0
- {investing_algorithm_framework-6.9.1.dist-info → investing_algorithm_framework-7.19.15.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
39
|
+
df = data.to_pandas().copy()
|
|
33
40
|
|
|
34
|
-
if
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
"
|
|
41
|
+
"CSVOHLCVDataProvider",
|
|
55
42
|
"CCXTOrderExecutor",
|
|
56
43
|
"CCXTPortfolioProvider",
|
|
57
44
|
"get_default_data_providers",
|
|
58
45
|
"get_default_ohlcv_data_providers",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
46
|
+
"AWSS3StorageStateHandler",
|
|
47
|
+
"CCXTOHLCVDataProvider",
|
|
48
|
+
"BacktestOrderExecutor",
|
|
49
|
+
"PandasOHLCVDataProvider",
|
|
62
50
|
]
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
from .ccxt import
|
|
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
|
-
|
|
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
|
-
'
|
|
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
|
]
|