From 6ccd98d795f20ebb1866111175a543a86c609d4f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 14:03:55 +0200 Subject: [PATCH 01/23] feat: introduce --export-directory --- freqtrade/commands/arguments.py | 8 +++++++- freqtrade/commands/cli_options.py | 6 ++++++ freqtrade/configuration/configuration.py | 18 ++++++++++++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index fa3c8bf5d..3f1fb9297 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -54,6 +54,7 @@ ARGS_BACKTEST = [ "strategy_list", "export", "exportfilename", + "exportdirectory", "backtest_breakdown", "backtest_cache", "freqai_backtest_live_models", @@ -94,7 +95,12 @@ ARGS_LIST_FREQAIMODELS = ["freqaimodel_path", "print_one_column"] ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column"] -ARGS_BACKTEST_SHOW = ["exportfilename", "backtest_show_pair_list", "backtest_breakdown"] +ARGS_BACKTEST_SHOW = [ + "exportfilename", + "exportdirectory", + "backtest_show_pair_list", + "backtest_breakdown", +] ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all", "trading_mode", "dex_exchanges"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 446e0fad7..33dc8fc61 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -209,6 +209,12 @@ AVAILABLE_CLI_OPTIONS = { help="Add notes to the backtest results.", metavar="TEXT", ), + "exportdirectory": Arg( + "--export-directory", + help="Directory to use for backtest results." + "Example: `--export-directory=user_data/backtest_results/`", + metavar="PATH", + ), "exportfilename": Arg( "--backtest-filename", "--export-filename", diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index e2601ee48..62d7d41f4 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -209,13 +209,27 @@ class Configuration: config.update({"datadir": create_datadir(config, self.args.get("datadir"))}) logger.info("Using data directory: %s ...", config.get("datadir")) + self._args_to_config( + config, argname="exportdirectory", logstring="Using {} as backtest directory ..." + ) + if self.args.get("exportfilename"): self._args_to_config( config, argname="exportfilename", logstring="Storing backtest results to {} ..." ) config["exportfilename"] = Path(config["exportfilename"]) - else: - config["exportfilename"] = config["user_data_dir"] / "backtest_results" + if config["exportdirectory"].is_dir(): + logger.warning( + "DEPRECATED: Using `--export-filename` with directories is deprecated, " + "use `--export-directory` instead." + ) + if config.get("exportdirectory") is None: + # Fallback - assign export-directory directly. + config["exportdirectory"] = config["exportfilename"] + + if not config.get("exportdirectory"): + config["exportdirectory"] = config["user_data_dir"] / "backtest_results" + config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("show_sensitive"): logger.warning( From c63d0e167cd99146d1529ee2da915cac8ca14790 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 14:04:23 +0200 Subject: [PATCH 02/23] chore: switch to using exportdirectory --- freqtrade/commands/optimize_commands.py | 2 +- freqtrade/data/entryexitanalysis.py | 12 ++++++------ freqtrade/optimize/optimize_reports/bt_storage.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/freqtrade/commands/optimize_commands.py b/freqtrade/commands/optimize_commands.py index 5ec3dfe01..9c3a861fd 100644 --- a/freqtrade/commands/optimize_commands.py +++ b/freqtrade/commands/optimize_commands.py @@ -72,7 +72,7 @@ def start_backtesting_show(args: dict[str, Any]) -> None: from freqtrade.data.btanalysis import load_backtest_stats from freqtrade.optimize.optimize_reports import show_backtest_results, show_sorted_pairlist - results = load_backtest_stats(config["exportfilename"]) + results = load_backtest_stats(config["exportdirectory"]) show_backtest_results(config, results) show_sorted_pairlist(config, results) diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index cbd6aae41..aa9a2d028 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -330,7 +330,7 @@ def process_entry_exit_reasons(config: Config): do_rejected = config.get("analysis_rejected", False) to_csv = config.get("analysis_to_csv", False) csv_path = Path( - config.get("analysis_csv_path", config["exportfilename"]), # type: ignore[arg-type] + config.get("analysis_csv_path", config["exportdirectory"]), # type: ignore[arg-type] ) if entry_only is True and exit_only is True: @@ -344,21 +344,21 @@ def process_entry_exit_reasons(config: Config): None if config.get("timerange") is None else str(config.get("timerange")) ) try: - backtest_stats = load_backtest_stats(config["exportfilename"]) + backtest_stats = load_backtest_stats(config["exportdirectory"]) except ValueError as e: raise ConfigurationError(e) from e for strategy_name, results in backtest_stats["strategy"].items(): - trades = load_backtest_data(config["exportfilename"], strategy_name) + trades = load_backtest_data(config["exportdirectory"], strategy_name) if trades is not None and not trades.empty: - signal_candles = load_backtest_analysis_data(config["exportfilename"], "signals") - exit_signals = load_backtest_analysis_data(config["exportfilename"], "exited") + signal_candles = load_backtest_analysis_data(config["exportdirectory"], "signals") + exit_signals = load_backtest_analysis_data(config["exportdirectory"], "exited") rej_df = None if do_rejected: rejected_signals_dict = load_backtest_analysis_data( - config["exportfilename"], "rejected" + config["exportdirectory"], "rejected" ) rej_df = prepare_results( rejected_signals_dict, diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index 1e6a67e81..ef73d4721 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -64,7 +64,7 @@ def store_backtest_results( :param market_change_data: Dataframe containing market change data :param analysis_results: Dictionary containing analysis results """ - recordfilename: Path = config["exportfilename"] + recordfilename: Path = config["exportdirectory"] zip_filename = _generate_filename(recordfilename, dtappendix, ".zip") base_filename = _generate_filename(recordfilename, dtappendix, "") json_filename = _generate_filename(recordfilename, dtappendix, ".json") From dacd09db8bb29211572bf62e7ffcf3ba183034ce Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 14:16:31 +0200 Subject: [PATCH 03/23] chore: improved code logic --- freqtrade/configuration/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 62d7d41f4..650725f53 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -212,6 +212,7 @@ class Configuration: self._args_to_config( config, argname="exportdirectory", logstring="Using {} as backtest directory ..." ) + config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("exportfilename"): self._args_to_config( @@ -229,7 +230,6 @@ class Configuration: if not config.get("exportdirectory"): config["exportdirectory"] = config["user_data_dir"] / "backtest_results" - config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("show_sensitive"): logger.warning( From dc12b3e7505e25e891e1b8fa1c02f41fd02c70bc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:05:44 +0200 Subject: [PATCH 04/23] feat: improved support for split "export-directory" and export-filenames --- freqtrade/commands/optimize_commands.py | 2 +- freqtrade/data/btanalysis/bt_fileutils.py | 38 ++++++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/freqtrade/commands/optimize_commands.py b/freqtrade/commands/optimize_commands.py index 9c3a861fd..7ddbf8af3 100644 --- a/freqtrade/commands/optimize_commands.py +++ b/freqtrade/commands/optimize_commands.py @@ -72,7 +72,7 @@ def start_backtesting_show(args: dict[str, Any]) -> None: from freqtrade.data.btanalysis import load_backtest_stats from freqtrade.optimize.optimize_reports import show_backtest_results, show_sorted_pairlist - results = load_backtest_stats(config["exportdirectory"]) + results = load_backtest_stats(config["exportdirectory"], config["exportfilename"]) show_backtest_results(config, results) show_sorted_pairlist(config, results) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 5d7a2083c..6a184541a 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -155,33 +155,41 @@ def load_backtest_metadata(filename: Path | str) -> dict[str, Any]: raise OperationalException("Unexpected error while loading backtest metadata.") from e -def load_backtest_stats(filename: Path | str) -> BacktestResultType: +def load_backtest_stats( + file_or_directory: Path | str, filename: Path | str | None = None +) -> BacktestResultType: """ Load backtest statistics file. - :param filename: pathlib.Path object, or string pointing to the file. + :param file_or_directory: pathlib.Path object, or string pointing to the directory, + or absolute/relative path to the backtest results file. + :param filename: Optional filename to load from (if different from the main filename). + Only valid when loading from a directory. :return: a dictionary containing the resulting file. """ - if isinstance(filename, str): - filename = Path(filename) - if filename.is_dir(): - filename = filename / get_latest_backtest_filename(filename) - if not filename.is_file(): - raise ValueError(f"File {filename} does not exist.") - logger.info(f"Loading backtest result from {filename}") + if isinstance(file_or_directory, str): + file_or_directory = Path(file_or_directory) + if file_or_directory.is_dir(): + if not filename: + filename = get_latest_backtest_filename(file_or_directory) + fn = file_or_directory / filename + else: + fn = file_or_directory - if filename.suffix == ".zip": + if not fn.is_file(): + raise ValueError(f"File {fn} does not exist.") + logger.info(f"Loading backtest result from {fn}") + + if fn.suffix == ".zip": data = json_load( - StringIO( - load_file_from_zip(filename, filename.with_suffix(".json").name).decode("utf-8") - ) + StringIO(load_file_from_zip(fn, fn.with_suffix(".json").name).decode("utf-8")) ) else: - with filename.open() as file: + with fn.open() as file: data = json_load(file) # Legacy list format does not contain metadata. if isinstance(data, dict): - data["metadata"] = load_backtest_metadata(filename) + data["metadata"] = load_backtest_metadata(fn) return data From 4de1501c68a04527dbd0e3b4ed87bd1c65062802 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:08:20 +0200 Subject: [PATCH 05/23] fix: argument load stability --- freqtrade/configuration/configuration.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 650725f53..c643a1d5f 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -212,14 +212,13 @@ class Configuration: self._args_to_config( config, argname="exportdirectory", logstring="Using {} as backtest directory ..." ) - config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("exportfilename"): self._args_to_config( config, argname="exportfilename", logstring="Storing backtest results to {} ..." ) config["exportfilename"] = Path(config["exportfilename"]) - if config["exportdirectory"].is_dir(): + if config.get("exportdirectory") and Path(config["exportdirectory"]).is_dir(): logger.warning( "DEPRECATED: Using `--export-filename` with directories is deprecated, " "use `--export-directory` instead." @@ -227,9 +226,9 @@ class Configuration: if config.get("exportdirectory") is None: # Fallback - assign export-directory directly. config["exportdirectory"] = config["exportfilename"] - if not config.get("exportdirectory"): config["exportdirectory"] = config["user_data_dir"] / "backtest_results" + config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("show_sensitive"): logger.warning( From 74aa17d5349eeb6ba4fafd6fb793e9232c0ff9cd Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:11:06 +0200 Subject: [PATCH 06/23] feat: support both relative filenames, as well as just the filename --- freqtrade/data/btanalysis/bt_fileutils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 6a184541a..5df8ef2a9 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -171,7 +171,10 @@ def load_backtest_stats( if file_or_directory.is_dir(): if not filename: filename = get_latest_backtest_filename(file_or_directory) - fn = file_or_directory / filename + if filename.is_file(): + fn = filename + else: + fn = file_or_directory / filename else: fn = file_or_directory From 33c2cc806a73e77f179dacbde2e74562ed08330e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:14:55 +0200 Subject: [PATCH 07/23] refactor: extract bt file normalization to separate function --- freqtrade/data/btanalysis/bt_fileutils.py | 31 +++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 5df8ef2a9..e9c58cf45 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -155,16 +155,12 @@ def load_backtest_metadata(filename: Path | str) -> dict[str, Any]: raise OperationalException("Unexpected error while loading backtest metadata.") from e -def load_backtest_stats( - file_or_directory: Path | str, filename: Path | str | None = None -) -> BacktestResultType: +def _normalize_filename(file_or_directory: Path | str, filename: Path | str | None = None) -> Path: """ - Load backtest statistics file. - :param file_or_directory: pathlib.Path object, or string pointing to the directory, - or absolute/relative path to the backtest results file. - :param filename: Optional filename to load from (if different from the main filename). - Only valid when loading from a directory. - :return: a dictionary containing the resulting file. + Normalize the filename by ensuring it is a Path object. + :param file_or_directory: The directory or file to normalize. + :param filename: The filename to normalize. + :return: A Path object representing the normalized filename. """ if isinstance(file_or_directory, str): file_or_directory = Path(file_or_directory) @@ -177,9 +173,24 @@ def load_backtest_stats( fn = file_or_directory / filename else: fn = file_or_directory + return fn + + +def load_backtest_stats( + file_or_directory: Path | str, filename: Path | str | None = None +) -> BacktestResultType: + """ + Load backtest statistics file. + :param file_or_directory: pathlib.Path object, or string pointing to the directory, + or absolute/relative path to the backtest results file. + :param filename: Optional filename to load from (if different from the main filename). + Only valid when loading from a directory. + :return: a dictionary containing the resulting file. + """ + fn = _normalize_filename(file_or_directory, filename) if not fn.is_file(): - raise ValueError(f"File {fn} does not exist.") + raise ValueError(f"File or directory {fn} does not exist.") logger.info(f"Loading backtest result from {fn}") if fn.suffix == ".zip": From aefc72554a26e6a54474ad45be3494948454e479 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:17:06 +0200 Subject: [PATCH 08/23] chore: ensure filename is a path object --- freqtrade/data/btanalysis/bt_fileutils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index e9c58cf45..88b690f6c 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -167,8 +167,8 @@ def _normalize_filename(file_or_directory: Path | str, filename: Path | str | No if file_or_directory.is_dir(): if not filename: filename = get_latest_backtest_filename(file_or_directory) - if filename.is_file(): - fn = filename + if Path(filename).is_file(): + fn = Path(filename) else: fn = file_or_directory / filename else: From 09b084e85aed79af69e5b6b245c4f9a0a6463c11 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:44:50 +0200 Subject: [PATCH 09/23] chore: adjust backtest-optimize reports tests --- tests/optimize/test_optimize_reports.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index b04e28da8..1ff4bfe3c 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -236,7 +236,7 @@ def test_generate_backtest_stats(default_conf, testdatadir, tmp_path): filename_last = tmp_path / LAST_BT_RESULT_FN _backup_file(filename_last, copy_file=True) assert not filename.is_file() - default_conf["exportfilename"] = filename + default_conf["exportdirectory"] = filename store_backtest_results(default_conf, stats, "2022_01_01_15_05_13") @@ -263,7 +263,7 @@ def test_store_backtest_results(testdatadir, mocker): zip_mock = mocker.patch("freqtrade.optimize.optimize_reports.bt_storage.ZipFile") data = {"metadata": {}, "strategy": {}, "strategy_comparison": []} store_backtest_results( - {"exportfilename": testdatadir, "original_config": {}}, data, "2022_01_01_15_05_13" + {"exportdirectory": testdatadir, "original_config": {}}, data, "2022_01_01_15_05_13" ) assert dump_mock.call_count == 2 @@ -275,7 +275,7 @@ def test_store_backtest_results(testdatadir, mocker): zip_mock.reset_mock() filename = testdatadir / "testresult.json" store_backtest_results( - {"exportfilename": filename, "original_config": {}}, data, "2022_01_01_15_05_13" + {"exportdirectory": filename, "original_config": {}}, data, "2022_01_01_15_05_13" ) assert dump_mock.call_count == 2 assert zip_mock.call_count == 1 @@ -287,7 +287,7 @@ def test_store_backtest_results(testdatadir, mocker): def test_store_backtest_results_real(tmp_path, caplog): data = {"metadata": {}, "strategy": {}, "strategy_comparison": []} config = { - "exportfilename": tmp_path, + "exportdirectory": tmp_path, "original_config": {}, } store_backtest_results( @@ -356,7 +356,7 @@ def test_write_read_backtest_candles(tmp_path): bt_results = {"metadata": {}, "strategy": {}, "strategy_comparison": []} mock_conf = { - "exportfilename": tmp_path, + "exportdirectory": tmp_path, "export": "signals", "runmode": "backtest", "original_config": {}, From 5c977c212bf1dc1240658c509de9cb956731ef7c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:45:44 +0200 Subject: [PATCH 10/23] test: drop test part using --export-filename to determine backtest result naming --- tests/optimize/test_optimize_reports.py | 27 ------------------------- 1 file changed, 27 deletions(-) diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 1ff4bfe3c..3cd89245b 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -393,33 +393,6 @@ def test_write_read_backtest_candles(tmp_path): _clean_test_file(stored_file) - # test file exporting - filename = tmp_path / "testresult" - mock_conf["exportfilename"] = filename - store_backtest_results(mock_conf, bt_results, sample_date, analysis_results=data) - stored_file = tmp_path / f"testresult-{sample_date}.zip" - signals_pkl = f"testresult-{sample_date}_signals.pkl" - rejected_pkl = f"testresult-{sample_date}_rejected.pkl" - exited_pkl = f"testresult-{sample_date}_exited.pkl" - assert not (tmp_path / signals_pkl).is_file() - assert stored_file.is_file() - - with ZipFile(stored_file, "r") as zipf: - assert signals_pkl in zipf.namelist() - assert rejected_pkl in zipf.namelist() - assert exited_pkl in zipf.namelist() - - with zipf.open(signals_pkl) as scp: - pickled_signal_candles2 = joblib.load(scp) - - assert pickled_signal_candles2.keys() == candle_dict.keys() - assert pickled_signal_candles2["DefStrat"].keys() == pickled_signal_candles2["DefStrat"].keys() - assert pickled_signal_candles2["DefStrat"]["UNITTEST/BTC"].equals( - pickled_signal_candles2["DefStrat"]["UNITTEST/BTC"] - ) - - _clean_test_file(stored_file) - def test_generate_pair_metrics(): results = pd.DataFrame( From 07906d2576eae1ce97afb40b285066dcc0e4ceee Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:46:23 +0200 Subject: [PATCH 11/23] test: update api backtest test --- tests/rpc/test_rpc_apiserver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index c8fdad8b6..56068e6fe 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -2802,8 +2802,8 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmp_path): ftbot.config["export"] = "trades" ftbot.config["backtest_cache"] = "day" ftbot.config["user_data_dir"] = tmp_path - ftbot.config["exportfilename"] = tmp_path / "backtest_results" - ftbot.config["exportfilename"].mkdir() + ftbot.config["exportdirectory"] = tmp_path / "backtest_results" + ftbot.config["exportdirectory"].mkdir() # start backtesting data = { From 36f2bef6b8bc25e18c35e1fd74e3399b74d9e90d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 16 Aug 2025 15:50:22 +0200 Subject: [PATCH 12/23] test: update test for split backtest-show reality --- tests/commands/test_commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 85e42c11d..2dde29c0d 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -1862,8 +1862,10 @@ def test_backtesting_show(mocker, testdatadir, capsys): sbr = mocker.patch("freqtrade.optimize.optimize_reports.show_backtest_results") args = [ "backtesting-show", + "--export-directory", + f"{testdatadir / 'backtest_results'}", "--export-filename", - f"{testdatadir / 'backtest_results/backtest-result.json'}", + "backtest-result.json", "--show-pair-list", ] pargs = get_args(args) From 9f1d9add1843dd94b1ae6b8f5a081c9092616bba Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 08:45:04 +0200 Subject: [PATCH 13/23] chore: improve docstring --- freqtrade/data/btanalysis/bt_fileutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 88b690f6c..766e0a47b 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -386,7 +386,7 @@ def _load_backtest_data_df_compatibility(df: pd.DataFrame) -> pd.DataFrame: def load_backtest_data(filename: Path | str, strategy: str | None = None) -> pd.DataFrame: """ - Load backtest data file. + Load backtest data file, returns a dataframe with the individual trades. :param filename: pathlib.Path object, or string pointing to a file or directory :param strategy: Strategy to load - mainly relevant for multi-strategy backtests Can also serve as protection to load the correct result. From b22bce3dd898351ad26954df1cb41eb390083505 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 08:53:05 +0200 Subject: [PATCH 14/23] feat: Support split directory and filename for backteststats loading --- freqtrade/data/btanalysis/bt_fileutils.py | 40 +++++++++++++++-------- freqtrade/data/entryexitanalysis.py | 18 +++++++--- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index 766e0a47b..cc53aab13 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -155,7 +155,7 @@ def load_backtest_metadata(filename: Path | str) -> dict[str, Any]: raise OperationalException("Unexpected error while loading backtest metadata.") from e -def _normalize_filename(file_or_directory: Path | str, filename: Path | str | None = None) -> Path: +def _normalize_filename(file_or_directory: Path | str, filename: Path | str | None) -> Path: """ Normalize the filename by ensuring it is a Path object. :param file_or_directory: The directory or file to normalize. @@ -384,16 +384,21 @@ def _load_backtest_data_df_compatibility(df: pd.DataFrame) -> pd.DataFrame: return df -def load_backtest_data(filename: Path | str, strategy: str | None = None) -> pd.DataFrame: +def load_backtest_data( + file_or_directory: Path | str, strategy: str | None = None, filename: Path | str | None = None +) -> pd.DataFrame: """ Load backtest data file, returns a dataframe with the individual trades. - :param filename: pathlib.Path object, or string pointing to a file or directory + :param file_or_directory: pathlib.Path object, or string pointing to the directory, + or absolute/relative path to the backtest results file. :param strategy: Strategy to load - mainly relevant for multi-strategy backtests Can also serve as protection to load the correct result. + :param filename: Optional filename to load from (if different from the main filename). + Only valid when loading from a directory. :return: a dataframe with the analysis results :raise: ValueError if loading goes wrong. """ - data = load_backtest_stats(filename) + data = load_backtest_stats(file_or_directory, filename) if not isinstance(data, list): # new, nested format if "strategy" not in data: @@ -452,20 +457,29 @@ def load_file_from_zip(zip_path: Path, filename: str) -> bytes: raise ValueError(f"Bad zip file: {zip_path}.") from None -def load_backtest_analysis_data(backtest_dir: Path, name: Literal["signals", "rejected", "exited"]): +def load_backtest_analysis_data( + file_or_directory: Path, + name: Literal["signals", "rejected", "exited"], + filename: Path | str | None = None, +): """ Load backtest analysis data either from a pickle file or from within a zip file - :param backtest_dir: Directory containing backtest results + :param file_or_directory: pathlib.Path object, or string pointing to the directory, + or absolute/relative path to the backtest results file. :param name: Name of the analysis data to load (signals, rejected, exited) + :param filename: Optional filename to load from (if different from the main filename). + Only valid when loading from a directory. :return: Analysis data """ import joblib - if backtest_dir.is_dir(): - lbf = Path(get_latest_backtest_filename(backtest_dir)) - zip_path = backtest_dir / lbf + zip_path = _normalize_filename(file_or_directory, None) + + if file_or_directory.is_dir(): + lbf = Path(get_latest_backtest_filename(file_or_directory)) + zip_path = file_or_directory / lbf else: - zip_path = backtest_dir + zip_path = file_or_directory if zip_path.suffix == ".zip": # Load from zip file @@ -480,10 +494,10 @@ def load_backtest_analysis_data(backtest_dir: Path, name: Literal["signals", "re else: # Load from separate pickle file - if backtest_dir.is_dir(): - scpf = Path(backtest_dir, f"{zip_path.stem}_{name}.pkl") + if file_or_directory.is_dir(): + scpf = Path(file_or_directory, f"{zip_path.stem}_{name}.pkl") else: - scpf = Path(backtest_dir.parent / f"{backtest_dir.stem}_{name}.pkl") + scpf = Path(file_or_directory.parent / f"{file_or_directory.stem}_{name}.pkl") try: with scpf.open("rb") as scp: diff --git a/freqtrade/data/entryexitanalysis.py b/freqtrade/data/entryexitanalysis.py index aa9a2d028..1509fade7 100644 --- a/freqtrade/data/entryexitanalysis.py +++ b/freqtrade/data/entryexitanalysis.py @@ -344,21 +344,29 @@ def process_entry_exit_reasons(config: Config): None if config.get("timerange") is None else str(config.get("timerange")) ) try: - backtest_stats = load_backtest_stats(config["exportdirectory"]) + backtest_stats = load_backtest_stats( + config["exportdirectory"], config["exportfilename"] + ) except ValueError as e: raise ConfigurationError(e) from e for strategy_name, results in backtest_stats["strategy"].items(): - trades = load_backtest_data(config["exportdirectory"], strategy_name) + trades = load_backtest_data( + config["exportdirectory"], strategy_name, config["exportfilename"] + ) if trades is not None and not trades.empty: - signal_candles = load_backtest_analysis_data(config["exportdirectory"], "signals") - exit_signals = load_backtest_analysis_data(config["exportdirectory"], "exited") + signal_candles = load_backtest_analysis_data( + config["exportdirectory"], "signals", config["exportfilename"] + ) + exit_signals = load_backtest_analysis_data( + config["exportdirectory"], "exited", config["exportfilename"] + ) rej_df = None if do_rejected: rejected_signals_dict = load_backtest_analysis_data( - config["exportdirectory"], "rejected" + config["exportdirectory"], "rejected", config["exportfilename"] ) rej_df = prepare_results( rejected_signals_dict, From 615095c780f99bd8c870554238ddb8f53a65fff7 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 08:53:16 +0200 Subject: [PATCH 15/23] feat: add exportdirectory to entry/exit analysis --- freqtrade/commands/arguments.py | 1 + freqtrade/data/btanalysis/bt_fileutils.py | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 3f1fb9297..f96148e3c 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -239,6 +239,7 @@ ARGS_HYPEROPT_SHOW = [ ARGS_ANALYZE_ENTRIES_EXITS = [ "exportfilename", + "exportdirectory", "analysis_groups", "enter_reason_list", "exit_reason_list", diff --git a/freqtrade/data/btanalysis/bt_fileutils.py b/freqtrade/data/btanalysis/bt_fileutils.py index cc53aab13..ea9c993fb 100644 --- a/freqtrade/data/btanalysis/bt_fileutils.py +++ b/freqtrade/data/btanalysis/bt_fileutils.py @@ -473,13 +473,7 @@ def load_backtest_analysis_data( """ import joblib - zip_path = _normalize_filename(file_or_directory, None) - - if file_or_directory.is_dir(): - lbf = Path(get_latest_backtest_filename(file_or_directory)) - zip_path = file_or_directory / lbf - else: - zip_path = file_or_directory + zip_path = _normalize_filename(file_or_directory, filename) if zip_path.suffix == ".zip": # Load from zip file From eee233f89493f9632204b63479a7c46513671c90 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 14:56:33 +0200 Subject: [PATCH 16/23] fix: ensure exportfilename is always set --- freqtrade/configuration/configuration.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index c643a1d5f..3a6121b08 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -228,6 +228,8 @@ class Configuration: config["exportdirectory"] = config["exportfilename"] if not config.get("exportdirectory"): config["exportdirectory"] = config["user_data_dir"] / "backtest_results" + if not config.get("exportfilename"): + config["exportfilename"] = None config["exportdirectory"] = Path(config["exportdirectory"]) if self.args.get("show_sensitive"): From e3f241acb7f795a180639c631376358104ad8992 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:08:55 +0200 Subject: [PATCH 17/23] chore: improve help text wording --- freqtrade/commands/cli_options.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 33dc8fc61..19e229e7d 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -199,27 +199,29 @@ AVAILABLE_CLI_OPTIONS = { "(so `backtest-data.json` becomes `backtest-data-SampleStrategy.json`", nargs="+", ), - "export": Arg( - "--export", - help="Export backtest results (default: trades).", - choices=constants.EXPORT_OPTIONS, - ), "backtest_notes": Arg( "--notes", help="Add notes to the backtest results.", metavar="TEXT", ), + "export": Arg( + "--export", + help="Export backtest results (default: trades).", + choices=constants.EXPORT_OPTIONS, + ), "exportdirectory": Arg( "--export-directory", - help="Directory to use for backtest results." - "Example: `--export-directory=user_data/backtest_results/`", + "--backtest-directory", + help="Directory to use for backtest results. " + "Example: `--export-directory=user_data/backtest_results/`. ", metavar="PATH", ), "exportfilename": Arg( "--backtest-filename", "--export-filename", help="Use this filename for backtest results." - "Example: `--backtest-filename=user_data/backtest_results/`", + "Example: `--backtest-filename=backtest_results_2020-09-27_16-20-48.json`. " + "Assumes either user_data/backtest_results/ or `--export-directory` as base directory.", metavar="PATH", ), "disableparamexport": Arg( From 7e4b9d7481890cd543251344612daecb6ece5b06 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:09:12 +0200 Subject: [PATCH 18/23] docs: update doc segments with new help text --- docs/commands/backtesting-analysis.md | 9 ++++++++- docs/commands/backtesting-show.md | 10 ++++++++-- docs/commands/backtesting.md | 9 ++++++++- docs/commands/lookahead-analysis.md | 9 ++++++++- docs/commands/plot-dataframe.md | 5 ++++- docs/commands/plot-profit.md | 5 ++++- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/docs/commands/backtesting-analysis.md b/docs/commands/backtesting-analysis.md index f6e79e858..35462d18c 100644 --- a/docs/commands/backtesting-analysis.md +++ b/docs/commands/backtesting-analysis.md @@ -3,6 +3,7 @@ usage: freqtrade backtesting-analysis [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--backtest-filename PATH] + [--export-directory PATH] [--analysis-groups {0,1,2,3,4,5} [{0,1,2,3,4,5} ...]] [--enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...]] [--exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...]] @@ -16,7 +17,13 @@ options: -h, --help show this help message and exit --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. + --export-directory PATH, --backtest-directory PATH + Directory to use for backtest results. Example: + `--export-directory=user_data/backtest_results/`. --analysis-groups {0,1,2,3,4,5} [{0,1,2,3,4,5} ...] grouping output - 0: simple wins/losses by enter tag, 1: by enter_tag, 2: by enter_tag and exit_tag, 3: by diff --git a/docs/commands/backtesting-show.md b/docs/commands/backtesting-show.md index 5e156b4a9..3a1b4be2b 100644 --- a/docs/commands/backtesting-show.md +++ b/docs/commands/backtesting-show.md @@ -2,14 +2,20 @@ usage: freqtrade backtesting-show [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--backtest-filename PATH] - [--show-pair-list] + [--export-directory PATH] [--show-pair-list] [--breakdown {day,week,month,year} [{day,week,month,year} ...]] options: -h, --help show this help message and exit --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. + --export-directory PATH, --backtest-directory PATH + Directory to use for backtest results. Example: + `--export-directory=user_data/backtest_results/`. --show-pair-list Show backtesting pairlist sorted by profit. --breakdown {day,week,month,year} [{day,week,month,year} ...] Show backtesting breakdown per [day, week, month, diff --git a/docs/commands/backtesting.md b/docs/commands/backtesting.md index 70c2c51c9..55ed392d8 100644 --- a/docs/commands/backtesting.md +++ b/docs/commands/backtesting.md @@ -15,6 +15,7 @@ usage: freqtrade backtesting [-h] [-v] [--no-color] [--logfile FILE] [-V] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--export {none,trades,signals}] [--backtest-filename PATH] + [--export-directory PATH] [--breakdown {day,week,month,year} [{day,week,month,year} ...]] [--cache {none,day,week,month}] [--freqai-backtest-live-models] [--notes TEXT] @@ -63,7 +64,13 @@ options: Export backtest results (default: trades). --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. + --export-directory PATH, --backtest-directory PATH + Directory to use for backtest results. Example: + `--export-directory=user_data/backtest_results/`. --breakdown {day,week,month,year} [{day,week,month,year} ...] Show backtesting breakdown per [day, week, month, year]. diff --git a/docs/commands/lookahead-analysis.md b/docs/commands/lookahead-analysis.md index 84ea9c1d9..29d64940a 100644 --- a/docs/commands/lookahead-analysis.md +++ b/docs/commands/lookahead-analysis.md @@ -16,6 +16,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--export {none,trades,signals}] [--backtest-filename PATH] + [--export-directory PATH] [--freqai-backtest-live-models] [--minimum-trade-amount INT] [--targeted-trade-amount INT] @@ -62,7 +63,13 @@ options: Export backtest results (default: trades). --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. + --export-directory PATH, --backtest-directory PATH + Directory to use for backtest results. Example: + `--export-directory=user_data/backtest_results/`. --freqai-backtest-live-models Run backtest with ready models. --minimum-trade-amount INT diff --git a/docs/commands/plot-dataframe.md b/docs/commands/plot-dataframe.md index 3179f8867..8fc066aab 100644 --- a/docs/commands/plot-dataframe.md +++ b/docs/commands/plot-dataframe.md @@ -40,7 +40,10 @@ options: Export backtest results (default: trades). --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. --timerange TIMERANGE Specify what timerange of data to use. -i TIMEFRAME, --timeframe TIMEFRAME diff --git a/docs/commands/plot-profit.md b/docs/commands/plot-profit.md index 8bd970f2a..1579adbe1 100644 --- a/docs/commands/plot-profit.md +++ b/docs/commands/plot-profit.md @@ -21,7 +21,10 @@ options: Export backtest results (default: trades). --backtest-filename PATH, --export-filename PATH Use this filename for backtest results.Example: - `--backtest-filename=user_data/backtest_results/` + `--backtest- + filename=backtest_results_2020-09-27_16-20-48.json`. + Assumes either user_data/backtest_results/ or + `--export-directory` as base directory. --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` for Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for From 6abc0a3fb96c2374a2ca0f0133206d51ca74e2dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:13:05 +0200 Subject: [PATCH 19/23] docs: update wording in documentation --- docs/advanced-backtesting.md | 10 +++++----- docs/backtesting.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index aac865422..b76ad660e 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -46,29 +46,29 @@ ranging from the simplest (0) to the most detailed per pair, per buy and per sel More options are available by running with the `-h` option. -### Using export-filename +### Using backtest-filename Normally, `backtesting-analysis` uses the latest backtest results, but if you wanted to go -back to a previous backtest output, you need to supply the `--export-filename` option. +back to a previous backtest output, you need to supply the `--backtest-filename` option. You can supply the same parameter to `backtest-analysis` with the name of the final backtest output file. This allows you to keep historical versions of backtest results and re-analyse them at a later date: ``` bash -freqtrade backtesting-analysis -c --timeframe --strategy --timerange= --export=signals --export-filename=user_data/backtest-results/backtest-result-2025-03-05_20-38-34.zip +freqtrade backtesting-analysis -c --timeframe --strategy --timerange= --export=signals --backtest-filename=backtest-result-2025-03-05_20-38-34.zip ``` You should see some output similar to below in the logs with the name of the timestamped filename that was exported: ``` -2022-06-14 16:28:32,698 - freqtrade.misc - INFO - dumping json to "/tmp/mystrat_backtest-2022-06-14_16-28-32.json" +2022-06-14 16:28:32,698 - freqtrade.misc - INFO - dumping json to "mystrat_backtest-2022-06-14_16-28-32.json" ``` You can then use that filename in `backtesting-analysis`: ``` -freqtrade backtesting-analysis -c --export-filename=/tmp/mystrat_backtest-2022-06-14_16-28-32.json +freqtrade backtesting-analysis -c --backtest-filename=mystrat_backtest-2022-06-14_16-28-32.json ``` ### Tuning the buy tags and sell tags to display diff --git a/docs/backtesting.md b/docs/backtesting.md index 41956b12d..5e9d285e1 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -108,7 +108,7 @@ Only use this if you're sure you'll not want to plot or analyze your results fur Exporting trades to file specifying a custom directory ```bash -freqtrade backtesting --strategy backtesting --export trades --export-filename=user_data/custom-backtest-results +freqtrade backtesting --strategy backtesting --export trades --backtest-directory=user_data/custom-backtest-results ``` --- From a00a5e52c41474c72af341f5b4e75dff2bcde457 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:15:37 +0200 Subject: [PATCH 20/23] docs: update backtest-filename wording --- docs/advanced-backtesting.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index b76ad660e..4daa51d58 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -48,11 +48,7 @@ More options are available by running with the `-h` option. ### Using backtest-filename -Normally, `backtesting-analysis` uses the latest backtest results, but if you wanted to go -back to a previous backtest output, you need to supply the `--backtest-filename` option. -You can supply the same parameter to `backtest-analysis` with the name of the final backtest -output file. This allows you to keep historical versions of backtest results and re-analyse -them at a later date: +By default, `backtesting-analysis` processes the most recent backtest results. If you want to analyze results from an earlier backtest, use the `--backtest-filename` option to specify the desired file. This lets you revisit and re-analyze historical backtest outputs at any time by providing the filename of the relevant backtest result: ``` bash freqtrade backtesting-analysis -c --timeframe --strategy --timerange= --export=signals --backtest-filename=backtest-result-2025-03-05_20-38-34.zip From e34ea393d91edc855e6140af8e563e9571605c3e Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:15:55 +0200 Subject: [PATCH 21/23] docs: improved help wording --- docs/commands/backtesting-analysis.md | 6 +++--- docs/commands/backtesting-show.md | 7 ++++--- docs/commands/backtesting.md | 6 +++--- docs/commands/lookahead-analysis.md | 6 +++--- docs/commands/plot-dataframe.md | 2 +- docs/commands/plot-profit.md | 2 +- freqtrade/commands/cli_options.py | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/commands/backtesting-analysis.md b/docs/commands/backtesting-analysis.md index 35462d18c..826792f4f 100644 --- a/docs/commands/backtesting-analysis.md +++ b/docs/commands/backtesting-analysis.md @@ -3,7 +3,7 @@ usage: freqtrade backtesting-analysis [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--backtest-filename PATH] - [--export-directory PATH] + [--backtest-directory PATH] [--analysis-groups {0,1,2,3,4,5} [{0,1,2,3,4,5} ...]] [--enter-reason-list ENTER_REASON_LIST [ENTER_REASON_LIST ...]] [--exit-reason-list EXIT_REASON_LIST [EXIT_REASON_LIST ...]] @@ -19,9 +19,9 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. - --export-directory PATH, --backtest-directory PATH + --backtest-directory PATH, --export-directory PATH Directory to use for backtest results. Example: `--export-directory=user_data/backtest_results/`. --analysis-groups {0,1,2,3,4,5} [{0,1,2,3,4,5} ...] diff --git a/docs/commands/backtesting-show.md b/docs/commands/backtesting-show.md index 3a1b4be2b..eb9c7137b 100644 --- a/docs/commands/backtesting-show.md +++ b/docs/commands/backtesting-show.md @@ -2,7 +2,8 @@ usage: freqtrade backtesting-show [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--backtest-filename PATH] - [--export-directory PATH] [--show-pair-list] + [--backtest-directory PATH] + [--show-pair-list] [--breakdown {day,week,month,year} [{day,week,month,year} ...]] options: @@ -11,9 +12,9 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. - --export-directory PATH, --backtest-directory PATH + --backtest-directory PATH, --export-directory PATH Directory to use for backtest results. Example: `--export-directory=user_data/backtest_results/`. --show-pair-list Show backtesting pairlist sorted by profit. diff --git a/docs/commands/backtesting.md b/docs/commands/backtesting.md index 55ed392d8..7082fb362 100644 --- a/docs/commands/backtesting.md +++ b/docs/commands/backtesting.md @@ -15,7 +15,7 @@ usage: freqtrade backtesting [-h] [-v] [--no-color] [--logfile FILE] [-V] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--export {none,trades,signals}] [--backtest-filename PATH] - [--export-directory PATH] + [--backtest-directory PATH] [--breakdown {day,week,month,year} [{day,week,month,year} ...]] [--cache {none,day,week,month}] [--freqai-backtest-live-models] [--notes TEXT] @@ -66,9 +66,9 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. - --export-directory PATH, --backtest-directory PATH + --backtest-directory PATH, --export-directory PATH Directory to use for backtest results. Example: `--export-directory=user_data/backtest_results/`. --breakdown {day,week,month,year} [{day,week,month,year} ...] diff --git a/docs/commands/lookahead-analysis.md b/docs/commands/lookahead-analysis.md index 29d64940a..880c41ce1 100644 --- a/docs/commands/lookahead-analysis.md +++ b/docs/commands/lookahead-analysis.md @@ -16,7 +16,7 @@ usage: freqtrade lookahead-analysis [-h] [-v] [--no-color] [--logfile FILE] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--export {none,trades,signals}] [--backtest-filename PATH] - [--export-directory PATH] + [--backtest-directory PATH] [--freqai-backtest-live-models] [--minimum-trade-amount INT] [--targeted-trade-amount INT] @@ -65,9 +65,9 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. - --export-directory PATH, --backtest-directory PATH + --backtest-directory PATH, --export-directory PATH Directory to use for backtest results. Example: `--export-directory=user_data/backtest_results/`. --freqai-backtest-live-models diff --git a/docs/commands/plot-dataframe.md b/docs/commands/plot-dataframe.md index 8fc066aab..a709858f3 100644 --- a/docs/commands/plot-dataframe.md +++ b/docs/commands/plot-dataframe.md @@ -42,7 +42,7 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. --timerange TIMERANGE Specify what timerange of data to use. diff --git a/docs/commands/plot-profit.md b/docs/commands/plot-profit.md index 1579adbe1..e46e4b223 100644 --- a/docs/commands/plot-profit.md +++ b/docs/commands/plot-profit.md @@ -23,7 +23,7 @@ options: Use this filename for backtest results.Example: `--backtest- filename=backtest_results_2020-09-27_16-20-48.json`. - Assumes either user_data/backtest_results/ or + Assumes either `user_data/backtest_results/` or `--export-directory` as base directory. --db-url PATH Override trades database URL, this is useful in custom deployments (default: `sqlite:///tradesv3.sqlite` for diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 19e229e7d..b4641597d 100755 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -210,8 +210,8 @@ AVAILABLE_CLI_OPTIONS = { choices=constants.EXPORT_OPTIONS, ), "exportdirectory": Arg( - "--export-directory", "--backtest-directory", + "--export-directory", help="Directory to use for backtest results. " "Example: `--export-directory=user_data/backtest_results/`. ", metavar="PATH", @@ -221,7 +221,7 @@ AVAILABLE_CLI_OPTIONS = { "--export-filename", help="Use this filename for backtest results." "Example: `--backtest-filename=backtest_results_2020-09-27_16-20-48.json`. " - "Assumes either user_data/backtest_results/ or `--export-directory` as base directory.", + "Assumes either `user_data/backtest_results/` or `--export-directory` as base directory.", metavar="PATH", ), "disableparamexport": Arg( From 7f0e886cfdf079b6eef8704955bca563b5df81be Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 15:31:48 +0200 Subject: [PATCH 22/23] chore: update config message naming --- freqtrade/configuration/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 3a6121b08..5f1715d9a 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -221,7 +221,7 @@ class Configuration: if config.get("exportdirectory") and Path(config["exportdirectory"]).is_dir(): logger.warning( "DEPRECATED: Using `--export-filename` with directories is deprecated, " - "use `--export-directory` instead." + "use `--backtest-directory` instead." ) if config.get("exportdirectory") is None: # Fallback - assign export-directory directly. From 2453e344f4cff60ce3d904f844922994ae3247f4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 17 Aug 2025 17:25:02 +0200 Subject: [PATCH 23/23] docs: improve documentation --- docs/advanced-backtesting.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/advanced-backtesting.md b/docs/advanced-backtesting.md index 4daa51d58..617ea7e3d 100644 --- a/docs/advanced-backtesting.md +++ b/docs/advanced-backtesting.md @@ -48,10 +48,11 @@ More options are available by running with the `-h` option. ### Using backtest-filename -By default, `backtesting-analysis` processes the most recent backtest results. If you want to analyze results from an earlier backtest, use the `--backtest-filename` option to specify the desired file. This lets you revisit and re-analyze historical backtest outputs at any time by providing the filename of the relevant backtest result: +By default, `backtesting-analysis` processes the most recent backtest results in the `user_data/backtest_results` directory. +If you want to analyze results from an earlier backtest, use the `--backtest-filename` option to specify the desired file. This lets you revisit and re-analyze historical backtest outputs at any time by providing the filename of the relevant backtest result: ``` bash -freqtrade backtesting-analysis -c --timeframe --strategy --timerange= --export=signals --backtest-filename=backtest-result-2025-03-05_20-38-34.zip +freqtrade backtesting-analysis -c --timeframe --strategy --timerange --export signals --backtest-filename backtest-result-2025-03-05_20-38-34.zip ``` You should see some output similar to below in the logs with the name of the timestamped @@ -67,6 +68,12 @@ You can then use that filename in `backtesting-analysis`: freqtrade backtesting-analysis -c --backtest-filename=mystrat_backtest-2022-06-14_16-28-32.json ``` +To use a result from a different results directory, you can use `--backtest-directory` to specify the directory + +``` bash +freqtrade backtesting-analysis -c --backtest-directory custom_results/ --backtest-filename mystrat_backtest-2022-06-14_16-28-32.json +``` + ### Tuning the buy tags and sell tags to display To show only certain buy and sell tags in the displayed output, use the following two options: