investing-algorithm-framework 7.17.0__tar.gz → 7.19.2__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.
Potentially problematic release.
This version of investing-algorithm-framework might be problematic. Click here for more details.
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/PKG-INFO +1 -1
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/__init__.py +7 -4
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/__init__.py +4 -2
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/analysis/__init__.py +5 -1
- investing_algorithm_framework-7.19.2/investing_algorithm_framework/app/analysis/backtest_utils.py +80 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/app.py +70 -3
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/__init__.py +3 -2
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_run.py +31 -7
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/exceptions.py +17 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/data_providers/data_provider_service.py +38 -4
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/pyproject.toml +1 -1
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/LICENSE +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/README.md +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/algorithm/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/algorithm/algorithm.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/algorithm/algorithm_factory.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/analysis/backtest_data_ranges.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/analysis/permutation.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/analysis/ranking.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/app_hook.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/context.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/eventloop.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/ascii.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/backtest_report.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/equity_curve.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/line_chart.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/monthly_returns_heatmap.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/charts/yearly_returns_barchart.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/generate.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/stop_loss_table.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/trades_table.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/tables/utils.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/strategy.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/task.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/create_app.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/error_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/responses.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/cli.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/deploy_to_aws_lambda.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/deploy_to_azure_function.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/initialize_app.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/.gitignore.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/app.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/app_azure_function.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/app_web.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/azure_function_host.json.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/data_providers.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/env.example.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/env_azure_function.example.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/market_data_providers.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/readme.md.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/requirements.txt.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/run_backtest.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/cli/templates/strategy.py.template +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/create_app.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/dependency_container.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_date_range.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_metrics.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/backtesting/combine_backtests.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/config.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/constants.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/data_provider.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/data_structures.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/base_model.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/data/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/data/data_source.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/data/data_type.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/event.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/order/order.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/position/position.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/snapshot_interval.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/trade.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/trade_risk_type.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/models/trade/trade_take_profit.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/order_executor.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/portfolio_provider.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/positions/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/positions/position_size.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/services/state_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/strategy.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/csv.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/custom_tqdm.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/dates.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/polars.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/random.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/download_data.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/data_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/data_providers/ccxt.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/data_providers/csv.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/data_providers/pandas.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/order/order_metadata.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/order_trade_association.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/portfolio/sql_portfolio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/trades/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/trades/trade.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/order_executors/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/trade_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/services/aws/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/services/aws/state_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/services/azure/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/infrastructure/services/azure/state_handler.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/backtesting/backtest_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/configuration_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/data_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/alpha.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/beta.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/cagr.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/calmar_ratio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/drawdown.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/equity_curve.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/exposure.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/generate.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/mean_daily_return.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/price_efficiency.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/profit_factor.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/recovery.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/returns.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/risk_free_rate.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/sharpe_ratio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/sortino_ratio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/standard_deviation.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/trades.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/ulcer.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/volatility.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/metrics/win_rate.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/order_service/order_executor_lookup.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/order_service/order_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/positions/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/positions/position_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/positions/position_snapshot_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/repository_service.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_order_evaluator/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
- {investing_algorithm_framework-7.17.0 → investing_algorithm_framework-7.19.2}/investing_algorithm_framework/services/trade_service/trade_service.py +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
from .app import App, Algorithm, \
|
|
2
2
|
TradingStrategy, StatelessAction, Task, AppHook, Context, \
|
|
3
|
-
add_html_report, BacktestReport, \
|
|
3
|
+
add_html_report, BacktestReport, save_backtests_to_directory, \
|
|
4
4
|
pretty_print_trades, pretty_print_positions, \
|
|
5
5
|
pretty_print_orders, pretty_print_backtest, select_backtest_date_ranges, \
|
|
6
|
-
get_equity_curve_with_drawdown_chart, \
|
|
6
|
+
get_equity_curve_with_drawdown_chart, load_backtests_from_directory, \
|
|
7
7
|
get_rolling_sharpe_ratio_chart, rank_results, \
|
|
8
8
|
get_monthly_returns_heatmap_chart, create_weights, \
|
|
9
9
|
get_yearly_returns_bar_chart, get_entry_and_exit_signals, \
|
|
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, \
|
|
@@ -189,5 +189,8 @@ __all__ = [
|
|
|
189
189
|
"get_negative_trades",
|
|
190
190
|
"get_positive_trades",
|
|
191
191
|
"get_number_of_trades",
|
|
192
|
-
"BacktestRun"
|
|
192
|
+
"BacktestRun",
|
|
193
|
+
"load_backtests_from_directory",
|
|
194
|
+
"save_backtests_to_directory",
|
|
195
|
+
"DataError"
|
|
193
196
|
]
|
|
@@ -14,7 +14,7 @@ from .reporting import add_html_report, \
|
|
|
14
14
|
get_yearly_returns_bar_chart, get_equity_curve_chart, \
|
|
15
15
|
get_ohlcv_data_completeness_chart, get_entry_and_exit_signals
|
|
16
16
|
from .analysis import select_backtest_date_ranges, rank_results, \
|
|
17
|
-
create_weights
|
|
17
|
+
create_weights, load_backtests_from_directory, save_backtests_to_directory
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
__all__ = [
|
|
@@ -41,5 +41,7 @@ __all__ = [
|
|
|
41
41
|
"rank_results",
|
|
42
42
|
"create_weights",
|
|
43
43
|
"get_entry_and_exit_signals",
|
|
44
|
-
"get_equity_curve_chart"
|
|
44
|
+
"get_equity_curve_chart",
|
|
45
|
+
"load_backtests_from_directory",
|
|
46
|
+
"save_backtests_to_directory"
|
|
45
47
|
]
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
from .backtest_data_ranges import select_backtest_date_ranges
|
|
2
2
|
from .ranking import rank_results, create_weights, combine_backtest_metrics
|
|
3
3
|
from .permutation import create_ohlcv_permutation
|
|
4
|
+
from .backtest_utils import load_backtests_from_directory, \
|
|
5
|
+
save_backtests_to_directory
|
|
4
6
|
|
|
5
7
|
__all__ = [
|
|
6
8
|
"select_backtest_date_ranges",
|
|
7
9
|
"rank_results",
|
|
8
10
|
"create_weights",
|
|
9
11
|
"create_ohlcv_permutation",
|
|
10
|
-
"combine_backtest_metrics"
|
|
12
|
+
"combine_backtest_metrics",
|
|
13
|
+
"load_backtests_from_directory",
|
|
14
|
+
"save_backtests_to_directory"
|
|
11
15
|
]
|
investing_algorithm_framework-7.19.2/investing_algorithm_framework/app/analysis/backtest_utils.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import List, Union
|
|
4
|
+
from logging import getLogger
|
|
5
|
+
from random import Random
|
|
6
|
+
|
|
7
|
+
from investing_algorithm_framework.domain import Backtest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
logger = getLogger("investing_algorithm_framework")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def save_backtests_to_directory(
|
|
14
|
+
backtests: List[Backtest],
|
|
15
|
+
directory_path: Union[str, Path]
|
|
16
|
+
) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Saves a list of Backtest objects to the specified directory.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
backtests (List[Backtest]): List of Backtest objects to save.
|
|
22
|
+
directory_path (str): Path to the directory where backtests
|
|
23
|
+
will be saved.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
None
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if not os.path.exists(directory_path):
|
|
30
|
+
os.makedirs(directory_path)
|
|
31
|
+
|
|
32
|
+
for backtest in backtests:
|
|
33
|
+
# Check if there is an ID in the backtest metadata
|
|
34
|
+
backtest_id = backtest.metadata.get('id')
|
|
35
|
+
|
|
36
|
+
if backtest_id is None:
|
|
37
|
+
logger.warning(
|
|
38
|
+
"Backtest is missing 'id' in metadata. "
|
|
39
|
+
"Generating a random ID as name for backtest file."
|
|
40
|
+
)
|
|
41
|
+
backtest_id = str(Random().randint(100000, 999999))
|
|
42
|
+
|
|
43
|
+
backtest.save(os.path.join(directory_path, backtest_id))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def load_backtests_from_directory(
|
|
47
|
+
directory_path: Union[str, Path]
|
|
48
|
+
) -> List[Backtest]:
|
|
49
|
+
"""
|
|
50
|
+
Loads Backtest objects from the specified directory.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
directory_path (str): Path to the directory from which backtests
|
|
54
|
+
will be loaded.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
List[Backtest]: List of loaded Backtest objects.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
backtests = []
|
|
61
|
+
|
|
62
|
+
if not os.path.exists(directory_path):
|
|
63
|
+
logger.warning(
|
|
64
|
+
f"Directory {directory_path} does not exist. "
|
|
65
|
+
"No backtests loaded."
|
|
66
|
+
)
|
|
67
|
+
return backtests
|
|
68
|
+
|
|
69
|
+
for file_name in os.listdir(directory_path):
|
|
70
|
+
file_path = os.path.join(directory_path, file_name)
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
backtest = Backtest.open(file_path)
|
|
74
|
+
backtests.append(backtest)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.error(
|
|
77
|
+
f"Failed to load backtest from {file_path}: {e}"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return backtests
|
|
@@ -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,72 @@ 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
|
+
add_pandas_index=False,
|
|
836
|
+
time_frame=data_source.time_frame
|
|
837
|
+
)
|
|
838
|
+
df = df.copy()
|
|
839
|
+
df['Datetime'] = pd.to_datetime(df['Datetime'])
|
|
840
|
+
df = df.sort_values('Datetime')\
|
|
841
|
+
.tail(data_source.window_size)
|
|
842
|
+
start = df['Datetime'].iloc[0]
|
|
843
|
+
end = df['Datetime'].iloc[-1]
|
|
844
|
+
freq = pd.to_timedelta(data_source.time_frame.value)
|
|
845
|
+
expected = pd.date_range(start, end, freq=freq)
|
|
846
|
+
actual = df['Datetime']
|
|
847
|
+
missing = expected.difference(actual)
|
|
848
|
+
|
|
849
|
+
# Calculate the percentage completeness
|
|
850
|
+
completeness = len(actual) / len(expected) * 100
|
|
851
|
+
|
|
852
|
+
if completeness < 100:
|
|
853
|
+
raise DataError(
|
|
854
|
+
f"Data completeness for data source "
|
|
855
|
+
f"{data_source.identifier} "
|
|
856
|
+
f"({data_source.symbol}) is {completeness:.2f}% "
|
|
857
|
+
f"complete. Missing data points: {len(missing)}"
|
|
858
|
+
)
|
|
859
|
+
|
|
792
860
|
def run_vector_backtests(
|
|
793
861
|
self,
|
|
794
862
|
initial_amount,
|
|
@@ -1070,13 +1138,12 @@ class App:
|
|
|
1070
1138
|
except Exception as e:
|
|
1071
1139
|
logger.error(
|
|
1072
1140
|
f"Error occurred during vector backtest for strategy "
|
|
1073
|
-
f"{strategy.
|
|
1141
|
+
f"{strategy.strategy_id}: {str(e)}"
|
|
1074
1142
|
)
|
|
1075
1143
|
if continue_on_error:
|
|
1076
1144
|
backtest = Backtest(
|
|
1077
1145
|
backtest_runs=[],
|
|
1078
1146
|
risk_free_rate=risk_free_rate,
|
|
1079
|
-
backtest_summary={}
|
|
1080
1147
|
)
|
|
1081
1148
|
else:
|
|
1082
1149
|
raise e
|
|
@@ -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
|
]
|
|
@@ -251,17 +251,41 @@ class BacktestRun:
|
|
|
251
251
|
# Remove backtest_metrics to avoid redundancy
|
|
252
252
|
data.pop("backtest_metrics", None)
|
|
253
253
|
|
|
254
|
-
|
|
254
|
+
# Ensure datetime objects are in UTC before formatting
|
|
255
|
+
backtest_start_date = self.backtest_start_date
|
|
256
|
+
|
|
257
|
+
if backtest_start_date.tzinfo is None:
|
|
258
|
+
# Naive datetime - treat as UTC
|
|
259
|
+
backtest_start_date = backtest_start_date.replace(
|
|
260
|
+
tzinfo=timezone.utc
|
|
261
|
+
)
|
|
262
|
+
else:
|
|
263
|
+
# Timezone-aware - convert to UTC
|
|
264
|
+
backtest_start_date = backtest_start_date.astimezone(
|
|
265
|
+
timezone.utc
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
backtest_end_date = self.backtest_end_date
|
|
269
|
+
if backtest_end_date.tzinfo is None:
|
|
270
|
+
backtest_end_date = backtest_end_date.replace(
|
|
271
|
+
tzinfo=timezone.utc
|
|
272
|
+
)
|
|
273
|
+
else:
|
|
274
|
+
backtest_end_date = backtest_end_date.astimezone(timezone.utc)
|
|
275
|
+
|
|
276
|
+
created_at = self.created_at
|
|
277
|
+
if created_at.tzinfo is None:
|
|
278
|
+
created_at = created_at.replace(tzinfo=timezone.utc)
|
|
279
|
+
else:
|
|
280
|
+
created_at = created_at.astimezone(timezone.utc)
|
|
281
|
+
|
|
282
|
+
data["backtest_start_date"] = backtest_start_date.strftime(
|
|
255
283
|
"%Y-%m-%d %H:%M:%S"
|
|
256
284
|
)
|
|
257
|
-
data["backtest_end_date"] =
|
|
285
|
+
data["backtest_end_date"] = backtest_end_date.strftime(
|
|
258
286
|
"%Y-%m-%d %H:%M:%S"
|
|
259
287
|
)
|
|
260
|
-
|
|
261
|
-
if self.created_at.tzinfo is None:
|
|
262
|
-
self.created_at = self.created_at.replace(tzinfo=timezone.utc)
|
|
263
|
-
|
|
264
|
-
data["created_at"] = self.created_at.strftime(
|
|
288
|
+
data["created_at"] = created_at.strftime(
|
|
265
289
|
"%Y-%m-%d %H:%M:%S"
|
|
266
290
|
)
|
|
267
291
|
json.dump(data, f, default=str)
|
|
@@ -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
|
+
}
|
|
@@ -7,7 +7,7 @@ from typing import List, Tuple, Optional, Dict, Any
|
|
|
7
7
|
|
|
8
8
|
from investing_algorithm_framework.domain import DataProvider, \
|
|
9
9
|
OperationalException, ImproperlyConfigured, DataSource, DataType, \
|
|
10
|
-
BacktestDateRange, tqdm, convert_polars_to_pandas
|
|
10
|
+
BacktestDateRange, tqdm, convert_polars_to_pandas, TimeFrame
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger("investing_algorithm_framework")
|
|
13
13
|
|
|
@@ -26,6 +26,7 @@ class DataProviderIndex:
|
|
|
26
26
|
self.data_providers_lookup = defaultdict()
|
|
27
27
|
self.ohlcv_data_providers = defaultdict()
|
|
28
28
|
self.ohlcv_data_providers_no_market = defaultdict()
|
|
29
|
+
self.ohlcv_data_providers_with_timeframe = defaultdict()
|
|
29
30
|
self.ticker_data_providers = defaultdict()
|
|
30
31
|
|
|
31
32
|
def add(self, data_provider: DataProvider):
|
|
@@ -80,11 +81,15 @@ class DataProviderIndex:
|
|
|
80
81
|
|
|
81
82
|
symbol = data_source.symbol
|
|
82
83
|
market = data_source.market
|
|
84
|
+
time_frame = data_source.time_frame
|
|
83
85
|
|
|
84
86
|
if DataType.OHLCV.equals(data_source.data_type):
|
|
85
87
|
if symbol not in self.ohlcv_data_providers:
|
|
86
88
|
self.ohlcv_data_providers[(symbol, market)] = best_provider
|
|
87
89
|
self.ohlcv_data_providers_no_market[symbol] = best_provider
|
|
90
|
+
self.ohlcv_data_providers_with_timeframe[
|
|
91
|
+
(symbol, market, time_frame)
|
|
92
|
+
] = best_provider
|
|
88
93
|
else:
|
|
89
94
|
try:
|
|
90
95
|
# If the symbol already exists, we can update the provider
|
|
@@ -105,6 +110,11 @@ class DataProviderIndex:
|
|
|
105
110
|
self.ohlcv_data_providers_no_market[symbol] =\
|
|
106
111
|
best_provider
|
|
107
112
|
|
|
113
|
+
time_frame_key = (symbol, market, time_frame)
|
|
114
|
+
self.ohlcv_data_providers_with_timeframe[
|
|
115
|
+
time_frame_key
|
|
116
|
+
] = best_provider
|
|
117
|
+
|
|
108
118
|
except Exception:
|
|
109
119
|
# If the existing provider does not have a time_frame
|
|
110
120
|
# attribute, we can safely ignore this
|
|
@@ -165,12 +175,16 @@ class DataProviderIndex:
|
|
|
165
175
|
|
|
166
176
|
symbol = data_source.symbol
|
|
167
177
|
market = data_source.market
|
|
178
|
+
time_frame = data_source.time_frame
|
|
168
179
|
|
|
169
180
|
if DataType.OHLCV.equals(data_source.data_type):
|
|
170
181
|
|
|
171
182
|
if symbol not in self.ohlcv_data_providers:
|
|
172
183
|
self.ohlcv_data_providers[(symbol, market)] = best_provider
|
|
173
184
|
self.ohlcv_data_providers_no_market[symbol] = best_provider
|
|
185
|
+
self.ohlcv_data_providers_with_timeframe[
|
|
186
|
+
(symbol, market, time_frame)
|
|
187
|
+
] = best_provider
|
|
174
188
|
else:
|
|
175
189
|
try:
|
|
176
190
|
# If the symbol already exists, we can update the provider
|
|
@@ -192,6 +206,11 @@ class DataProviderIndex:
|
|
|
192
206
|
self.ohlcv_data_providers_no_market[symbol] = \
|
|
193
207
|
best_provider
|
|
194
208
|
|
|
209
|
+
time_frame_key = (symbol, market, data_source.time_frame)
|
|
210
|
+
self.ohlcv_data_providers_with_timeframe[
|
|
211
|
+
time_frame_key
|
|
212
|
+
] = best_provider
|
|
213
|
+
|
|
195
214
|
except Exception:
|
|
196
215
|
# If the existing provider does not have a time_frame
|
|
197
216
|
# attribute, we can safely ignore this
|
|
@@ -264,7 +283,10 @@ class DataProviderIndex:
|
|
|
264
283
|
return len(self.data_providers_lookup)
|
|
265
284
|
|
|
266
285
|
def get_ohlcv_data_provider(
|
|
267
|
-
self,
|
|
286
|
+
self,
|
|
287
|
+
symbol: str,
|
|
288
|
+
market: Optional[str] = None,
|
|
289
|
+
time_frame: Optional[str] = None
|
|
268
290
|
) -> Optional[DataProvider]:
|
|
269
291
|
"""
|
|
270
292
|
Get the OHLCV data provider for a given symbol and market.
|
|
@@ -272,12 +294,20 @@ class DataProviderIndex:
|
|
|
272
294
|
Args:
|
|
273
295
|
symbol (str): The symbol to get the data provider for.
|
|
274
296
|
market (Optional[str]): The market to get the data provider for.
|
|
297
|
+
time_frame (Optional[str]): The time frame to get the
|
|
298
|
+
data provider for.
|
|
275
299
|
|
|
276
300
|
Returns:
|
|
277
301
|
DataProvider: The OHLCV data provider for the symbol and market,
|
|
278
302
|
or None if no provider is found.
|
|
279
303
|
"""
|
|
280
304
|
|
|
305
|
+
if market is not None and time_frame is not None:
|
|
306
|
+
time_frame = TimeFrame.from_value(time_frame)
|
|
307
|
+
return self.ohlcv_data_providers_with_timeframe.get(
|
|
308
|
+
(symbol, market, time_frame), None
|
|
309
|
+
)
|
|
310
|
+
|
|
281
311
|
if market is None:
|
|
282
312
|
# If no market is specified
|
|
283
313
|
return self.ohlcv_data_providers_no_market.get(symbol, None)
|
|
@@ -462,7 +492,8 @@ class DataProviderService:
|
|
|
462
492
|
start_date: Optional[datetime] = None,
|
|
463
493
|
end_date: Optional[datetime] = None,
|
|
464
494
|
window_size: Optional[int] = None,
|
|
465
|
-
pandas: bool = False
|
|
495
|
+
pandas: bool = False,
|
|
496
|
+
add_pandas_index: bool = True,
|
|
466
497
|
):
|
|
467
498
|
"""
|
|
468
499
|
Function to get OHLCV data from the data provider.
|
|
@@ -483,6 +514,7 @@ class DataProviderService:
|
|
|
483
514
|
data_provider = self.data_provider_index.get_ohlcv_data_provider(
|
|
484
515
|
symbol=symbol,
|
|
485
516
|
market=market,
|
|
517
|
+
time_frame=time_frame
|
|
486
518
|
)
|
|
487
519
|
|
|
488
520
|
if data_provider is None:
|
|
@@ -511,7 +543,9 @@ class DataProviderService:
|
|
|
511
543
|
|
|
512
544
|
if pandas:
|
|
513
545
|
if isinstance(data, pl.DataFrame):
|
|
514
|
-
return convert_polars_to_pandas(
|
|
546
|
+
return convert_polars_to_pandas(
|
|
547
|
+
data, add_index=add_pandas_index
|
|
548
|
+
)
|
|
515
549
|
else:
|
|
516
550
|
return data
|
|
517
551
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|