From 85fc9364319b03d2fc75c714f3855349dc0e107d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 Mar 2025 17:22:50 +0100 Subject: [PATCH] feat: add Strategy and parameter file to backtest zip file --- freqtrade/optimize/backtesting.py | 1 + .../optimize/optimize_reports/bt_storage.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index d2efc78b5..9a5e58c92 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -1792,6 +1792,7 @@ class Backtesting: dt_appendix, market_change_data=combined_res, analysis_results=self.analysis_results, + strategy_files={s.get_strategy_name(): s.__file__ for s in self.strategylist}, ) # Results may be mixed up now. Sort them so they follow --strategy-list order. diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index 00c8c1913..202db7c21 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -53,6 +53,7 @@ def store_backtest_results( *, market_change_data: DataFrame | None = None, analysis_results: dict[str, dict[str, DataFrame]] | None = None, + strategy_files: dict[str, str] | None = None, ) -> Path: """ Stores backtest results and analysis data in a zip file, with metadata stored separately @@ -90,6 +91,25 @@ def store_backtest_results( dump_json_to_file(config_buf, sanitize_config(config["original_config"])) zipf.writestr(f"{base_filename.stem}_config.json", config_buf.getvalue()) + for strategy_name, strategy_file in (strategy_files or {}).items(): + # Store the strategy file and its parameters + strategy_buf = BytesIO() + strategy_path = Path(strategy_file) + with strategy_path.open("rb") as strategy_file_obj: + strategy_buf.write(strategy_file_obj.read()) + strategy_buf.seek(0) + zipf.writestr(f"{base_filename.stem}_{strategy_name}.py", strategy_buf.getvalue()) + strategy_params = strategy_path.with_suffix(".json") + if strategy_params.is_file(): + strategy_params_buf = BytesIO() + with strategy_params.open("rb") as strategy_params_obj: + strategy_params_buf.write(strategy_params_obj.read()) + strategy_params_buf.seek(0) + zipf.writestr( + f"{base_filename.stem}_{strategy_name}.json", + strategy_params_buf.getvalue(), + ) + # Add market change data if present if market_change_data is not None: market_change_name = f"{base_filename.stem}_market_change.feather"