investing-algorithm-framework 7.0.2__tar.gz → 7.1.0__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-7.0.2 → investing_algorithm_framework-7.1.0}/PKG-INFO +1 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/app.py +145 -10
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/strategy.py +9 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/time_unit.py +20 -4
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/download_data.py +9 -8
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/data_providers/ccxt.py +1 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/__init__.py +2 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/backtesting/backtest_service.py +1 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/data_providers/data_provider_service.py +6 -6
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/__init__.py +2 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/generate.py +3 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/sharpe_ratio.py +3 -10
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/sortino_ratio.py +3 -7
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/pyproject.toml +1 -1
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/LICENSE +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/README.md +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/algorithm/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/algorithm/algorithm.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/algorithm/algorithm_factory.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/analysis/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/analysis/backtest_data_ranges.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/analysis/ranking.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/app_hook.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/context.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/eventloop.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/ascii.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/backtest_report.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/monthly_returns_heatmap.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/charts/yearly_returns_barchart.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/generate.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/stop_loss_table.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/trades_table.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/tables/utils.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/task.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/responses.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/cli.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/deploy_to_aws_lambda.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/deploy_to_azure_function.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/initialize_app.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/.gitignore.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/app.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/app_azure_function.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/app_web.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/azure_function_host.json.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/data_providers.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/env.example.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/env_azure_function.example.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/market_data_providers.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/readme.md.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/requirements.txt.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/run_backtest.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/cli/templates/strategy.py.template +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/create_app.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/dependency_container.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/backtest.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/backtest_date_range.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/backtest_metrics.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/backtest_position.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/backtesting/backtest_results.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/config.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/constants.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/data_provider.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/data_structures.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/data/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/data/data_source.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/data/data_type.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/event.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/order/order.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/order/order_status.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/snapshot_interval.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/time_frame.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/trade.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/trade_risk_type.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/trade_status.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/models/trade/trade_take_profit.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/order_executor.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/portfolio_provider.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/observable.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/observer.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/services/state_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/strategy.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/custom_tqdm.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/dates.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/polars.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/data_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/data_providers/csv.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/data_providers/pandas.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/order/order.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/order/order_metadata.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/order_trade_association.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/portfolio/sql_portfolio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/trades/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/trades/trade.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/order_executors/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/trade_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/aws/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/aws/state_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/azure/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/azure/state_handler.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/unit_of_work/in_memory.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/infrastructure/unit_of_work/sqlalchemy.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/configuration_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/data_providers/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/alpha.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/beta.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/cagr.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/calmar_ratio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/drawdown.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/equity_curve.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/exposure.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/mean_daily_return.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/price_efficiency.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/profit_factor.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/recovery.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/returns.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/risk_free_rate.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/standard_deviation.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/ulcer.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/volatility.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/metrics/win_rate.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/order_service/order_backtest_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/order_service/order_executor_lookup.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/order_service/order_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/positions/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/positions/position_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/positions/position_snapshot_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/repository_service.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_order_evaluator/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
- {investing_algorithm_framework-7.0.2 → investing_algorithm_framework-7.1.0}/investing_algorithm_framework/services/trade_service/trade_service.py +0 -0
|
@@ -26,7 +26,7 @@ from investing_algorithm_framework.infrastructure import setup_sqlalchemy, \
|
|
|
26
26
|
BacktestOrderExecutor, CCXTOHLCVDataProvider, clear_db
|
|
27
27
|
from investing_algorithm_framework.services import OrderBacktestService, \
|
|
28
28
|
BacktestPortfolioService, BacktestTradeOrderEvaluator, \
|
|
29
|
-
DefaultTradeOrderEvaluator
|
|
29
|
+
DefaultTradeOrderEvaluator, get_risk_free_rate_us
|
|
30
30
|
from .app_hook import AppHook
|
|
31
31
|
from .eventloop import EventLoopService
|
|
32
32
|
|
|
@@ -381,6 +381,10 @@ class App:
|
|
|
381
381
|
None
|
|
382
382
|
"""
|
|
383
383
|
logger.info("Initializing data sources")
|
|
384
|
+
|
|
385
|
+
if data_sources is None or len(data_sources) == 0:
|
|
386
|
+
return
|
|
387
|
+
|
|
384
388
|
data_provider_service = self.container.data_provider_service()
|
|
385
389
|
data_provider_service.reset()
|
|
386
390
|
|
|
@@ -415,6 +419,10 @@ class App:
|
|
|
415
419
|
None
|
|
416
420
|
"""
|
|
417
421
|
logger.info("Initializing data sources for backtest")
|
|
422
|
+
|
|
423
|
+
if data_sources is None or len(data_sources) == 0:
|
|
424
|
+
return
|
|
425
|
+
|
|
418
426
|
data_provider_service = self.container.data_provider_service()
|
|
419
427
|
data_provider_service.reset()
|
|
420
428
|
|
|
@@ -825,6 +833,18 @@ class App:
|
|
|
825
833
|
self.initialize_backtest_services()
|
|
826
834
|
self.initialize_backtest_portfolios()
|
|
827
835
|
|
|
836
|
+
if risk_free_rate is None:
|
|
837
|
+
logger.info("No risk free rate provided, retrieving it...")
|
|
838
|
+
risk_free_rate = get_risk_free_rate_us()
|
|
839
|
+
|
|
840
|
+
if risk_free_rate is None:
|
|
841
|
+
raise OperationalException(
|
|
842
|
+
"Could not retrieve risk free rate for backtest metrics."
|
|
843
|
+
"Please provide a risk free as an argument when running "
|
|
844
|
+
"your backtest or make sure you have an internet "
|
|
845
|
+
"connection"
|
|
846
|
+
)
|
|
847
|
+
|
|
828
848
|
algorithm = self.container.algorithm_factory().create_algorithm(
|
|
829
849
|
name=name if name else self._name,
|
|
830
850
|
strategies=(
|
|
@@ -888,18 +908,90 @@ class App:
|
|
|
888
908
|
|
|
889
909
|
return backtest
|
|
890
910
|
|
|
911
|
+
def run_vector_backtests(
|
|
912
|
+
self,
|
|
913
|
+
backtest_date_range: BacktestDateRange,
|
|
914
|
+
initial_amount,
|
|
915
|
+
strategies: List[TradingStrategy],
|
|
916
|
+
snapshot_interval: SnapshotInterval = SnapshotInterval.DAILY,
|
|
917
|
+
risk_free_rate: Optional[float] = None,
|
|
918
|
+
skip_data_sources_initialization: bool = False
|
|
919
|
+
):
|
|
920
|
+
"""
|
|
921
|
+
Run vectorized backtests for a set of strategies. The provided
|
|
922
|
+
set of strategies need to have their 'buy_signal_vectorized' and
|
|
923
|
+
'sell_signal_vectorized' methods implemented to support vectorized
|
|
924
|
+
backtesting.
|
|
925
|
+
|
|
926
|
+
Args:
|
|
927
|
+
backtest_date_range: The date range to run the backtest for
|
|
928
|
+
(instance of BacktestDateRange)
|
|
929
|
+
initial_amount: The initial amount to start the backtest with.
|
|
930
|
+
This will be the amount of trading currency that the backtest
|
|
931
|
+
portfolio will start with.
|
|
932
|
+
strategies (List[TradingStrategy]): List of strategy objects
|
|
933
|
+
that need to be backtested. Each strategy should implement
|
|
934
|
+
the 'buy_signal_vectorized' and 'sell_signal_vectorized'
|
|
935
|
+
methods to support vectorized backtesting.
|
|
936
|
+
snapshot_interval (SnapshotInterval): The snapshot
|
|
937
|
+
interval to use for the backtest. This is used to determine
|
|
938
|
+
how often the portfolio snapshot should be taken during the
|
|
939
|
+
backtest. The default is TRADE_CLOSE, which means that the
|
|
940
|
+
portfolio snapshot will be taken at the end of each trade.
|
|
941
|
+
risk_free_rate (Optional[float]): The risk-free rate to use for
|
|
942
|
+
the backtest. This is used to calculate the Sharpe ratio
|
|
943
|
+
and other performance metrics. If not provided, the default
|
|
944
|
+
risk-free rate will be tried to be fetched from the
|
|
945
|
+
US Treasury website.
|
|
946
|
+
skip_data_sources_initialization (bool): Whether to skip the
|
|
947
|
+
initialization of data sources. This is useful when the data
|
|
948
|
+
sources are already initialized, and you want to skip the
|
|
949
|
+
initialization step. This will speed up the backtesting
|
|
950
|
+
process, but make sure that the data sources are already
|
|
951
|
+
initialized before calling this method.
|
|
952
|
+
|
|
953
|
+
Returns:
|
|
954
|
+
List[Backtest]: List of Backtest instances for each strategy
|
|
955
|
+
that was backtested.
|
|
956
|
+
"""
|
|
957
|
+
backtests = []
|
|
958
|
+
data_sources = []
|
|
959
|
+
|
|
960
|
+
for strategy in strategies:
|
|
961
|
+
data_sources.extend(strategy.data_sources)
|
|
962
|
+
|
|
963
|
+
if not skip_data_sources_initialization:
|
|
964
|
+
self.initialize_data_sources_backtest(
|
|
965
|
+
data_sources, backtest_date_range
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
for strategy in tqdm(strategies):
|
|
969
|
+
backtests.append(
|
|
970
|
+
self.run_vector_backtest(
|
|
971
|
+
backtest_date_range=backtest_date_range,
|
|
972
|
+
initial_amount=initial_amount,
|
|
973
|
+
strategy=strategy,
|
|
974
|
+
snapshot_interval=snapshot_interval,
|
|
975
|
+
risk_free_rate=risk_free_rate,
|
|
976
|
+
skip_data_sources_initialization=True
|
|
977
|
+
)
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
return backtests
|
|
981
|
+
|
|
891
982
|
def run_vector_backtest(
|
|
892
983
|
self,
|
|
893
984
|
backtest_date_range: BacktestDateRange,
|
|
894
985
|
initial_amount,
|
|
895
|
-
strategy,
|
|
986
|
+
strategy: TradingStrategy,
|
|
896
987
|
snapshot_interval: SnapshotInterval = SnapshotInterval.DAILY,
|
|
897
988
|
metadata: Optional[Dict[str, str]] = None,
|
|
898
989
|
risk_free_rate: Optional[float] = None,
|
|
990
|
+
skip_data_sources_initialization: bool = False
|
|
899
991
|
) -> Backtest:
|
|
900
992
|
"""
|
|
901
|
-
Run
|
|
902
|
-
|
|
993
|
+
Run vectorized backtests for a strategy. The provided
|
|
994
|
+
strategy needs to have its 'buy_signal_vectorized' and
|
|
903
995
|
'sell_signal_vectorized' methods implemented to support vectorized
|
|
904
996
|
backtesting.
|
|
905
997
|
|
|
@@ -925,6 +1017,12 @@ class App:
|
|
|
925
1017
|
backtest report. This can be used to store additional
|
|
926
1018
|
information about the backtest, such as the author, version,
|
|
927
1019
|
parameters or any other relevant information.
|
|
1020
|
+
skip_data_sources_initialization (bool): Whether to skip the
|
|
1021
|
+
initialization of data sources. This is useful when the data
|
|
1022
|
+
sources are already initialized, and you want to skip the
|
|
1023
|
+
initialization step. This will speed up the backtesting
|
|
1024
|
+
process, but make sure that the data sources are already
|
|
1025
|
+
initialized before calling this method.
|
|
928
1026
|
|
|
929
1027
|
Returns:
|
|
930
1028
|
Backtest: Instance of Backtest
|
|
@@ -935,9 +1033,24 @@ class App:
|
|
|
935
1033
|
snapshot_interval=snapshot_interval,
|
|
936
1034
|
initial_amount=initial_amount
|
|
937
1035
|
)
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1036
|
+
|
|
1037
|
+
if not skip_data_sources_initialization:
|
|
1038
|
+
self.initialize_data_sources_backtest(
|
|
1039
|
+
strategy.data_sources, backtest_date_range
|
|
1040
|
+
)
|
|
1041
|
+
|
|
1042
|
+
if risk_free_rate is None:
|
|
1043
|
+
logger.info("No risk free rate provided, retrieving it...")
|
|
1044
|
+
risk_free_rate = get_risk_free_rate_us()
|
|
1045
|
+
|
|
1046
|
+
if risk_free_rate is None:
|
|
1047
|
+
raise OperationalException(
|
|
1048
|
+
"Could not retrieve risk free rate for backtest metrics."
|
|
1049
|
+
"Please provide a risk free as an argument when running "
|
|
1050
|
+
"your backtest or make sure you have an internet "
|
|
1051
|
+
"connection"
|
|
1052
|
+
)
|
|
1053
|
+
|
|
941
1054
|
backtest_service = self.container.backtest_service()
|
|
942
1055
|
backtest_service.validate_strategy_for_vector_backtest(strategy)
|
|
943
1056
|
backtest = backtest_service.create_vector_backtest(
|
|
@@ -946,7 +1059,17 @@ class App:
|
|
|
946
1059
|
initial_amount=initial_amount,
|
|
947
1060
|
risk_free_rate=risk_free_rate
|
|
948
1061
|
)
|
|
949
|
-
|
|
1062
|
+
|
|
1063
|
+
# Add the metadata to the backtest
|
|
1064
|
+
if metadata is None:
|
|
1065
|
+
|
|
1066
|
+
if strategy.metadata is not None:
|
|
1067
|
+
backtest.metadata = {}
|
|
1068
|
+
else:
|
|
1069
|
+
backtest.metadata = strategy.metadata
|
|
1070
|
+
else:
|
|
1071
|
+
backtest.metadata = metadata
|
|
1072
|
+
|
|
950
1073
|
return backtest
|
|
951
1074
|
|
|
952
1075
|
def run_backtests(
|
|
@@ -977,7 +1100,8 @@ class App:
|
|
|
977
1100
|
for the backtest. This is used to determine how often the
|
|
978
1101
|
portfolio snapshot should be taken during the backtest.
|
|
979
1102
|
risk_free_rate (Optional[float]): The risk-free rate to use for
|
|
980
|
-
|
|
1103
|
+
the backtest. This is used to calculate the Sharpe ratio
|
|
1104
|
+
and other performance metrics. If not provided, the default
|
|
981
1105
|
risk-free rate will be tried to be fetched from the
|
|
982
1106
|
US Treasury website.
|
|
983
1107
|
save (bool): Whether to save the backtest reports to disk.
|
|
@@ -994,7 +1118,6 @@ class App:
|
|
|
994
1118
|
"""
|
|
995
1119
|
backtests = []
|
|
996
1120
|
backtest_service = self.container.backtest_service()
|
|
997
|
-
final_algorithms = []
|
|
998
1121
|
|
|
999
1122
|
if algorithms is not None:
|
|
1000
1123
|
final_algorithms = algorithms
|
|
@@ -1011,6 +1134,18 @@ class App:
|
|
|
1011
1134
|
"No algorithms or strategy provided for backtesting"
|
|
1012
1135
|
)
|
|
1013
1136
|
|
|
1137
|
+
if risk_free_rate is None:
|
|
1138
|
+
logger.info("No risk free rate provided, retrieving it...")
|
|
1139
|
+
risk_free_rate = get_risk_free_rate_us()
|
|
1140
|
+
|
|
1141
|
+
if risk_free_rate is None:
|
|
1142
|
+
raise OperationalException(
|
|
1143
|
+
"Could not retrieve risk free rate for backtest metrics."
|
|
1144
|
+
"Please provide a risk free as an argument when running "
|
|
1145
|
+
"your backtest or make sure you have an internet "
|
|
1146
|
+
"connection"
|
|
1147
|
+
)
|
|
1148
|
+
|
|
1014
1149
|
for date_range in backtest_date_ranges:
|
|
1015
1150
|
for algorithm in final_algorithms:
|
|
1016
1151
|
|
|
@@ -27,8 +27,12 @@ class TradingStrategy:
|
|
|
27
27
|
sources to use for the strategy. The data sources will be used
|
|
28
28
|
to indentify data providers that will be called to gather data
|
|
29
29
|
and pass to the strategy before its run.
|
|
30
|
+
metadata (optional): Dict[str, Any] - a dictionary
|
|
31
|
+
containing metadata about the strategy. This can be used to
|
|
32
|
+
store additional information about the strategy, such as its
|
|
33
|
+
author, version, description, params etc.
|
|
30
34
|
"""
|
|
31
|
-
time_unit:
|
|
35
|
+
time_unit: TimeUnit = None
|
|
32
36
|
interval: int = None
|
|
33
37
|
worker_id: str = None
|
|
34
38
|
strategy_id: str = None
|
|
@@ -36,6 +40,7 @@ class TradingStrategy:
|
|
|
36
40
|
data_sources: List[DataSource] = None
|
|
37
41
|
traces = None
|
|
38
42
|
context: Context = None
|
|
43
|
+
metadata: Dict[str, Any] = None
|
|
39
44
|
|
|
40
45
|
def __init__(
|
|
41
46
|
self,
|
|
@@ -43,6 +48,7 @@ class TradingStrategy:
|
|
|
43
48
|
time_unit=None,
|
|
44
49
|
interval=None,
|
|
45
50
|
data_sources=None,
|
|
51
|
+
metadata=None,
|
|
46
52
|
worker_id=None,
|
|
47
53
|
decorated=None
|
|
48
54
|
):
|
|
@@ -65,6 +71,8 @@ class TradingStrategy:
|
|
|
65
71
|
if data_sources is not None:
|
|
66
72
|
self.data_sources = data_sources
|
|
67
73
|
|
|
74
|
+
self.metadata = metadata if metadata is not None else {}
|
|
75
|
+
|
|
68
76
|
if decorated is not None:
|
|
69
77
|
self.decorated = decorated
|
|
70
78
|
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
from datetime import timedelta
|
|
2
2
|
from enum import Enum
|
|
3
|
+
from investing_algorithm_framework.domain.exceptions import \
|
|
4
|
+
OperationalException
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class TimeUnit(Enum):
|
|
8
|
+
"""
|
|
9
|
+
Enum class the represents a time unit such as
|
|
10
|
+
second, minute, hour or day. This can class
|
|
11
|
+
can be used to specify time specification within
|
|
12
|
+
the framework.
|
|
13
|
+
"""
|
|
6
14
|
SECOND = "SECOND"
|
|
7
15
|
MINUTE = "MINUTE"
|
|
8
16
|
HOUR = "HOUR"
|
|
@@ -18,7 +26,11 @@ class TimeUnit(Enum):
|
|
|
18
26
|
if value.upper() == entry.value:
|
|
19
27
|
return entry
|
|
20
28
|
|
|
21
|
-
|
|
29
|
+
raise OperationalException(
|
|
30
|
+
f"Could not convert string {value} to time unit"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
raise OperationalException(
|
|
22
34
|
f"Could not convert value {value} to time unit," +
|
|
23
35
|
" please make sure that the value is either of type string or" +
|
|
24
36
|
f"TimeUnit. Its current type is {type(value)}"
|
|
@@ -38,17 +50,21 @@ class TimeUnit(Enum):
|
|
|
38
50
|
TimeUnit: The extracted time unit.
|
|
39
51
|
"""
|
|
40
52
|
if not isinstance(file_path, str):
|
|
41
|
-
raise
|
|
53
|
+
raise OperationalException(
|
|
54
|
+
"File path must be a string."
|
|
55
|
+
)
|
|
42
56
|
|
|
43
57
|
parts = file_path.split('_')
|
|
44
58
|
if len(parts) < 2:
|
|
45
|
-
raise
|
|
59
|
+
raise OperationalException(
|
|
60
|
+
"File name does not contain a valid time unit."
|
|
61
|
+
)
|
|
46
62
|
|
|
47
63
|
time_unit_str = parts[-1].split('.')[0].upper()
|
|
48
64
|
try:
|
|
49
65
|
return TimeUnit.from_string(time_unit_str)
|
|
50
66
|
except ValueError:
|
|
51
|
-
raise
|
|
67
|
+
raise OperationalException(
|
|
52
68
|
f"Could not extract time unit from file name: {file_path}. "
|
|
53
69
|
"Expected format 'symbol_timeunit.csv', "
|
|
54
70
|
f"got '{time_unit_str}'."
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from pathlib import Path
|
|
1
2
|
from dateutil import parser
|
|
2
|
-
from datetime import timezone
|
|
3
|
+
from datetime import timezone, datetime
|
|
3
4
|
import pandas
|
|
4
5
|
import polars
|
|
5
6
|
from typing import Union
|
|
@@ -8,21 +9,21 @@ from investing_algorithm_framework.services import DataProviderService, \
|
|
|
8
9
|
from investing_algorithm_framework.infrastructure import \
|
|
9
10
|
get_default_data_providers
|
|
10
11
|
from investing_algorithm_framework.domain import DataSource, \
|
|
11
|
-
OperationalException
|
|
12
|
+
OperationalException, DataType
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def download(
|
|
15
16
|
symbol: str,
|
|
16
|
-
market=None,
|
|
17
|
-
date=None,
|
|
17
|
+
market: str = None,
|
|
18
|
+
date: Union[datetime, str] = None,
|
|
18
19
|
time_frame: str = None,
|
|
19
|
-
data_type: str =
|
|
20
|
-
start_date: str = None,
|
|
21
|
-
end_date: str = None,
|
|
20
|
+
data_type: Union[str, DataType] = DataType.OHLCV,
|
|
21
|
+
start_date: Union[datetime, str] = None,
|
|
22
|
+
end_date: Union[datetime, str] = None,
|
|
22
23
|
window_size: int = 200,
|
|
23
24
|
pandas: bool = True,
|
|
24
25
|
save: bool = True,
|
|
25
|
-
storage_path: str = None,
|
|
26
|
+
storage_path: Union[str, Path] = None,
|
|
26
27
|
) -> Union[pandas.DataFrame, polars.DataFrame]:
|
|
27
28
|
"""
|
|
28
29
|
Download market data from the specified source. This function
|
|
@@ -142,7 +142,7 @@ class CCXTOHLCVDataProvider(DataProvider):
|
|
|
142
142
|
symbol=symbol,
|
|
143
143
|
market=market,
|
|
144
144
|
time_frame=data_source.time_frame,
|
|
145
|
-
storage_path=
|
|
145
|
+
storage_path=data_source.storage_path,
|
|
146
146
|
start_date=start_date,
|
|
147
147
|
end_date=end_date
|
|
148
148
|
)
|
|
@@ -12,6 +12,7 @@ from .portfolios import PortfolioService, BacktestPortfolioService, \
|
|
|
12
12
|
from .positions import PositionService, PositionSnapshotService
|
|
13
13
|
from .repository_service import RepositoryService
|
|
14
14
|
from .trade_service import TradeService
|
|
15
|
+
from .metrics import get_risk_free_rate_us
|
|
15
16
|
|
|
16
17
|
__all__ = [
|
|
17
18
|
"OrderService",
|
|
@@ -34,4 +35,5 @@ __all__ = [
|
|
|
34
35
|
"PortfolioProviderLookup",
|
|
35
36
|
"TradeOrderEvaluator",
|
|
36
37
|
"DefaultTradeOrderEvaluator",
|
|
38
|
+
"get_risk_free_rate_us"
|
|
37
39
|
]
|
|
@@ -323,7 +323,7 @@ class BacktestService(Observable):
|
|
|
323
323
|
algorithm: The algorithm to create the backtest report for
|
|
324
324
|
number_of_runs: The number of runs
|
|
325
325
|
backtest_date_range: The backtest date range of the backtest
|
|
326
|
-
risk_free_rate: The risk-free rate to use
|
|
326
|
+
risk_free_rate: The risk-free rate to use for the backtest metrics
|
|
327
327
|
strategy_directory_path (optional, str): The path to the
|
|
328
328
|
strategy directory
|
|
329
329
|
|
|
@@ -44,18 +44,18 @@ class DataProviderIndex:
|
|
|
44
44
|
|
|
45
45
|
def register(self, data_source: DataSource) -> DataProvider:
|
|
46
46
|
"""
|
|
47
|
-
Register
|
|
47
|
+
Register a data source in the DataProvider Index.
|
|
48
48
|
|
|
49
|
-
This method will also check if the data provider supports
|
|
50
|
-
the market. If no data provider is found for the market and symbol,
|
|
51
|
-
it will raise an ImproperlyConfigured exception.
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
This method will go over all data providers and select the
|
|
51
|
+
best matching data provider for the data source.
|
|
52
|
+
|
|
53
|
+
If multiple data providers are found for the data source,
|
|
54
54
|
it will sort them by priority and pick the best one.
|
|
55
55
|
|
|
56
56
|
Args:
|
|
57
57
|
data_source (DataSource): The data source to register the
|
|
58
|
-
|
|
58
|
+
data provider for.
|
|
59
59
|
|
|
60
60
|
Returns:
|
|
61
61
|
None
|
|
@@ -27,6 +27,7 @@ from .exposure import get_exposure, get_average_trade_duration, \
|
|
|
27
27
|
from .win_rate import get_win_rate, get_win_loss_ratio
|
|
28
28
|
from .calmar_ratio import get_calmar_ratio
|
|
29
29
|
from .generate import create_backtest_metrics
|
|
30
|
+
from .risk_free_rate import get_risk_free_rate_us
|
|
30
31
|
|
|
31
32
|
__all__ = [
|
|
32
33
|
"get_annual_volatility",
|
|
@@ -81,4 +82,5 @@ __all__ = [
|
|
|
81
82
|
"create_backtest_metrics",
|
|
82
83
|
"get_growth",
|
|
83
84
|
"get_growth_percentage",
|
|
85
|
+
"get_risk_free_rate_us"
|
|
84
86
|
]
|
|
@@ -57,7 +57,9 @@ def create_backtest_metrics(
|
|
|
57
57
|
backtest_results.portfolio_snapshots,
|
|
58
58
|
risk_free_rate=risk_free_rate
|
|
59
59
|
),
|
|
60
|
-
sortino_ratio=get_sortino_ratio(
|
|
60
|
+
sortino_ratio=get_sortino_ratio(
|
|
61
|
+
backtest_results.portfolio_snapshots, risk_free_rate=risk_free_rate
|
|
62
|
+
),
|
|
61
63
|
profit_factor=get_profit_factor(backtest_results.trades),
|
|
62
64
|
calmar_ratio=get_calmar_ratio(backtest_results.portfolio_snapshots),
|
|
63
65
|
annual_volatility=get_annual_volatility(
|
|
@@ -53,12 +53,11 @@ from datetime import datetime
|
|
|
53
53
|
|
|
54
54
|
from investing_algorithm_framework.domain import PortfolioSnapshot
|
|
55
55
|
from .mean_daily_return import get_mean_daily_return
|
|
56
|
-
from .risk_free_rate import get_risk_free_rate_us
|
|
57
56
|
from .standard_deviation import get_daily_returns_std
|
|
58
57
|
|
|
59
58
|
|
|
60
59
|
def get_sharpe_ratio(
|
|
61
|
-
snapshots: List[PortfolioSnapshot], risk_free_rate:
|
|
60
|
+
snapshots: List[PortfolioSnapshot], risk_free_rate: float,
|
|
62
61
|
) -> float:
|
|
63
62
|
"""
|
|
64
63
|
Calculate the Sharpe Ratio from a backtest report using daily or
|
|
@@ -79,9 +78,6 @@ def get_sharpe_ratio(
|
|
|
79
78
|
mean_daily_return = get_mean_daily_return(snapshots)
|
|
80
79
|
std_daily_return = get_daily_returns_std(snapshots)
|
|
81
80
|
|
|
82
|
-
if risk_free_rate is None:
|
|
83
|
-
risk_free_rate = get_risk_free_rate_us()
|
|
84
|
-
|
|
85
81
|
if std_daily_return == 0:
|
|
86
82
|
return float('nan') # Avoid division by zero
|
|
87
83
|
|
|
@@ -92,21 +88,18 @@ def get_sharpe_ratio(
|
|
|
92
88
|
|
|
93
89
|
|
|
94
90
|
def get_rolling_sharpe_ratio(
|
|
95
|
-
snapshots: List[PortfolioSnapshot], risk_free_rate:
|
|
91
|
+
snapshots: List[PortfolioSnapshot], risk_free_rate: float
|
|
96
92
|
) -> List[Tuple[float, datetime]]:
|
|
97
93
|
"""
|
|
98
94
|
Calculate the rolling Sharpe Ratio over a 365-day window.
|
|
99
95
|
|
|
100
96
|
Args:
|
|
101
97
|
snapshots (List[PortfolioSnapshot]): Time-sorted list of snapshots.
|
|
102
|
-
risk_free_rate (float
|
|
98
|
+
risk_free_rate (float): Annualized risk-free rate (e.g., 0.03 for 3%).
|
|
103
99
|
|
|
104
100
|
Returns:
|
|
105
101
|
List[Tuple[float, datetime]]: List of (sharpe_ratio, snapshot_date).
|
|
106
102
|
"""
|
|
107
|
-
if risk_free_rate is None:
|
|
108
|
-
risk_free_rate = get_risk_free_rate_us()
|
|
109
|
-
|
|
110
103
|
data = [(s.created_at, s.total_value) for s in snapshots]
|
|
111
104
|
df = pd.DataFrame(data, columns=["created_at", "total_value"])
|
|
112
105
|
df['created_at'] = pd.to_datetime(df['created_at'])
|
|
@@ -30,7 +30,7 @@ from .standard_deviation import get_downside_std_of_daily_returns
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def get_sortino_ratio(
|
|
33
|
-
snapshots: List[PortfolioSnapshot], risk_free_rate:
|
|
33
|
+
snapshots: List[PortfolioSnapshot], risk_free_rate: float
|
|
34
34
|
) -> float:
|
|
35
35
|
"""
|
|
36
36
|
Calculate the Sortino Ratio for a given report.
|
|
@@ -46,9 +46,8 @@ def get_sortino_ratio(
|
|
|
46
46
|
Args:
|
|
47
47
|
snapshots (List[PortfolioSnapshot]): List of portfolio snapshots
|
|
48
48
|
from the backtest report.
|
|
49
|
-
risk_free_rate (float
|
|
50
|
-
(e.g., 0.047 for 4.7%).
|
|
51
|
-
rate.
|
|
49
|
+
risk_free_rate (float): Annual risk-free rate as a decimal
|
|
50
|
+
(e.g., 0.047 for 4.7%).
|
|
52
51
|
|
|
53
52
|
Returns:
|
|
54
53
|
float: The Sortino Ratio.
|
|
@@ -61,9 +60,6 @@ def get_sortino_ratio(
|
|
|
61
60
|
mean_daily_return = get_mean_daily_return(snapshots)
|
|
62
61
|
std_downside_daily_return = get_downside_std_of_daily_returns(snapshots)
|
|
63
62
|
|
|
64
|
-
if risk_free_rate is None:
|
|
65
|
-
risk_free_rate = get_risk_free_rate_us()
|
|
66
|
-
|
|
67
63
|
if std_downside_daily_return == 0:
|
|
68
64
|
return float('nan') # or 0.0, depending on preference
|
|
69
65
|
|
|
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
|