refactor: move backtest "storage" logic to storage file
This commit is contained in:
@@ -47,8 +47,7 @@ from freqtrade.optimize.optimize_reports import (
|
|||||||
generate_rejected_signals,
|
generate_rejected_signals,
|
||||||
generate_trade_signal_candles,
|
generate_trade_signal_candles,
|
||||||
show_backtest_results,
|
show_backtest_results,
|
||||||
store_backtest_analysis_results,
|
store_backtest_results,
|
||||||
store_backtest_stats,
|
|
||||||
)
|
)
|
||||||
from freqtrade.persistence import (
|
from freqtrade.persistence import (
|
||||||
CustomDataWrapper,
|
CustomDataWrapper,
|
||||||
@@ -1662,21 +1661,12 @@ class Backtesting:
|
|||||||
dt_appendix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
dt_appendix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
if self.config.get("export", "none") in ("trades", "signals"):
|
if self.config.get("export", "none") in ("trades", "signals"):
|
||||||
combined_res = combined_dataframes_with_rel_mean(data, min_date, max_date)
|
combined_res = combined_dataframes_with_rel_mean(data, min_date, max_date)
|
||||||
store_backtest_stats(
|
store_backtest_results(
|
||||||
self.config["exportfilename"],
|
self.config,
|
||||||
self.results,
|
self.results,
|
||||||
dt_appendix,
|
dt_appendix,
|
||||||
market_change_data=combined_res,
|
market_change_data=combined_res,
|
||||||
)
|
analysis_results=self.analysis_results,
|
||||||
|
|
||||||
if (
|
|
||||||
self.config.get("export", "none") == "signals"
|
|
||||||
and self.dataprovider.runmode == RunMode.BACKTEST
|
|
||||||
):
|
|
||||||
store_backtest_analysis_results(
|
|
||||||
self.config["exportfilename"],
|
|
||||||
self.analysis_results,
|
|
||||||
dt_appendix,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Results may be mixed up now. Sort them so they follow --strategy-list order.
|
# Results may be mixed up now. Sort them so they follow --strategy-list order.
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ from freqtrade.optimize.optimize_reports.bt_output import (
|
|||||||
text_table_strategy,
|
text_table_strategy,
|
||||||
text_table_tags,
|
text_table_tags,
|
||||||
)
|
)
|
||||||
from freqtrade.optimize.optimize_reports.bt_storage import (
|
from freqtrade.optimize.optimize_reports.bt_storage import store_backtest_results
|
||||||
store_backtest_analysis_results,
|
|
||||||
store_backtest_stats,
|
|
||||||
)
|
|
||||||
from freqtrade.optimize.optimize_reports.optimize_reports import (
|
from freqtrade.optimize.optimize_reports.optimize_reports import (
|
||||||
generate_all_periodic_breakdown_stats,
|
generate_all_periodic_breakdown_stats,
|
||||||
generate_backtest_stats,
|
generate_backtest_stats,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from pathlib import Path
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.constants import LAST_BT_RESULT_FN
|
from freqtrade.constants import LAST_BT_RESULT_FN
|
||||||
|
from freqtrade.enums.runmode import RunMode
|
||||||
from freqtrade.ft_types import BacktestResultType
|
from freqtrade.ft_types import BacktestResultType
|
||||||
from freqtrade.misc import file_dump_joblib, file_dump_json
|
from freqtrade.misc import file_dump_joblib, file_dump_json
|
||||||
from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename
|
from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename
|
||||||
@@ -29,21 +30,27 @@ def _generate_filename(recordfilename: Path, appendix: str, suffix: str) -> Path
|
|||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def store_backtest_stats(
|
def store_backtest_results(
|
||||||
recordfilename: Path,
|
config: dict,
|
||||||
stats: BacktestResultType,
|
stats: BacktestResultType,
|
||||||
dtappendix: str,
|
dtappendix: str,
|
||||||
*,
|
*,
|
||||||
market_change_data: DataFrame | None = None,
|
market_change_data: DataFrame | None = None,
|
||||||
|
analysis_results: dict[str, dict[str, DataFrame]] | None = None,
|
||||||
) -> Path:
|
) -> Path:
|
||||||
"""
|
"""
|
||||||
Stores backtest results
|
Stores backtest results and analysis data
|
||||||
:param recordfilename: Path object, which can either be a filename or a directory.
|
:param config: Configuration dictionary
|
||||||
Filenames will be appended with a timestamp right before the suffix
|
|
||||||
while for directories, <directory>/backtest-result-<datetime>.json will be used as filename
|
|
||||||
:param stats: Dataframe containing the backtesting statistics
|
:param stats: Dataframe containing the backtesting statistics
|
||||||
:param dtappendix: Datetime to use for the filename
|
:param dtappendix: Datetime to use for the filename
|
||||||
|
:param market_change_data: Dataframe containing market change data
|
||||||
|
:param analysis_results: Dictionary containing analysis results
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Path object, which can either be a filename or a directory.
|
||||||
|
# Filenames will be appended with a timestamp right before the suffix
|
||||||
|
# while for directories, <directory>/backtest-result-<datetime>.json will be used as filename
|
||||||
|
recordfilename: Path = config["exportfilename"]
|
||||||
filename = _generate_filename(recordfilename, dtappendix, ".json")
|
filename = _generate_filename(recordfilename, dtappendix, ".json")
|
||||||
|
|
||||||
# Store metadata separately.
|
# Store metadata separately.
|
||||||
@@ -65,6 +72,21 @@ def store_backtest_stats(
|
|||||||
filename_mc, compression_level=9, compression="lz4"
|
filename_mc, compression_level=9, compression="lz4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
config.get("export", "none") == "signals"
|
||||||
|
and analysis_results is not None
|
||||||
|
and config.get("runmode", RunMode.OTHER) == RunMode.BACKTEST
|
||||||
|
):
|
||||||
|
_store_backtest_analysis_data(
|
||||||
|
recordfilename, analysis_results["signals"], dtappendix, "signals"
|
||||||
|
)
|
||||||
|
_store_backtest_analysis_data(
|
||||||
|
recordfilename, analysis_results["rejected"], dtappendix, "rejected"
|
||||||
|
)
|
||||||
|
_store_backtest_analysis_data(
|
||||||
|
recordfilename, analysis_results["exited"], dtappendix, "exited"
|
||||||
|
)
|
||||||
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
@@ -86,13 +108,3 @@ def _store_backtest_analysis_data(
|
|||||||
file_dump_joblib(filename, data)
|
file_dump_joblib(filename, data)
|
||||||
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def store_backtest_analysis_results(
|
|
||||||
recordfilename: Path,
|
|
||||||
candles: dict[str, dict[str, DataFrame]],
|
|
||||||
dtappendix: str,
|
|
||||||
) -> None:
|
|
||||||
_store_backtest_analysis_data(recordfilename, candles["signals"], dtappendix, "signals")
|
|
||||||
_store_backtest_analysis_data(recordfilename, candles["rejected"], dtappendix, "rejected")
|
|
||||||
_store_backtest_analysis_data(recordfilename, candles["exited"], dtappendix, "exited")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user