investing-algorithm-framework 3.7.2__tar.gz → 3.8__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.
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/PKG-INFO +10 -5
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/README.md +5 -2
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/__init__.py +4 -10
- investing_algorithm_framework-3.8/investing_algorithm_framework/deployment/__init__.py +3 -0
- investing_algorithm_framework-3.8/investing_algorithm_framework/deployment/azure/__init__.py +3 -0
- investing_algorithm_framework-3.8/investing_algorithm_framework/deployment/azure/azure_functions.py +102 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/__init__.py +5 -7
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/__init__.py +3 -1
- investing_algorithm_framework-3.8/investing_algorithm_framework/domain/models/date_range.py +56 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/market_data_sources.py +169 -17
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/__init__.py +2 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/backtesting.py +1 -1
- investing_algorithm_framework-3.8/investing_algorithm_framework/domain/utils/polars.py +41 -0
- investing_algorithm_framework-3.8/investing_algorithm_framework/indicators/__init__.py +13 -0
- investing_algorithm_framework-3.8/investing_algorithm_framework/indicators/advanced.py +224 -0
- investing_algorithm_framework-3.8/investing_algorithm_framework/indicators/trend.py +339 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +184 -34
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +6 -6
- investing_algorithm_framework-3.8/investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +182 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +17 -3
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +2 -2
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/order_service/order_backtest_service.py +4 -4
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/pyproject.toml +5 -2
- investing_algorithm_framework-3.7.2/investing_algorithm_framework/domain/graphs.py +0 -382
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/LICENSE +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/algorithm.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/app.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/strategy.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/task.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/create_app.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/error_handler.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/responses.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/create_app.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/dependency_container.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/config.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/constants.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/data_structures.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/exceptions.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/metrics/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/metrics/price_efficiency.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/base_model.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/order/order.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/position/position.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/trade/trade.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/market_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/singleton.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/strategy.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/csv.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/random.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/backtesting/backtest_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/backtesting/graphs.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/configuration_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/order_service/order_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/position_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/repository_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
- {investing_algorithm_framework-3.7.2 → investing_algorithm_framework-3.8}/investing_algorithm_framework/services/trade_service/trade_service.py +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: investing-algorithm-framework
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8
|
|
4
4
|
Summary: A framework for creating trading bots
|
|
5
5
|
Author: MDUYN
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
9
8
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -18,12 +17,15 @@ Requires-Dist: ccxt (>=4.2.48,<5.0.0)
|
|
|
18
17
|
Requires-Dist: dependency-injector (>=4.40.0,<5.0.0)
|
|
19
18
|
Requires-Dist: jupyter (>=1.0.0,<2.0.0)
|
|
20
19
|
Requires-Dist: marshmallow (>=3.5.0,<4.0.0)
|
|
20
|
+
Requires-Dist: numpy (>=2.1.3,<3.0.0)
|
|
21
21
|
Requires-Dist: plotly (>=5.22.0,<6.0.0)
|
|
22
22
|
Requires-Dist: polars[numpy,pandas] (>=0.20.10,<0.21.0)
|
|
23
23
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
|
24
24
|
Requires-Dist: schedule (>=1.1.0,<2.0.0)
|
|
25
|
+
Requires-Dist: scipy (>=1.14.1,<2.0.0)
|
|
25
26
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
26
27
|
Requires-Dist: tqdm (>=4.66.1,<5.0.0)
|
|
28
|
+
Requires-Dist: tulipy (>=0.4.0,<0.5.0)
|
|
27
29
|
Requires-Dist: wrapt (>=1.16.0,<2.0.0)
|
|
28
30
|
Description-Content-Type: text/markdown
|
|
29
31
|
|
|
@@ -61,6 +63,9 @@ Features:
|
|
|
61
63
|
* Stateless running for cloud function deployments
|
|
62
64
|
* Polars dataframes support out of the box for fast data processing [pola.rs](https://pola.rs/)
|
|
63
65
|
|
|
66
|
+
Additional features:
|
|
67
|
+
* Indicators (python >= 3.10 required): Set of indicators that can be used in your trading bot. You can donwload the package with `pip install investing-algorithm-framework[indicators]` or `poetry add investing-algorithm-framework[indicators]]`
|
|
68
|
+
|
|
64
69
|
## Example implementation
|
|
65
70
|
The following algorithm connects to binance and buys BTC every 5 seconds.
|
|
66
71
|
It also exposes an REST API that allows you to interact with the algorithm.
|
|
@@ -77,7 +82,7 @@ symbols = ["BTC/EUR"]
|
|
|
77
82
|
|
|
78
83
|
# Define resource directory and the symbols you want to trade
|
|
79
84
|
config = {
|
|
80
|
-
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()
|
|
85
|
+
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve(),
|
|
81
86
|
SYMBOLS: symbols
|
|
82
87
|
}
|
|
83
88
|
|
|
@@ -87,7 +92,7 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
|
87
92
|
identifier="BTC-ohlcv",
|
|
88
93
|
market="BITVAVO",
|
|
89
94
|
symbol="BTC/EUR",
|
|
90
|
-
|
|
95
|
+
time_frame="2h",
|
|
91
96
|
window_size=200
|
|
92
97
|
)
|
|
93
98
|
# Ticker data for orders, trades and positions
|
|
@@ -32,6 +32,9 @@ Features:
|
|
|
32
32
|
* Stateless running for cloud function deployments
|
|
33
33
|
* Polars dataframes support out of the box for fast data processing [pola.rs](https://pola.rs/)
|
|
34
34
|
|
|
35
|
+
Additional features:
|
|
36
|
+
* Indicators (python >= 3.10 required): Set of indicators that can be used in your trading bot. You can donwload the package with `pip install investing-algorithm-framework[indicators]` or `poetry add investing-algorithm-framework[indicators]]`
|
|
37
|
+
|
|
35
38
|
## Example implementation
|
|
36
39
|
The following algorithm connects to binance and buys BTC every 5 seconds.
|
|
37
40
|
It also exposes an REST API that allows you to interact with the algorithm.
|
|
@@ -48,7 +51,7 @@ symbols = ["BTC/EUR"]
|
|
|
48
51
|
|
|
49
52
|
# Define resource directory and the symbols you want to trade
|
|
50
53
|
config = {
|
|
51
|
-
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()
|
|
54
|
+
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve(),
|
|
52
55
|
SYMBOLS: symbols
|
|
53
56
|
}
|
|
54
57
|
|
|
@@ -58,7 +61,7 @@ bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
|
|
|
58
61
|
identifier="BTC-ohlcv",
|
|
59
62
|
market="BITVAVO",
|
|
60
63
|
symbol="BTC/EUR",
|
|
61
|
-
|
|
64
|
+
time_frame="2h",
|
|
62
65
|
window_size=200
|
|
63
66
|
)
|
|
64
67
|
# Ticker data for orders, trades and positions
|
|
@@ -10,15 +10,13 @@ from investing_algorithm_framework.domain import ApiException, \
|
|
|
10
10
|
TickerMarketDataSource, MarketService, BacktestReportsEvaluation, \
|
|
11
11
|
pretty_print_backtest_reports_evaluation, load_backtest_reports, \
|
|
12
12
|
RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
|
|
13
|
-
load_backtest_report, BacktestDateRange,
|
|
14
|
-
|
|
13
|
+
load_backtest_report, BacktestDateRange, convert_polars_to_pandas, \
|
|
14
|
+
DateRange
|
|
15
15
|
from investing_algorithm_framework.infrastructure import \
|
|
16
16
|
CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
|
|
17
17
|
CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
|
|
18
18
|
CSVTickerMarketDataSource
|
|
19
19
|
from .create_app import create_app
|
|
20
|
-
from investing_algorithm_framework.services import \
|
|
21
|
-
create_trade_exit_markers_chart, create_trade_entry_markers_chart
|
|
22
20
|
|
|
23
21
|
__all__ = [
|
|
24
22
|
"Algorithm",
|
|
@@ -67,10 +65,6 @@ __all__ = [
|
|
|
67
65
|
"DATETIME_FORMAT",
|
|
68
66
|
"load_backtest_report",
|
|
69
67
|
"BacktestDateRange",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"create_ema_graph",
|
|
73
|
-
"create_prices_graph",
|
|
74
|
-
"create_rsi_graph",
|
|
75
|
-
"get_price_efficiency_ratio"
|
|
68
|
+
"convert_polars_to_pandas",
|
|
69
|
+
"DateRange"
|
|
76
70
|
]
|
investing_algorithm_framework-3.8/investing_algorithm_framework/deployment/azure/azure_functions.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# import os
|
|
2
|
+
# import json
|
|
3
|
+
# from azure.identity import DefaultAzureCredential
|
|
4
|
+
# from azure.mgmt.resource import ResourceManagementClient
|
|
5
|
+
# from azure.mgmt.storage import StorageManagementClient
|
|
6
|
+
# from azure.mgmt.web import WebSiteManagementClient
|
|
7
|
+
# import shutil
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# def deploy_to_azure_functions(azure_credentials_json, azure_function_path):
|
|
11
|
+
# """
|
|
12
|
+
# This function deploys a Python function app to Azure Functions.
|
|
13
|
+
|
|
14
|
+
# Parameters:
|
|
15
|
+
# - azure_credentials_json (str): Path to the Azure credentials
|
|
16
|
+
# JSON file.
|
|
17
|
+
# - azure_function_path (str): Path to the Python function
|
|
18
|
+
# app directory.
|
|
19
|
+
|
|
20
|
+
# Returns:
|
|
21
|
+
# None
|
|
22
|
+
# """
|
|
23
|
+
|
|
24
|
+
# # Load Azure credentials
|
|
25
|
+
# with open('azure_credentials.json') as f:
|
|
26
|
+
# credentials = json.load(f)
|
|
27
|
+
|
|
28
|
+
# SUBSCRIPTION_ID = credentials['subscriptionId']
|
|
29
|
+
# RESOURCE_GROUP_NAME = "myResourceGroup"
|
|
30
|
+
# LOCATION = "eastus"
|
|
31
|
+
# STORAGE_ACCOUNT_NAME = "mystorageaccount123"
|
|
32
|
+
# FUNCTION_APP_NAME = "my-python-function-app"
|
|
33
|
+
|
|
34
|
+
# # Authenticate using DefaultAzureCredential
|
|
35
|
+
# credential = DefaultAzureCredential()
|
|
36
|
+
|
|
37
|
+
# # Clients
|
|
38
|
+
# resource_client = ResourceManagementClient(credential, SUBSCRIPTION_ID)
|
|
39
|
+
# storage_client = StorageManagementClient(credential, SUBSCRIPTION_ID)
|
|
40
|
+
# web_client = WebSiteManagementClient(credential, SUBSCRIPTION_ID)
|
|
41
|
+
|
|
42
|
+
# # Create Resource Group
|
|
43
|
+
# resource_client.resource_groups.create_or_update(RESOURCE_GROUP_NAME,
|
|
44
|
+
# {"location": LOCATION})
|
|
45
|
+
|
|
46
|
+
# # Create Storage Account
|
|
47
|
+
# storage_client.storage_accounts.begin_create(
|
|
48
|
+
# RESOURCE_GROUP_NAME,
|
|
49
|
+
# STORAGE_ACCOUNT_NAME,
|
|
50
|
+
# {
|
|
51
|
+
# "sku": {"name": "Standard_LRS"},
|
|
52
|
+
# "kind": "StorageV2",
|
|
53
|
+
# "location": LOCATION
|
|
54
|
+
# }
|
|
55
|
+
# ).result()
|
|
56
|
+
|
|
57
|
+
# # Create Function App (with a Consumption Plan)
|
|
58
|
+
# site_config = {
|
|
59
|
+
# "location": LOCATION,
|
|
60
|
+
# "server_farm_id": f"/subscriptions/{SUBSCRIPTION_ID}" +
|
|
61
|
+
# "/resourceGroups" +
|
|
62
|
+
# "/{RESOURCE_GROUP_NAME}/providers/Microsoft.Web/" +
|
|
63
|
+
# "serverfarms/{APP_SERVICE_PLAN_NAME}",
|
|
64
|
+
# "reserved": True, # This is necessary for Linux-based function apps
|
|
65
|
+
# "site_config": {
|
|
66
|
+
# "app_settings": [
|
|
67
|
+
# {
|
|
68
|
+
# "name": "FUNCTIONS_WORKER_RUNTIME", "value": "python"
|
|
69
|
+
# },
|
|
70
|
+
# {
|
|
71
|
+
# "name": "AzureWebJobsStorage",
|
|
72
|
+
# "value": "DefaultEndpointsProtocol=https;" +
|
|
73
|
+
# f"AccountName={STORAGE_ACCOUNT_NAME}" +
|
|
74
|
+
# ";AccountKey=account_key>",
|
|
75
|
+
# }
|
|
76
|
+
# ]
|
|
77
|
+
# },
|
|
78
|
+
# "kind": "functionapp",
|
|
79
|
+
# }
|
|
80
|
+
|
|
81
|
+
# web_client.web_apps.begin_create_or_update(RESOURCE_GROUP_NAME,
|
|
82
|
+
# FUNCTION_APP_NAME,
|
|
83
|
+
# site_config).result()
|
|
84
|
+
|
|
85
|
+
# # Zip Function Code
|
|
86
|
+
# def zipdir(path, zipfile):
|
|
87
|
+
# for root, dirs, files in os.walk(path):
|
|
88
|
+
# for file in files:
|
|
89
|
+
# zipfile.write(os.path.join(root, file),
|
|
90
|
+
# os.path.relpath(os.path.join(root, file), path))
|
|
91
|
+
|
|
92
|
+
# shutil.make_archive('myfunctionapp', 'zip', 'myfunctionapp/')
|
|
93
|
+
|
|
94
|
+
# # Deploy Function Code
|
|
95
|
+
# def deploy_function():
|
|
96
|
+
# with open("myfunctionapp.zip", "rb") as z:
|
|
97
|
+
# web_client.web_apps.begin_create_zip_deployment(
|
|
98
|
+
# RESOURCE_GROUP_NAME, FUNCTION_APP_NAME, z).result()
|
|
99
|
+
|
|
100
|
+
# deploy_function()
|
|
101
|
+
|
|
102
|
+
# print(f"Function app '{FUNCTION_APP_NAME}' deployed to Azure.")
|
|
@@ -17,7 +17,7 @@ from .models import OrderStatus, OrderSide, OrderType, TimeInterval, \
|
|
|
17
17
|
PortfolioConfiguration, Portfolio, Position, Order, TradeStatus, \
|
|
18
18
|
BacktestReport, PortfolioSnapshot, StrategyProfile, \
|
|
19
19
|
BacktestPosition, Trade, MarketCredential, PositionSnapshot, \
|
|
20
|
-
BacktestReportsEvaluation, AppMode, BacktestDateRange
|
|
20
|
+
BacktestReportsEvaluation, AppMode, BacktestDateRange, DateRange
|
|
21
21
|
from .services import TickerMarketDataSource, OrderBookMarketDataSource, \
|
|
22
22
|
OHLCVMarketDataSource, BacktestMarketDataSource, MarketDataSource, \
|
|
23
23
|
MarketService, MarketCredentialService, AbstractPortfolioSyncService, \
|
|
@@ -27,10 +27,9 @@ 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
|
+
load_backtest_report, convert_polars_to_pandas, \
|
|
31
31
|
csv_to_list, StoppableThread, pretty_print_backtest_reports_evaluation, \
|
|
32
32
|
pretty_print_backtest, load_csv_into_dict, load_backtest_reports
|
|
33
|
-
from .graphs import create_prices_graph, create_ema_graph, create_rsi_graph
|
|
34
33
|
from .metrics import get_price_efficiency_ratio
|
|
35
34
|
|
|
36
35
|
__all__ = [
|
|
@@ -116,8 +115,7 @@ __all__ = [
|
|
|
116
115
|
"RoundingService",
|
|
117
116
|
"BacktestDateRange",
|
|
118
117
|
"load_backtest_report",
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"get_price_efficiency_ratio"
|
|
118
|
+
"get_price_efficiency_ratio",
|
|
119
|
+
"convert_polars_to_pandas",
|
|
120
|
+
"DateRange"
|
|
123
121
|
]
|
|
@@ -12,6 +12,7 @@ from .time_unit import TimeUnit
|
|
|
12
12
|
from .trade import Trade, TradeStatus
|
|
13
13
|
from .trading_data_types import TradingDataType
|
|
14
14
|
from .trading_time_frame import TradingTimeFrame
|
|
15
|
+
from .date_range import DateRange
|
|
15
16
|
|
|
16
17
|
__all__ = [
|
|
17
18
|
"OrderStatus",
|
|
@@ -36,5 +37,6 @@ __all__ = [
|
|
|
36
37
|
"TradeStatus",
|
|
37
38
|
"BacktestReportsEvaluation",
|
|
38
39
|
"AppMode",
|
|
39
|
-
"BacktestDateRange"
|
|
40
|
+
"BacktestDateRange",
|
|
41
|
+
"DateRange",
|
|
40
42
|
]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DateRange:
|
|
6
|
+
"""
|
|
7
|
+
DateRange class. This class is used to define a date range and the name of
|
|
8
|
+
the range. Also, it can be used to store trading metadata such as
|
|
9
|
+
classification of the trend (Up or Down).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
start_date: datetime,
|
|
15
|
+
end_date: datetime,
|
|
16
|
+
name: str,
|
|
17
|
+
up_trend: bool = False,
|
|
18
|
+
down_trend: bool = False
|
|
19
|
+
):
|
|
20
|
+
self.start_date = start_date
|
|
21
|
+
self.end_date = end_date
|
|
22
|
+
self.name = name
|
|
23
|
+
self._up_trend = up_trend
|
|
24
|
+
self._down_trend = down_trend
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def up_trend(self) -> Union[bool, None]:
|
|
28
|
+
|
|
29
|
+
if self._up_trend and not self._down_trend:
|
|
30
|
+
return True
|
|
31
|
+
else:
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
@up_trend.setter
|
|
35
|
+
def up_trend(self, value: bool):
|
|
36
|
+
self._up_trend = value
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def down_trend(self) -> Union[bool, None]:
|
|
40
|
+
|
|
41
|
+
if self._down_trend and not self._up_trend:
|
|
42
|
+
return True
|
|
43
|
+
else:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
@down_trend.setter
|
|
47
|
+
def down_trend(self, value: bool):
|
|
48
|
+
self._down_trend = value
|
|
49
|
+
|
|
50
|
+
def __str__(self):
|
|
51
|
+
return f"DateRange({self.start_date}, {self.end_date}, {self.name})"
|
|
52
|
+
|
|
53
|
+
def __repr__(self):
|
|
54
|
+
return f"DateRange(Name: {self.name} " + \
|
|
55
|
+
f"Start date: {self.start_date} " + \
|
|
56
|
+
f"End date: {self.end_date})"
|
|
@@ -96,7 +96,7 @@ class BacktestMarketDataSource(ABC):
|
|
|
96
96
|
:param kwargs: Additional arguments to get the data. Common arguments
|
|
97
97
|
- start_date: datetime
|
|
98
98
|
- end_date: datetime
|
|
99
|
-
-
|
|
99
|
+
- time_frame: str
|
|
100
100
|
- backtest_start_date: datetime
|
|
101
101
|
- backtest_end_date: datetime
|
|
102
102
|
- backtest_data_index_date: datetime
|
|
@@ -160,12 +160,14 @@ class MarketDataSource(ABC):
|
|
|
160
160
|
identifier,
|
|
161
161
|
market,
|
|
162
162
|
symbol,
|
|
163
|
+
storage_path=None
|
|
163
164
|
):
|
|
164
165
|
self._identifier = identifier
|
|
165
166
|
self._market = market
|
|
166
167
|
self._symbol = symbol
|
|
167
168
|
self._market_credential_service = None
|
|
168
169
|
self._config = None
|
|
170
|
+
self._storage_path = storage_path
|
|
169
171
|
|
|
170
172
|
@property
|
|
171
173
|
def config(self):
|
|
@@ -199,6 +201,13 @@ class MarketDataSource(ABC):
|
|
|
199
201
|
def get_symbol(self):
|
|
200
202
|
return self.symbol
|
|
201
203
|
|
|
204
|
+
@property
|
|
205
|
+
def storage_path(self):
|
|
206
|
+
return self._storage_path
|
|
207
|
+
|
|
208
|
+
def get_storage_path(self):
|
|
209
|
+
return self.storage_path
|
|
210
|
+
|
|
202
211
|
@abstractmethod
|
|
203
212
|
def get_data(self, **kwargs):
|
|
204
213
|
"""
|
|
@@ -206,7 +215,7 @@ class MarketDataSource(ABC):
|
|
|
206
215
|
:param kwargs: Additional arguments to get the data. Common arguments
|
|
207
216
|
- start_date: datetime
|
|
208
217
|
- end_date: datetime
|
|
209
|
-
-
|
|
218
|
+
- time_frame: str
|
|
210
219
|
|
|
211
220
|
:return: Object with the data
|
|
212
221
|
"""
|
|
@@ -224,6 +233,147 @@ class MarketDataSource(ABC):
|
|
|
224
233
|
def market_credential_service(self, value):
|
|
225
234
|
self._market_credential_service = value
|
|
226
235
|
|
|
236
|
+
@staticmethod
|
|
237
|
+
def get_file_name_symbol(file_path):
|
|
238
|
+
"""
|
|
239
|
+
Static function that extracts the symbol from a give data filepath,
|
|
240
|
+
given that the data file path is in the format
|
|
241
|
+
{DATA_TYPE}_{TARGET_SYMBOL}_{TRADING_SYMBOL}_{MARKET}_
|
|
242
|
+
{time_frame}_{START_DATETIME}_{END_DATETIME}.csv
|
|
243
|
+
|
|
244
|
+
Parameters:
|
|
245
|
+
file_path: str - the given file path of
|
|
246
|
+
the data storage file
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
string representing the symbol
|
|
250
|
+
"""
|
|
251
|
+
parts = file_path.split("_")
|
|
252
|
+
|
|
253
|
+
if len(parts) < 6:
|
|
254
|
+
return None
|
|
255
|
+
|
|
256
|
+
return "".join([parts[1], '/', parts[2]])
|
|
257
|
+
|
|
258
|
+
@staticmethod
|
|
259
|
+
def get_file_name_time_frame(file_path):
|
|
260
|
+
"""
|
|
261
|
+
Static function that extracts the time_frame from a give data filepath,
|
|
262
|
+
given that the data file path is in the format
|
|
263
|
+
{DATA_TYPE}_{TARGET_SYMBOL}_{TRADING_SYMBOL}_{MARKET}_
|
|
264
|
+
{time_frame}_{START_DATETIME}_{END_DATETIME}.csv
|
|
265
|
+
|
|
266
|
+
Parameters:
|
|
267
|
+
file_path: str - the given file path of the data storage file
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
string representing the time_frame
|
|
271
|
+
"""
|
|
272
|
+
parts = file_path.split("_")
|
|
273
|
+
|
|
274
|
+
if len(parts) < 6:
|
|
275
|
+
return None
|
|
276
|
+
|
|
277
|
+
return TimeFrame.from_string(parts[4])
|
|
278
|
+
|
|
279
|
+
@staticmethod
|
|
280
|
+
def get_file_name_market(file_path):
|
|
281
|
+
"""
|
|
282
|
+
Static function that extracts the time_frame from a give data filepath,
|
|
283
|
+
given that the data file path is in the format
|
|
284
|
+
{DATA_TYPE}_{TARGET_SYMBOL}_{TRADING_SYMBOL}_{MARKET}
|
|
285
|
+
_{time_frame}_{START_DATETIME}_{END_DATETIME}.csv
|
|
286
|
+
|
|
287
|
+
Parameters:
|
|
288
|
+
file_path: str - the given file path of the data storage file
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
string representing the market
|
|
292
|
+
"""
|
|
293
|
+
parts = file_path.split("_")
|
|
294
|
+
|
|
295
|
+
if len(parts) < 6:
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
return TimeFrame.from_string(parts[3])
|
|
299
|
+
|
|
300
|
+
@staticmethod
|
|
301
|
+
def get_file_name_start_datetime(file_path):
|
|
302
|
+
"""
|
|
303
|
+
Static function that extracts the time_frame from a give data filepath,
|
|
304
|
+
given that the data file path is in the format
|
|
305
|
+
{DATA_TYPE}_{TARGET_SYMBOL}_{TRADING_SYMBOL}_{MARKET}_
|
|
306
|
+
{time_frame}_{START_DATETIME}_{END_DATETIME}.csv
|
|
307
|
+
|
|
308
|
+
Parameters:
|
|
309
|
+
file_path: str - the given file path of the data storage file
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
string representing the start datetime
|
|
313
|
+
"""
|
|
314
|
+
parts = file_path.split("_")
|
|
315
|
+
|
|
316
|
+
if len(parts) < 6:
|
|
317
|
+
return None
|
|
318
|
+
|
|
319
|
+
return TimeFrame.from_string(parts[5])
|
|
320
|
+
|
|
321
|
+
@staticmethod
|
|
322
|
+
def get_file_name_end_datetime(file_path):
|
|
323
|
+
"""
|
|
324
|
+
Static function that extracts the time_frame
|
|
325
|
+
from a give data filepath, given that the data file
|
|
326
|
+
path is in the format
|
|
327
|
+
{DATA_TYPE}_{TARGET_SYMBOL}_{TRADING_SYMBOL}_{MARKET}_
|
|
328
|
+
{time_frame}_{START_DATETIME}_{END_DATETIME}.csv
|
|
329
|
+
|
|
330
|
+
Parameters:
|
|
331
|
+
file_path: str - the given file path of the data storage file
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
string representing the end datetime
|
|
335
|
+
"""
|
|
336
|
+
parts = file_path.split("_")
|
|
337
|
+
|
|
338
|
+
if len(parts) < 6:
|
|
339
|
+
return None
|
|
340
|
+
|
|
341
|
+
return TimeFrame.from_string(parts[6])
|
|
342
|
+
|
|
343
|
+
@staticmethod
|
|
344
|
+
def create_storage_file_path(
|
|
345
|
+
storage_path,
|
|
346
|
+
data_type,
|
|
347
|
+
symbol,
|
|
348
|
+
market,
|
|
349
|
+
time_frame,
|
|
350
|
+
start_datetime,
|
|
351
|
+
end_datetime,
|
|
352
|
+
):
|
|
353
|
+
"""
|
|
354
|
+
Static function that creates a storage file path given the parameters
|
|
355
|
+
|
|
356
|
+
Parameters:
|
|
357
|
+
storage_path: str - the storage path of the data storage file
|
|
358
|
+
data_type: str - the type of data
|
|
359
|
+
symbol: str - the asset symbol
|
|
360
|
+
market: str - the market
|
|
361
|
+
time_frame: str - the time_frame
|
|
362
|
+
start_datetime: datetime - the start datetime
|
|
363
|
+
end_datetime: datetime - the end datetime
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
string representing the storage file path
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
target_symbol, trading_symbol = symbol.split('/')
|
|
370
|
+
path = os.path.join(
|
|
371
|
+
storage_path,
|
|
372
|
+
f"{data_type}_{target_symbol}_{trading_symbol}_{market}_" +
|
|
373
|
+
f"{time_frame}_{start_datetime}_{end_datetime}.csv"
|
|
374
|
+
)
|
|
375
|
+
return path
|
|
376
|
+
|
|
227
377
|
|
|
228
378
|
class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
229
379
|
"""
|
|
@@ -234,30 +384,32 @@ class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
|
234
384
|
identifier,
|
|
235
385
|
market,
|
|
236
386
|
symbol,
|
|
237
|
-
|
|
387
|
+
time_frame,
|
|
238
388
|
window_size=None,
|
|
389
|
+
storage_path=None,
|
|
239
390
|
):
|
|
240
391
|
super().__init__(
|
|
241
392
|
identifier=identifier,
|
|
242
393
|
market=market,
|
|
243
394
|
symbol=symbol,
|
|
395
|
+
storage_path=storage_path
|
|
244
396
|
)
|
|
245
397
|
self._window_size = window_size
|
|
246
|
-
self.
|
|
398
|
+
self._time_frame = time_frame
|
|
247
399
|
|
|
248
400
|
@property
|
|
249
|
-
def
|
|
250
|
-
return self.
|
|
401
|
+
def time_frame(self):
|
|
402
|
+
return self._time_frame
|
|
251
403
|
|
|
252
|
-
def
|
|
253
|
-
return self.
|
|
404
|
+
def get_time_frame(self):
|
|
405
|
+
return self.time_frame
|
|
254
406
|
|
|
255
|
-
def create_start_date(self, end_date,
|
|
256
|
-
minutes = TimeFrame.from_value(
|
|
407
|
+
def create_start_date(self, end_date, time_frame, window_size):
|
|
408
|
+
minutes = TimeFrame.from_value(time_frame).amount_of_minutes
|
|
257
409
|
return end_date - timedelta(minutes=window_size * minutes)
|
|
258
410
|
|
|
259
|
-
def create_end_date(self, start_date,
|
|
260
|
-
minutes = TimeFrame.from_value(
|
|
411
|
+
def create_end_date(self, start_date, time_frame, window_size):
|
|
412
|
+
minutes = TimeFrame.from_value(time_frame).amount_of_minutes
|
|
261
413
|
return start_date + timedelta(minutes=window_size * minutes)
|
|
262
414
|
|
|
263
415
|
@property
|
|
@@ -279,11 +431,11 @@ class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
|
279
431
|
start_date: datetime,
|
|
280
432
|
end_date: datetime,
|
|
281
433
|
window_size: int,
|
|
282
|
-
|
|
434
|
+
time_frame
|
|
283
435
|
):
|
|
284
436
|
"""
|
|
285
437
|
Function to get the date ranges of the market data source based
|
|
286
|
-
on the window size and the
|
|
438
|
+
on the window size and the time_frame. The date ranges
|
|
287
439
|
will be calculated based on the start date and the end date.
|
|
288
440
|
"""
|
|
289
441
|
|
|
@@ -292,9 +444,9 @@ class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
|
292
444
|
"Start date must be before end date"
|
|
293
445
|
)
|
|
294
446
|
|
|
295
|
-
|
|
447
|
+
time_frame = TimeFrame.from_value(time_frame)
|
|
296
448
|
new_end_date = start_date + timedelta(
|
|
297
|
-
minutes=window_size *
|
|
449
|
+
minutes=window_size * time_frame.amount_of_minutes
|
|
298
450
|
)
|
|
299
451
|
ranges = [(start_date, new_end_date)]
|
|
300
452
|
start_date = new_end_date
|
|
@@ -304,7 +456,7 @@ class OHLCVMarketDataSource(MarketDataSource, ABC):
|
|
|
304
456
|
|
|
305
457
|
while start_date < end_date:
|
|
306
458
|
new_end_date = start_date + timedelta(
|
|
307
|
-
minutes=self.window_size *
|
|
459
|
+
minutes=self.window_size * time_frame.amount_of_minutes
|
|
308
460
|
)
|
|
309
461
|
|
|
310
462
|
if new_end_date > end_date:
|
|
@@ -5,6 +5,7 @@ from .csv import get_total_amount_of_rows, append_dict_as_row_to_csv, \
|
|
|
5
5
|
from .random import random_string
|
|
6
6
|
from .stoppable_thread import StoppableThread
|
|
7
7
|
from .synchronized import synchronized
|
|
8
|
+
from .polars import convert_polars_to_pandas
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
10
11
|
'synchronized',
|
|
@@ -19,4 +20,5 @@ __all__ = [
|
|
|
19
20
|
'load_csv_into_dict',
|
|
20
21
|
'load_backtest_report',
|
|
21
22
|
'load_backtest_reports',
|
|
23
|
+
'convert_polars_to_pandas'
|
|
22
24
|
]
|
|
@@ -345,7 +345,7 @@ def pretty_print_backtest(
|
|
|
345
345
|
"""
|
|
346
346
|
|
|
347
347
|
print(ascii_art)
|
|
348
|
-
pretty_print_price_efficiency([backtest_report], precision=precision)
|
|
348
|
+
# pretty_print_price_efficiency([backtest_report], precision=precision)
|
|
349
349
|
|
|
350
350
|
if show_positions:
|
|
351
351
|
print(f"{COLOR_YELLOW}Positions overview{COLOR_RESET}")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pandas import to_datetime
|
|
2
|
+
from polars import DataFrame as PolarsDataFrame
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def convert_polars_to_pandas(
|
|
6
|
+
data: PolarsDataFrame,
|
|
7
|
+
remove_duplicates=True,
|
|
8
|
+
add_index=True,
|
|
9
|
+
datetime_column_name="Datetime"
|
|
10
|
+
):
|
|
11
|
+
"""
|
|
12
|
+
Function to convert polars dataframe to pandas dataframe.
|
|
13
|
+
|
|
14
|
+
Parameters:
|
|
15
|
+
data:Polars Dataframe - The original polars dataframe
|
|
16
|
+
remove_duplicates: Boolean - If set to true, all duplicate
|
|
17
|
+
dates will be removed from the dataframe
|
|
18
|
+
add_index: Boolean - If set to true, an index will
|
|
19
|
+
be added to the dataframe
|
|
20
|
+
datetime_column_name: String - the column name that has the
|
|
21
|
+
datetime object. By default this is set to column name Datetime
|
|
22
|
+
This is only used if add_index is set to True
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Pandas DataFrame that has been converted from a Polars DataFrame
|
|
26
|
+
"""
|
|
27
|
+
data = data.to_pandas().copy()
|
|
28
|
+
|
|
29
|
+
if add_index:
|
|
30
|
+
# Convert 'Datetime' column to datetime format if it's not already
|
|
31
|
+
data[datetime_column_name] = to_datetime(data[datetime_column_name])
|
|
32
|
+
|
|
33
|
+
# Set 'Datetime' column as the index
|
|
34
|
+
data.set_index(datetime_column_name, inplace=True)
|
|
35
|
+
|
|
36
|
+
if remove_duplicates:
|
|
37
|
+
|
|
38
|
+
# Remove duplicate dates
|
|
39
|
+
data = data[~data.index.duplicated(keep='first')]
|
|
40
|
+
|
|
41
|
+
return data
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .advanced import get_peaks
|
|
2
|
+
from .trend import is_uptrend, is_downtrend, is_crossover, \
|
|
3
|
+
has_crossed_upward, get_sma, get_up_and_downtrends
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"get_peaks",
|
|
7
|
+
"is_uptrend",
|
|
8
|
+
"is_downtrend",
|
|
9
|
+
"is_crossover",
|
|
10
|
+
"has_crossed_upward",
|
|
11
|
+
"get_sma",
|
|
12
|
+
"get_up_and_downtrends"
|
|
13
|
+
]
|