investing-algorithm-framework 3.7.0__py3-none-any.whl → 7.19.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of investing-algorithm-framework might be problematic. Click here for more details.
- investing_algorithm_framework/__init__.py +168 -45
- investing_algorithm_framework/app/__init__.py +32 -1
- investing_algorithm_framework/app/algorithm/__init__.py +7 -0
- investing_algorithm_framework/app/algorithm/algorithm.py +239 -0
- investing_algorithm_framework/app/algorithm/algorithm_factory.py +114 -0
- investing_algorithm_framework/app/analysis/__init__.py +15 -0
- investing_algorithm_framework/app/analysis/backtest_data_ranges.py +121 -0
- investing_algorithm_framework/app/analysis/backtest_utils.py +107 -0
- investing_algorithm_framework/app/analysis/permutation.py +116 -0
- investing_algorithm_framework/app/analysis/ranking.py +297 -0
- investing_algorithm_framework/app/app.py +1933 -589
- investing_algorithm_framework/app/app_hook.py +28 -0
- investing_algorithm_framework/app/context.py +1725 -0
- investing_algorithm_framework/app/eventloop.py +590 -0
- investing_algorithm_framework/app/reporting/__init__.py +27 -0
- investing_algorithm_framework/app/reporting/ascii.py +921 -0
- investing_algorithm_framework/app/reporting/backtest_report.py +349 -0
- investing_algorithm_framework/app/reporting/charts/__init__.py +19 -0
- investing_algorithm_framework/app/reporting/charts/entry_exist_signals.py +66 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve.py +37 -0
- investing_algorithm_framework/app/reporting/charts/equity_curve_drawdown.py +74 -0
- investing_algorithm_framework/app/reporting/charts/line_chart.py +11 -0
- investing_algorithm_framework/app/reporting/charts/monthly_returns_heatmap.py +70 -0
- investing_algorithm_framework/app/reporting/charts/ohlcv_data_completeness.py +51 -0
- investing_algorithm_framework/app/reporting/charts/rolling_sharp_ratio.py +79 -0
- investing_algorithm_framework/app/reporting/charts/yearly_returns_barchart.py +55 -0
- investing_algorithm_framework/app/reporting/generate.py +185 -0
- investing_algorithm_framework/app/reporting/tables/__init__.py +11 -0
- investing_algorithm_framework/app/reporting/tables/key_metrics_table.py +217 -0
- investing_algorithm_framework/app/reporting/tables/stop_loss_table.py +0 -0
- investing_algorithm_framework/app/reporting/tables/time_metrics_table.py +80 -0
- investing_algorithm_framework/app/reporting/tables/trade_metrics_table.py +147 -0
- investing_algorithm_framework/app/reporting/tables/trades_table.py +75 -0
- investing_algorithm_framework/app/reporting/tables/utils.py +29 -0
- investing_algorithm_framework/app/reporting/templates/report_template.html.j2 +154 -0
- investing_algorithm_framework/app/stateless/action_handlers/__init__.py +4 -2
- investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +1 -1
- investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +1 -1
- investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +14 -7
- investing_algorithm_framework/app/strategy.py +664 -84
- investing_algorithm_framework/app/task.py +5 -3
- investing_algorithm_framework/app/web/__init__.py +2 -1
- investing_algorithm_framework/app/web/create_app.py +4 -2
- investing_algorithm_framework/cli/__init__.py +0 -0
- investing_algorithm_framework/cli/cli.py +226 -0
- investing_algorithm_framework/cli/deploy_to_aws_lambda.py +501 -0
- investing_algorithm_framework/cli/deploy_to_azure_function.py +718 -0
- investing_algorithm_framework/cli/initialize_app.py +603 -0
- investing_algorithm_framework/cli/templates/.gitignore.template +178 -0
- investing_algorithm_framework/cli/templates/app.py.template +18 -0
- investing_algorithm_framework/cli/templates/app_aws_lambda_function.py.template +48 -0
- investing_algorithm_framework/cli/templates/app_azure_function.py.template +14 -0
- investing_algorithm_framework/cli/templates/app_web.py.template +18 -0
- investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template +22 -0
- investing_algorithm_framework/cli/templates/aws_lambda_dockerignore.template +92 -0
- investing_algorithm_framework/cli/templates/aws_lambda_readme.md.template +110 -0
- investing_algorithm_framework/cli/templates/aws_lambda_requirements.txt.template +2 -0
- investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +65 -0
- investing_algorithm_framework/cli/templates/azure_function_host.json.template +15 -0
- investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +8 -0
- investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +3 -0
- investing_algorithm_framework/cli/templates/data_providers.py.template +17 -0
- investing_algorithm_framework/cli/templates/env.example.template +2 -0
- investing_algorithm_framework/cli/templates/env_azure_function.example.template +4 -0
- investing_algorithm_framework/cli/templates/market_data_providers.py.template +9 -0
- investing_algorithm_framework/cli/templates/readme.md.template +135 -0
- investing_algorithm_framework/cli/templates/requirements.txt.template +2 -0
- investing_algorithm_framework/cli/templates/run_backtest.py.template +20 -0
- investing_algorithm_framework/cli/templates/strategy.py.template +124 -0
- investing_algorithm_framework/create_app.py +40 -6
- investing_algorithm_framework/dependency_container.py +72 -56
- investing_algorithm_framework/domain/__init__.py +71 -47
- investing_algorithm_framework/domain/backtesting/__init__.py +21 -0
- investing_algorithm_framework/domain/backtesting/backtest.py +503 -0
- investing_algorithm_framework/domain/backtesting/backtest_date_range.py +96 -0
- investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +242 -0
- investing_algorithm_framework/domain/backtesting/backtest_metrics.py +459 -0
- investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py +275 -0
- investing_algorithm_framework/domain/backtesting/backtest_run.py +605 -0
- investing_algorithm_framework/domain/backtesting/backtest_summary_metrics.py +162 -0
- investing_algorithm_framework/domain/backtesting/combine_backtests.py +280 -0
- investing_algorithm_framework/domain/config.py +59 -91
- investing_algorithm_framework/domain/constants.py +13 -38
- investing_algorithm_framework/domain/data_provider.py +334 -0
- investing_algorithm_framework/domain/data_structures.py +3 -2
- investing_algorithm_framework/domain/exceptions.py +51 -1
- investing_algorithm_framework/domain/models/__init__.py +17 -12
- investing_algorithm_framework/domain/models/data/__init__.py +7 -0
- investing_algorithm_framework/domain/models/data/data_source.py +214 -0
- investing_algorithm_framework/domain/models/data/data_type.py +46 -0
- investing_algorithm_framework/domain/models/event.py +35 -0
- investing_algorithm_framework/domain/models/market/market_credential.py +55 -1
- investing_algorithm_framework/domain/models/order/order.py +77 -83
- investing_algorithm_framework/domain/models/order/order_status.py +2 -2
- investing_algorithm_framework/domain/models/order/order_type.py +1 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio.py +81 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +26 -3
- investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +108 -11
- investing_algorithm_framework/domain/models/position/__init__.py +2 -1
- investing_algorithm_framework/domain/models/position/position.py +12 -0
- investing_algorithm_framework/domain/models/position/position_size.py +41 -0
- investing_algorithm_framework/domain/models/risk_rules/__init__.py +7 -0
- investing_algorithm_framework/domain/models/risk_rules/stop_loss_rule.py +51 -0
- investing_algorithm_framework/domain/models/risk_rules/take_profit_rule.py +55 -0
- investing_algorithm_framework/domain/models/snapshot_interval.py +45 -0
- investing_algorithm_framework/domain/models/strategy_profile.py +19 -151
- investing_algorithm_framework/domain/models/time_frame.py +37 -0
- investing_algorithm_framework/domain/models/time_interval.py +33 -0
- investing_algorithm_framework/domain/models/time_unit.py +66 -2
- investing_algorithm_framework/domain/models/trade/__init__.py +8 -1
- investing_algorithm_framework/domain/models/trade/trade.py +295 -171
- investing_algorithm_framework/domain/models/trade/trade_status.py +9 -2
- investing_algorithm_framework/domain/models/trade/trade_stop_loss.py +332 -0
- investing_algorithm_framework/domain/models/trade/trade_take_profit.py +365 -0
- investing_algorithm_framework/domain/order_executor.py +112 -0
- investing_algorithm_framework/domain/portfolio_provider.py +118 -0
- investing_algorithm_framework/domain/services/__init__.py +2 -9
- investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -6
- investing_algorithm_framework/domain/services/state_handler.py +38 -0
- investing_algorithm_framework/domain/strategy.py +1 -29
- investing_algorithm_framework/domain/utils/__init__.py +12 -7
- investing_algorithm_framework/domain/utils/custom_tqdm.py +22 -0
- investing_algorithm_framework/domain/utils/dates.py +57 -0
- investing_algorithm_framework/domain/utils/jupyter_notebook_detection.py +19 -0
- investing_algorithm_framework/domain/utils/polars.py +53 -0
- investing_algorithm_framework/domain/utils/random.py +29 -0
- investing_algorithm_framework/download_data.py +108 -0
- investing_algorithm_framework/infrastructure/__init__.py +31 -18
- investing_algorithm_framework/infrastructure/data_providers/__init__.py +36 -0
- investing_algorithm_framework/infrastructure/data_providers/ccxt.py +1143 -0
- investing_algorithm_framework/infrastructure/data_providers/csv.py +568 -0
- investing_algorithm_framework/infrastructure/data_providers/pandas.py +599 -0
- investing_algorithm_framework/infrastructure/database/__init__.py +6 -2
- investing_algorithm_framework/infrastructure/database/sql_alchemy.py +86 -12
- investing_algorithm_framework/infrastructure/models/__init__.py +6 -11
- investing_algorithm_framework/infrastructure/models/order/__init__.py +2 -1
- investing_algorithm_framework/infrastructure/models/order/order.py +35 -49
- investing_algorithm_framework/infrastructure/models/order/order_metadata.py +44 -0
- investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
- investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +1 -1
- investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +8 -0
- investing_algorithm_framework/infrastructure/models/portfolio/{portfolio.py → sql_portfolio.py} +17 -5
- investing_algorithm_framework/infrastructure/models/trades/__init__.py +9 -0
- investing_algorithm_framework/infrastructure/models/trades/trade.py +130 -0
- investing_algorithm_framework/infrastructure/models/trades/trade_stop_loss.py +59 -0
- investing_algorithm_framework/infrastructure/models/trades/trade_take_profit.py +55 -0
- investing_algorithm_framework/infrastructure/order_executors/__init__.py +21 -0
- investing_algorithm_framework/infrastructure/order_executors/backtest_oder_executor.py +28 -0
- investing_algorithm_framework/infrastructure/order_executors/ccxt_order_executor.py +200 -0
- investing_algorithm_framework/infrastructure/portfolio_providers/__init__.py +19 -0
- investing_algorithm_framework/infrastructure/portfolio_providers/ccxt_portfolio_provider.py +199 -0
- investing_algorithm_framework/infrastructure/repositories/__init__.py +8 -0
- investing_algorithm_framework/infrastructure/repositories/order_metadata_repository.py +17 -0
- investing_algorithm_framework/infrastructure/repositories/order_repository.py +5 -0
- investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +1 -1
- investing_algorithm_framework/infrastructure/repositories/position_repository.py +11 -0
- investing_algorithm_framework/infrastructure/repositories/repository.py +81 -27
- investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
- investing_algorithm_framework/infrastructure/repositories/trade_stop_loss_repository.py +29 -0
- investing_algorithm_framework/infrastructure/repositories/trade_take_profit_repository.py +29 -0
- investing_algorithm_framework/infrastructure/services/__init__.py +4 -4
- investing_algorithm_framework/infrastructure/services/aws/__init__.py +6 -0
- investing_algorithm_framework/infrastructure/services/aws/state_handler.py +113 -0
- investing_algorithm_framework/infrastructure/services/azure/__init__.py +5 -0
- investing_algorithm_framework/infrastructure/services/azure/state_handler.py +158 -0
- investing_algorithm_framework/services/__init__.py +113 -16
- investing_algorithm_framework/services/backtesting/__init__.py +0 -7
- investing_algorithm_framework/services/backtesting/backtest_service.py +566 -359
- investing_algorithm_framework/services/configuration_service.py +77 -11
- investing_algorithm_framework/services/data_providers/__init__.py +5 -0
- investing_algorithm_framework/services/data_providers/data_provider_service.py +850 -0
- investing_algorithm_framework/services/market_credential_service.py +16 -1
- investing_algorithm_framework/services/metrics/__init__.py +114 -0
- investing_algorithm_framework/services/metrics/alpha.py +0 -0
- investing_algorithm_framework/services/metrics/beta.py +0 -0
- investing_algorithm_framework/services/metrics/cagr.py +60 -0
- investing_algorithm_framework/services/metrics/calmar_ratio.py +40 -0
- investing_algorithm_framework/services/metrics/drawdown.py +181 -0
- investing_algorithm_framework/services/metrics/equity_curve.py +24 -0
- investing_algorithm_framework/services/metrics/exposure.py +210 -0
- investing_algorithm_framework/services/metrics/generate.py +358 -0
- investing_algorithm_framework/services/metrics/mean_daily_return.py +83 -0
- investing_algorithm_framework/services/metrics/profit_factor.py +165 -0
- investing_algorithm_framework/services/metrics/recovery.py +113 -0
- investing_algorithm_framework/services/metrics/returns.py +452 -0
- investing_algorithm_framework/services/metrics/risk_free_rate.py +28 -0
- investing_algorithm_framework/services/metrics/sharpe_ratio.py +137 -0
- investing_algorithm_framework/services/metrics/sortino_ratio.py +74 -0
- investing_algorithm_framework/services/metrics/standard_deviation.py +157 -0
- investing_algorithm_framework/services/metrics/trades.py +500 -0
- investing_algorithm_framework/services/metrics/treynor_ratio.py +0 -0
- investing_algorithm_framework/services/metrics/ulcer.py +0 -0
- investing_algorithm_framework/services/metrics/value_at_risk.py +0 -0
- investing_algorithm_framework/services/metrics/volatility.py +97 -0
- investing_algorithm_framework/services/metrics/win_rate.py +177 -0
- investing_algorithm_framework/services/order_service/__init__.py +3 -1
- investing_algorithm_framework/services/order_service/order_backtest_service.py +76 -89
- investing_algorithm_framework/services/order_service/order_executor_lookup.py +110 -0
- investing_algorithm_framework/services/order_service/order_service.py +407 -326
- investing_algorithm_framework/services/portfolios/__init__.py +3 -1
- investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +37 -3
- investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +22 -8
- investing_algorithm_framework/services/portfolios/portfolio_provider_lookup.py +106 -0
- investing_algorithm_framework/services/portfolios/portfolio_service.py +96 -28
- investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +97 -28
- investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +116 -313
- investing_algorithm_framework/services/positions/__init__.py +7 -0
- investing_algorithm_framework/services/positions/position_service.py +210 -0
- investing_algorithm_framework/services/repository_service.py +8 -2
- investing_algorithm_framework/services/trade_order_evaluator/__init__.py +9 -0
- investing_algorithm_framework/services/trade_order_evaluator/backtest_trade_oder_evaluator.py +113 -0
- investing_algorithm_framework/services/trade_order_evaluator/default_trade_order_evaluator.py +51 -0
- investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py +80 -0
- investing_algorithm_framework/services/trade_service/__init__.py +7 -1
- investing_algorithm_framework/services/trade_service/trade_service.py +1013 -315
- investing_algorithm_framework/services/trade_service/trade_stop_loss_service.py +39 -0
- investing_algorithm_framework/services/trade_service/trade_take_profit_service.py +41 -0
- investing_algorithm_framework-7.19.15.dist-info/METADATA +537 -0
- investing_algorithm_framework-7.19.15.dist-info/RECORD +263 -0
- investing_algorithm_framework-7.19.15.dist-info/entry_points.txt +3 -0
- investing_algorithm_framework/app/algorithm.py +0 -1105
- investing_algorithm_framework/domain/graphs.py +0 -382
- investing_algorithm_framework/domain/metrics/__init__.py +0 -6
- investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -11
- investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -43
- investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -120
- investing_algorithm_framework/domain/models/backtesting/backtest_report.py +0 -580
- investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -243
- investing_algorithm_framework/domain/models/trading_data_types.py +0 -47
- investing_algorithm_framework/domain/models/trading_time_frame.py +0 -223
- investing_algorithm_framework/domain/services/market_data_sources.py +0 -344
- investing_algorithm_framework/domain/services/market_service.py +0 -153
- investing_algorithm_framework/domain/singleton.py +0 -9
- investing_algorithm_framework/domain/utils/backtesting.py +0 -472
- investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -12
- investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +0 -559
- investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +0 -254
- investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -47
- investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -5
- investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -455
- investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -7
- investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -2
- investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +0 -350
- investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -53
- investing_algorithm_framework/services/backtesting/graphs.py +0 -61
- investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -8
- investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -150
- investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +0 -189
- investing_algorithm_framework/services/position_service.py +0 -31
- investing_algorithm_framework/services/strategy_orchestrator_service.py +0 -264
- investing_algorithm_framework-3.7.0.dist-info/METADATA +0 -339
- investing_algorithm_framework-3.7.0.dist-info/RECORD +0 -147
- /investing_algorithm_framework/{domain → services}/metrics/price_efficiency.py +0 -0
- /investing_algorithm_framework/services/{position_snapshot_service.py → positions/position_snapshot_service.py} +0 -0
- {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/LICENSE +0 -0
- {investing_algorithm_framework-3.7.0.dist-info → investing_algorithm_framework-7.19.15.dist-info}/WHEEL +0 -0
|
@@ -1,24 +1,56 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
from .app import App, Algorithm, \
|
|
2
|
+
TradingStrategy, StatelessAction, Task, AppHook, Context, \
|
|
3
|
+
add_html_report, BacktestReport, save_backtests_to_directory, \
|
|
4
|
+
pretty_print_trades, pretty_print_positions, \
|
|
5
|
+
pretty_print_orders, pretty_print_backtest, select_backtest_date_ranges, \
|
|
6
|
+
get_equity_curve_with_drawdown_chart, load_backtests_from_directory, \
|
|
7
|
+
get_rolling_sharpe_ratio_chart, rank_results, \
|
|
8
|
+
get_monthly_returns_heatmap_chart, create_weights, \
|
|
9
|
+
get_yearly_returns_bar_chart, get_entry_and_exit_signals, \
|
|
10
|
+
get_ohlcv_data_completeness_chart, get_equity_curve_chart
|
|
11
|
+
from .domain import ApiException, combine_backtests, PositionSize, \
|
|
12
|
+
OrderType, OperationalException, OrderStatus, OrderSide, \
|
|
13
|
+
TimeUnit, TimeInterval, Order, Portfolio, Backtest, DataError, \
|
|
14
|
+
Position, TimeFrame, INDEX_DATETIME, MarketCredential, TakeProfitRule, \
|
|
15
|
+
PortfolioConfiguration, RESOURCE_DIRECTORY, AWS_LAMBDA_LOGGING_CONFIG, \
|
|
16
|
+
Trade, APP_MODE, AppMode, DATETIME_FORMAT, \
|
|
17
|
+
BacktestDateRange, convert_polars_to_pandas, BacktestRun, \
|
|
18
|
+
DEFAULT_LOGGING_CONFIG, DataType, DataProvider, StopLossRule, \
|
|
19
|
+
TradeStatus, generate_backtest_summary_metrics, \
|
|
20
|
+
APPLICATION_DIRECTORY, DataSource, OrderExecutor, PortfolioProvider, \
|
|
21
|
+
SnapshotInterval, AWS_S3_STATE_BUCKET_NAME, BacktestEvaluationFocus
|
|
22
|
+
from .infrastructure import AzureBlobStorageStateHandler, \
|
|
23
|
+
CSVOHLCVDataProvider, CCXTOHLCVDataProvider, PandasOHLCVDataProvider, \
|
|
24
|
+
AWSS3StorageStateHandler
|
|
19
25
|
from .create_app import create_app
|
|
20
|
-
from
|
|
21
|
-
|
|
26
|
+
from .download_data import download
|
|
27
|
+
from .services import get_annual_volatility, get_sortino_ratio, \
|
|
28
|
+
get_drawdown_series, get_max_drawdown, get_equity_curve, \
|
|
29
|
+
get_price_efficiency_ratio, get_sharpe_ratio, \
|
|
30
|
+
get_profit_factor, get_cumulative_profit_factor_series, \
|
|
31
|
+
get_rolling_profit_factor_series, get_cagr, \
|
|
32
|
+
get_standard_deviation_returns, get_standard_deviation_downside_returns, \
|
|
33
|
+
get_max_drawdown_absolute, get_total_return, get_exposure_ratio, \
|
|
34
|
+
get_average_trade_duration, get_win_rate, get_win_loss_ratio, \
|
|
35
|
+
get_calmar_ratio, get_trade_frequency, get_yearly_returns, \
|
|
36
|
+
get_monthly_returns, get_best_year, get_best_month, get_worst_year, \
|
|
37
|
+
get_worst_month, get_best_trade, get_worst_trade, \
|
|
38
|
+
get_average_yearly_return, get_average_trade_gain, \
|
|
39
|
+
get_average_trade_loss, get_average_monthly_return, \
|
|
40
|
+
get_percentage_winning_months, get_max_drawdown_duration, \
|
|
41
|
+
get_max_daily_drawdown, get_trades_per_day, \
|
|
42
|
+
get_trades_per_year, get_average_monthly_return_losing_months, \
|
|
43
|
+
get_average_monthly_return_winning_months, get_percentage_winning_years, \
|
|
44
|
+
get_rolling_sharpe_ratio, create_backtest_metrics, get_total_growth, \
|
|
45
|
+
get_total_loss, get_cumulative_exposure, get_median_trade_return, \
|
|
46
|
+
get_average_trade_return, get_risk_free_rate_us, get_cumulative_return, \
|
|
47
|
+
get_cumulative_return_series, get_current_average_trade_return, \
|
|
48
|
+
get_current_average_trade_gain, get_current_average_trade_duration, \
|
|
49
|
+
get_current_average_trade_loss, get_negative_trades, \
|
|
50
|
+
get_positive_trades, get_number_of_trades, get_current_win_rate, \
|
|
51
|
+
get_current_win_loss_ratio, create_backtest_metrics_for_backtest, \
|
|
52
|
+
TradeTakeProfitService, TradeStopLossService
|
|
53
|
+
|
|
22
54
|
|
|
23
55
|
__all__ = [
|
|
24
56
|
"Algorithm",
|
|
@@ -27,12 +59,9 @@ __all__ = [
|
|
|
27
59
|
"AppHook",
|
|
28
60
|
"create_app",
|
|
29
61
|
"ApiException",
|
|
30
|
-
"TradingDataType",
|
|
31
|
-
"TradingTimeFrame",
|
|
32
62
|
"OrderType",
|
|
33
63
|
"OrderStatus",
|
|
34
64
|
"OrderSide",
|
|
35
|
-
"Config",
|
|
36
65
|
"PortfolioConfiguration",
|
|
37
66
|
"TimeUnit",
|
|
38
67
|
"TimeInterval",
|
|
@@ -43,34 +72,128 @@ __all__ = [
|
|
|
43
72
|
"StatelessAction",
|
|
44
73
|
"Task",
|
|
45
74
|
"pretty_print_backtest",
|
|
46
|
-
"
|
|
75
|
+
"INDEX_DATETIME",
|
|
47
76
|
"Trade",
|
|
48
77
|
"TimeFrame",
|
|
49
|
-
"CCXTOrderBookMarketDataSource",
|
|
50
|
-
"CCXTTickerMarketDataSource",
|
|
51
|
-
"CCXTOHLCVMarketDataSource",
|
|
52
|
-
"OHLCVMarketDataSource",
|
|
53
|
-
"OrderBookMarketDataSource",
|
|
54
|
-
"TickerMarketDataSource",
|
|
55
|
-
"CSVOHLCVMarketDataSource",
|
|
56
|
-
"CSVTickerMarketDataSource",
|
|
57
78
|
"MarketCredential",
|
|
58
|
-
"MarketService",
|
|
59
79
|
"OperationalException",
|
|
60
|
-
"pretty_print_backtest_reports_evaluation",
|
|
61
|
-
"BacktestReportsEvaluation",
|
|
62
|
-
"load_backtest_reports",
|
|
63
|
-
"SYMBOLS",
|
|
64
|
-
"RESERVED_BALANCES",
|
|
65
80
|
"APP_MODE",
|
|
66
81
|
"AppMode",
|
|
67
82
|
"DATETIME_FORMAT",
|
|
68
|
-
"
|
|
83
|
+
"Backtest",
|
|
69
84
|
"BacktestDateRange",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
85
|
+
"convert_polars_to_pandas",
|
|
86
|
+
"AzureBlobStorageStateHandler",
|
|
87
|
+
"DEFAULT_LOGGING_CONFIG",
|
|
88
|
+
"BacktestReport",
|
|
89
|
+
"TradeStatus",
|
|
90
|
+
"Context",
|
|
91
|
+
"APPLICATION_DIRECTORY",
|
|
92
|
+
"download",
|
|
93
|
+
"pretty_print_orders",
|
|
94
|
+
"pretty_print_trades",
|
|
95
|
+
"pretty_print_positions",
|
|
96
|
+
"DataSource",
|
|
97
|
+
"OrderExecutor",
|
|
98
|
+
"PortfolioProvider",
|
|
99
|
+
"SnapshotInterval",
|
|
100
|
+
"add_html_report",
|
|
101
|
+
"AWSS3StorageStateHandler",
|
|
102
|
+
"AWS_S3_STATE_BUCKET_NAME",
|
|
103
|
+
"AWS_LAMBDA_LOGGING_CONFIG",
|
|
104
|
+
'select_backtest_date_ranges',
|
|
105
|
+
'DataType',
|
|
106
|
+
'CSVOHLCVDataProvider',
|
|
107
|
+
"CCXTOHLCVDataProvider",
|
|
108
|
+
"DataProvider",
|
|
109
|
+
"get_annual_volatility",
|
|
110
|
+
"get_sortino_ratio",
|
|
111
|
+
"get_drawdown_series",
|
|
112
|
+
"get_max_drawdown",
|
|
113
|
+
"get_equity_curve",
|
|
114
|
+
"get_price_efficiency_ratio",
|
|
115
|
+
"get_sharpe_ratio",
|
|
116
|
+
"get_profit_factor",
|
|
117
|
+
"get_cumulative_profit_factor_series",
|
|
118
|
+
"get_rolling_profit_factor_series",
|
|
119
|
+
"get_sharpe_ratio",
|
|
120
|
+
"get_cagr",
|
|
121
|
+
"get_standard_deviation_returns",
|
|
122
|
+
"get_standard_deviation_downside_returns",
|
|
123
|
+
"get_max_drawdown_absolute",
|
|
124
|
+
"get_total_return",
|
|
125
|
+
"get_exposure_ratio",
|
|
126
|
+
"get_cumulative_exposure",
|
|
127
|
+
"get_average_trade_duration",
|
|
128
|
+
"get_win_rate",
|
|
129
|
+
"get_win_loss_ratio",
|
|
130
|
+
"get_calmar_ratio",
|
|
131
|
+
"get_trade_frequency",
|
|
132
|
+
"get_yearly_returns",
|
|
133
|
+
"get_monthly_returns",
|
|
134
|
+
"get_best_year",
|
|
135
|
+
"get_best_month",
|
|
136
|
+
"get_worst_year",
|
|
137
|
+
"get_worst_month",
|
|
138
|
+
"get_best_trade",
|
|
139
|
+
"get_worst_trade",
|
|
140
|
+
"get_average_yearly_return",
|
|
141
|
+
"get_average_trade_gain",
|
|
142
|
+
"get_average_trade_loss",
|
|
143
|
+
"get_average_monthly_return",
|
|
144
|
+
"get_percentage_winning_months",
|
|
145
|
+
"get_average_trade_duration",
|
|
146
|
+
"get_trade_frequency",
|
|
147
|
+
"get_win_rate",
|
|
148
|
+
"get_win_loss_ratio",
|
|
149
|
+
"get_calmar_ratio",
|
|
150
|
+
"get_max_drawdown_absolute",
|
|
151
|
+
"get_max_drawdown_duration",
|
|
152
|
+
"get_max_daily_drawdown",
|
|
153
|
+
"get_trades_per_day",
|
|
154
|
+
"get_trades_per_year",
|
|
155
|
+
"get_average_monthly_return_losing_months",
|
|
156
|
+
"get_average_monthly_return_winning_months",
|
|
157
|
+
"get_percentage_winning_years",
|
|
158
|
+
"get_rolling_sharpe_ratio",
|
|
159
|
+
"create_backtest_metrics",
|
|
160
|
+
"PandasOHLCVDataProvider",
|
|
161
|
+
"get_equity_curve_with_drawdown_chart",
|
|
162
|
+
"get_rolling_sharpe_ratio_chart",
|
|
163
|
+
"get_monthly_returns_heatmap_chart",
|
|
164
|
+
"get_yearly_returns_bar_chart",
|
|
165
|
+
"get_ohlcv_data_completeness_chart",
|
|
166
|
+
"rank_results",
|
|
167
|
+
"create_weights",
|
|
168
|
+
"get_entry_and_exit_signals",
|
|
169
|
+
"BacktestEvaluationFocus",
|
|
170
|
+
"combine_backtests",
|
|
171
|
+
"PositionSize",
|
|
172
|
+
"get_median_trade_return",
|
|
173
|
+
"get_average_trade_return",
|
|
174
|
+
"get_risk_free_rate_us",
|
|
175
|
+
"get_cumulative_return",
|
|
176
|
+
"get_cumulative_return_series",
|
|
177
|
+
"get_total_loss",
|
|
178
|
+
"get_total_growth",
|
|
179
|
+
"generate_backtest_summary_metrics",
|
|
180
|
+
"get_equity_curve_chart",
|
|
181
|
+
"get_current_win_rate",
|
|
182
|
+
"get_current_win_loss_ratio",
|
|
183
|
+
"get_current_average_trade_loss",
|
|
184
|
+
"get_current_average_trade_duration",
|
|
185
|
+
"get_current_average_trade_gain",
|
|
186
|
+
"get_current_average_trade_return",
|
|
187
|
+
"get_negative_trades",
|
|
188
|
+
"get_positive_trades",
|
|
189
|
+
"get_number_of_trades",
|
|
190
|
+
"BacktestRun",
|
|
191
|
+
"load_backtests_from_directory",
|
|
192
|
+
"save_backtests_to_directory",
|
|
193
|
+
"DataError",
|
|
194
|
+
"create_backtest_metrics_for_backtest",
|
|
195
|
+
"TakeProfitRule",
|
|
196
|
+
"StopLossRule",
|
|
197
|
+
"TradeStopLossService",
|
|
198
|
+
"TradeTakeProfitService"
|
|
76
199
|
]
|
|
@@ -4,6 +4,18 @@ from investing_algorithm_framework.app.strategy import TradingStrategy
|
|
|
4
4
|
from investing_algorithm_framework.app.task import Task
|
|
5
5
|
from investing_algorithm_framework.app.web import create_flask_app
|
|
6
6
|
from .algorithm import Algorithm
|
|
7
|
+
from .context import Context
|
|
8
|
+
from .reporting import add_html_report, \
|
|
9
|
+
BacktestReport, pretty_print_backtest, pretty_print_trades, \
|
|
10
|
+
pretty_print_positions, pretty_print_orders, \
|
|
11
|
+
get_equity_curve_with_drawdown_chart, \
|
|
12
|
+
get_rolling_sharpe_ratio_chart, \
|
|
13
|
+
get_monthly_returns_heatmap_chart, \
|
|
14
|
+
get_yearly_returns_bar_chart, get_equity_curve_chart, \
|
|
15
|
+
get_ohlcv_data_completeness_chart, get_entry_and_exit_signals
|
|
16
|
+
from .analysis import select_backtest_date_ranges, rank_results, \
|
|
17
|
+
create_weights, load_backtests_from_directory, save_backtests_to_directory
|
|
18
|
+
|
|
7
19
|
|
|
8
20
|
__all__ = [
|
|
9
21
|
"Algorithm",
|
|
@@ -12,5 +24,24 @@ __all__ = [
|
|
|
12
24
|
"TradingStrategy",
|
|
13
25
|
"StatelessAction",
|
|
14
26
|
"Task",
|
|
15
|
-
"AppHook"
|
|
27
|
+
"AppHook",
|
|
28
|
+
"Context",
|
|
29
|
+
"add_html_report",
|
|
30
|
+
"BacktestReport",
|
|
31
|
+
"pretty_print_backtest",
|
|
32
|
+
"pretty_print_trades",
|
|
33
|
+
"pretty_print_positions",
|
|
34
|
+
"pretty_print_orders",
|
|
35
|
+
"select_backtest_date_ranges",
|
|
36
|
+
"get_equity_curve_with_drawdown_chart",
|
|
37
|
+
"get_rolling_sharpe_ratio_chart",
|
|
38
|
+
"get_monthly_returns_heatmap_chart",
|
|
39
|
+
"get_yearly_returns_bar_chart",
|
|
40
|
+
"get_ohlcv_data_completeness_chart",
|
|
41
|
+
"rank_results",
|
|
42
|
+
"create_weights",
|
|
43
|
+
"get_entry_and_exit_signals",
|
|
44
|
+
"get_equity_curve_chart",
|
|
45
|
+
"load_backtests_from_directory",
|
|
46
|
+
"save_backtests_to_directory"
|
|
16
47
|
]
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from investing_algorithm_framework.app.app_hook import AppHook
|
|
7
|
+
from investing_algorithm_framework.app.strategy import TradingStrategy
|
|
8
|
+
from investing_algorithm_framework.domain import OperationalException, \
|
|
9
|
+
DataSource
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger("investing_algorithm_framework")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Algorithm:
|
|
15
|
+
"""
|
|
16
|
+
Class to represent an algorithm. An algorithm is a collection of
|
|
17
|
+
strategies that are executed in a specific order.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
_name: The name of the algorithm. It should be a string and
|
|
21
|
+
can only contain letters and numbers.
|
|
22
|
+
_description: The description of the algorithm. It should be a string.
|
|
23
|
+
_strategies: A list of strategies that are part of the algorithm.
|
|
24
|
+
_tasks: A list of tasks that are part of the algorithm.
|
|
25
|
+
_data_sources: A list of data sources that are part of the algorithm.
|
|
26
|
+
_on_strategy_run_hooks: A list of hooks that will be called when a
|
|
27
|
+
"""
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
name: str = None,
|
|
31
|
+
description: str = None,
|
|
32
|
+
strategy=None,
|
|
33
|
+
strategies=None,
|
|
34
|
+
tasks: List = None,
|
|
35
|
+
data_sources: List[DataSource] = None,
|
|
36
|
+
on_strategy_run_hooks=None,
|
|
37
|
+
metadata=None
|
|
38
|
+
):
|
|
39
|
+
self._name = name
|
|
40
|
+
self._context = {}
|
|
41
|
+
self._description = None
|
|
42
|
+
|
|
43
|
+
if description is not None:
|
|
44
|
+
self._description = description
|
|
45
|
+
|
|
46
|
+
self._strategies = []
|
|
47
|
+
self._tasks = []
|
|
48
|
+
self._data_sources = []
|
|
49
|
+
self._on_strategy_run_hooks = []
|
|
50
|
+
self.metadata = metadata
|
|
51
|
+
|
|
52
|
+
if data_sources is not None:
|
|
53
|
+
self._data_sources = data_sources
|
|
54
|
+
|
|
55
|
+
if strategies is not None:
|
|
56
|
+
self.strategies = strategies
|
|
57
|
+
|
|
58
|
+
if tasks is not None:
|
|
59
|
+
self.tasks = tasks
|
|
60
|
+
|
|
61
|
+
if strategy is not None:
|
|
62
|
+
self.add_strategy(strategy, throw_exception=True)
|
|
63
|
+
|
|
64
|
+
if on_strategy_run_hooks is not None:
|
|
65
|
+
for hook in on_strategy_run_hooks:
|
|
66
|
+
self.add_on_strategy_run_hook(hook)
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def _validate_name(name):
|
|
70
|
+
"""
|
|
71
|
+
Function to validate the name of the algorithm. This function
|
|
72
|
+
will check if the name of the algorithm is a string and raise
|
|
73
|
+
an exception if it is not.
|
|
74
|
+
|
|
75
|
+
Name can only contain letters, numbers
|
|
76
|
+
|
|
77
|
+
Parameters:
|
|
78
|
+
name: The name of the algorithm
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
None
|
|
82
|
+
"""
|
|
83
|
+
if not isinstance(name, str):
|
|
84
|
+
raise OperationalException(
|
|
85
|
+
"The name of the algorithm must be a string"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
pattern = re.compile(r"^[a-zA-Z0-9]*$")
|
|
89
|
+
|
|
90
|
+
if not pattern.match(name):
|
|
91
|
+
raise OperationalException(
|
|
92
|
+
"The name of the algorithm can only contain" +
|
|
93
|
+
" letters and numbers"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
illegal_chars = r"[\/:*?\"<>|]"
|
|
97
|
+
|
|
98
|
+
if re.search(illegal_chars, name):
|
|
99
|
+
raise OperationalException(
|
|
100
|
+
f"Illegal characters detected in algorithm: {name}. "
|
|
101
|
+
f"Illegal characters: / \\ : * ? \" < > |"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def name(self):
|
|
106
|
+
return self._name
|
|
107
|
+
|
|
108
|
+
@name.setter
|
|
109
|
+
def name(self, name):
|
|
110
|
+
Algorithm._validate_name(name)
|
|
111
|
+
self._name = name
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def data_sources(self):
|
|
115
|
+
return self._data_sources
|
|
116
|
+
|
|
117
|
+
@data_sources.setter
|
|
118
|
+
def data_sources(self, data_sources):
|
|
119
|
+
self._data_sources = data_sources
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def description(self):
|
|
123
|
+
"""
|
|
124
|
+
Function to get the description of the algorithm
|
|
125
|
+
"""
|
|
126
|
+
return self._description
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def strategies(self):
|
|
130
|
+
return self._strategies
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def on_strategy_run_hooks(self):
|
|
134
|
+
return self._on_strategy_run_hooks
|
|
135
|
+
|
|
136
|
+
@strategies.setter
|
|
137
|
+
def strategies(self, strategies):
|
|
138
|
+
|
|
139
|
+
for strategy in strategies:
|
|
140
|
+
self.add_strategy(strategy)
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def tasks(self):
|
|
144
|
+
return self._tasks
|
|
145
|
+
|
|
146
|
+
@tasks.setter
|
|
147
|
+
def tasks(self, tasks):
|
|
148
|
+
|
|
149
|
+
for task in tasks:
|
|
150
|
+
self.add_task(task)
|
|
151
|
+
|
|
152
|
+
def get_strategy(self, strategy_id):
|
|
153
|
+
for strategy in self._strategies:
|
|
154
|
+
if strategy.worker_id == strategy_id:
|
|
155
|
+
return strategy
|
|
156
|
+
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
def get_strategies(self):
|
|
160
|
+
|
|
161
|
+
if self._strategies is None:
|
|
162
|
+
raise OperationalException(
|
|
163
|
+
"No strategies have been added to the algorithm"
|
|
164
|
+
)
|
|
165
|
+
return self._strategies
|
|
166
|
+
|
|
167
|
+
def add_strategy(self, strategy, throw_exception=True) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Function to add a strategy to the algorithm. The strategy should be an
|
|
170
|
+
instance of TradingStrategy or a subclass based on the TradingStrategy
|
|
171
|
+
class.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
strategy: Instance of TradingStrategy
|
|
175
|
+
throw_exception: Flag to allow for throwing an exception when
|
|
176
|
+
the provided strategy is not inline with what the application
|
|
177
|
+
expects.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
None
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
if inspect.isclass(strategy):
|
|
184
|
+
|
|
185
|
+
if not issubclass(strategy, TradingStrategy):
|
|
186
|
+
raise OperationalException(
|
|
187
|
+
"The strategy must be a subclass of TradingStrategy"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
strategy = strategy()
|
|
191
|
+
|
|
192
|
+
if not isinstance(strategy, TradingStrategy):
|
|
193
|
+
|
|
194
|
+
if throw_exception:
|
|
195
|
+
raise OperationalException(
|
|
196
|
+
"Strategy should be an instance of TradingStrategy"
|
|
197
|
+
)
|
|
198
|
+
else:
|
|
199
|
+
return
|
|
200
|
+
|
|
201
|
+
has_duplicates = False
|
|
202
|
+
|
|
203
|
+
for i in range(len(self._strategies)):
|
|
204
|
+
for j in range(i + 1, len(self._strategies)):
|
|
205
|
+
if self._strategies[i].worker_id == strategy.worker_id:
|
|
206
|
+
has_duplicates = True
|
|
207
|
+
break
|
|
208
|
+
|
|
209
|
+
if has_duplicates:
|
|
210
|
+
raise OperationalException(
|
|
211
|
+
"Can't add strategy, there already exists a strategy "
|
|
212
|
+
"with the same id in the algorithm"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
self._strategies.append(strategy)
|
|
216
|
+
|
|
217
|
+
def add_task(self, task):
|
|
218
|
+
if inspect.isclass(task):
|
|
219
|
+
task = task()
|
|
220
|
+
|
|
221
|
+
self._tasks.append(task)
|
|
222
|
+
|
|
223
|
+
def add_on_strategy_run_hook(self, app_hook):
|
|
224
|
+
"""
|
|
225
|
+
Function to add a hook that will be called when a strategy is run.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
app_hook: The hook function to be added.
|
|
229
|
+
"""
|
|
230
|
+
# Check if the app_hook inherits from AppHook
|
|
231
|
+
if inspect.isclass(app_hook) and not issubclass(app_hook, AppHook):
|
|
232
|
+
raise OperationalException(
|
|
233
|
+
"App hook should be an instance of AppHook"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if inspect.isclass(app_hook):
|
|
237
|
+
app_hook = app_hook()
|
|
238
|
+
|
|
239
|
+
self._on_strategy_run_hooks.append(app_hook)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from .algorithm import Algorithm
|
|
3
|
+
from investing_algorithm_framework.domain import OperationalException
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def validate_algorithm_name(name, illegal_chars=r"[\/:*?\"<>|]"):
|
|
7
|
+
"""
|
|
8
|
+
Validate an algorithm name for illegal characters and throw an
|
|
9
|
+
exception if any are found.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
name (str): The name to validate.
|
|
13
|
+
illegal_chars (str): A regex pattern for characters considered
|
|
14
|
+
illegal (default: r"[/:*?\"<>|]").
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
ValueError: If illegal characters are found in the filename.
|
|
18
|
+
"""
|
|
19
|
+
if re.search(illegal_chars, name):
|
|
20
|
+
raise OperationalException(
|
|
21
|
+
f"Illegal characters detected in filename: {name}. "
|
|
22
|
+
f"Illegal characters: {illegal_chars}"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AlgorithmFactory:
|
|
27
|
+
"""
|
|
28
|
+
Factory class for creating an algorithm instance.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def create_algorithm_name(algorithm):
|
|
33
|
+
"""
|
|
34
|
+
Create a name for the algorithm based on its
|
|
35
|
+
strategies.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
algorithm (Algorithm): Instance of Algorithm.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
str: Name of the algorithm.
|
|
42
|
+
"""
|
|
43
|
+
first_strategy = algorithm.strategies[0] \
|
|
44
|
+
if algorithm.strategies else None
|
|
45
|
+
|
|
46
|
+
if first_strategy is not None:
|
|
47
|
+
return f"{first_strategy.__class__.__name__}"
|
|
48
|
+
|
|
49
|
+
return "DefaultAlgorithm"
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def create_algorithm(
|
|
53
|
+
name=None,
|
|
54
|
+
algorithm=None,
|
|
55
|
+
strategy=None,
|
|
56
|
+
strategies=None,
|
|
57
|
+
tasks=None,
|
|
58
|
+
on_strategy_run_hooks=None,
|
|
59
|
+
) -> Algorithm:
|
|
60
|
+
"""
|
|
61
|
+
Create an instance of the specified algorithm type.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
name (str): Name of the algorithm.
|
|
65
|
+
algorithm (Algorithm): Instance of Algorithm to be used.
|
|
66
|
+
strategy (TradingStrategy): Single TradingStrategy instance.
|
|
67
|
+
strategies (list): List of TradingStrategy instances.
|
|
68
|
+
tasks (list): List of Task instances.
|
|
69
|
+
on_strategy_run_hooks (list): List of hooks to be called
|
|
70
|
+
when a strategy is run.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Algorithm: Instance of Algorithm.
|
|
74
|
+
"""
|
|
75
|
+
name = name
|
|
76
|
+
strategies = strategies or []
|
|
77
|
+
tasks = tasks or []
|
|
78
|
+
on_strategy_run_hooks = on_strategy_run_hooks or []
|
|
79
|
+
data_sources = []
|
|
80
|
+
|
|
81
|
+
if algorithm is not None and isinstance(algorithm, Algorithm):
|
|
82
|
+
if name is None:
|
|
83
|
+
name = algorithm.name
|
|
84
|
+
|
|
85
|
+
strategies.extend(algorithm.strategies)
|
|
86
|
+
tasks.extend(algorithm.tasks)
|
|
87
|
+
on_strategy_run_hooks.extend(algorithm.on_strategy_run_hooks)
|
|
88
|
+
|
|
89
|
+
if hasattr(algorithm, 'data_sources'):
|
|
90
|
+
data_sources.extend(algorithm.data_sources)
|
|
91
|
+
|
|
92
|
+
if strategy is not None:
|
|
93
|
+
strategies.append(strategy)
|
|
94
|
+
data_sources.extend(strategy.data_sources)
|
|
95
|
+
|
|
96
|
+
for strategy_entry in strategies:
|
|
97
|
+
if strategy_entry.data_sources is not None \
|
|
98
|
+
and len(strategy_entry.data_sources):
|
|
99
|
+
data_sources.extend(strategy_entry.data_sources)
|
|
100
|
+
|
|
101
|
+
algorithm = Algorithm(
|
|
102
|
+
name=name,
|
|
103
|
+
strategies=strategies,
|
|
104
|
+
tasks=tasks,
|
|
105
|
+
on_strategy_run_hooks=on_strategy_run_hooks,
|
|
106
|
+
data_sources=data_sources
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if algorithm.name is None:
|
|
110
|
+
algorithm.name = AlgorithmFactory.create_algorithm_name(algorithm)
|
|
111
|
+
|
|
112
|
+
# Validate the algorithm name
|
|
113
|
+
validate_algorithm_name(algorithm.name)
|
|
114
|
+
return algorithm
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .backtest_data_ranges import select_backtest_date_ranges
|
|
2
|
+
from .ranking import rank_results, create_weights, combine_backtest_metrics
|
|
3
|
+
from .permutation import create_ohlcv_permutation
|
|
4
|
+
from .backtest_utils import load_backtests_from_directory, \
|
|
5
|
+
save_backtests_to_directory
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"select_backtest_date_ranges",
|
|
9
|
+
"rank_results",
|
|
10
|
+
"create_weights",
|
|
11
|
+
"create_ohlcv_permutation",
|
|
12
|
+
"combine_backtest_metrics",
|
|
13
|
+
"load_backtests_from_directory",
|
|
14
|
+
"save_backtests_to_directory"
|
|
15
|
+
]
|