From c8a5904959aeac7b6351ac593422923b358bd033 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 16 Apr 2024 19:27:29 +0200 Subject: [PATCH] Store and load backtest-market-change data --- freqtrade/data/btanalysis.py | 10 ++++++++++ freqtrade/optimize/backtesting.py | 4 ++++ .../optimize/optimize_reports/bt_storage.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index ef92d4db6..07417b27f 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -238,6 +238,16 @@ def update_backtest_metadata(filename: Path, strategy: str, content: Dict[str, A file_dump_json(get_backtest_metadata_filename(filename), metadata) +def get_backtest_market_change(filename: Path, include_ts: bool = True) -> pd.DataFrame: + """ + Read backtest market change file. + """ + df = pd.read_feather(filename) + if include_ts: + df.loc[:, '__date_ts'] = df.loc[:, 'date'].astype(np.int64) // 1000 // 1000 + return df + + def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, str], min_backtest_date: Optional[datetime] = None) -> Dict[str, Any]: """ diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index ee52a5af3..88c0d1cd3 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -19,6 +19,7 @@ from freqtrade.data import history from freqtrade.data.btanalysis import find_existing_backtest_stats, trade_list_to_dataframe from freqtrade.data.converter import trim_dataframe, trim_dataframes from freqtrade.data.dataprovider import DataProvider +from freqtrade.data.metrics import combined_dataframes_with_rel_mean from freqtrade.enums import (BacktestState, CandleType, ExitCheckTuple, ExitType, RunMode, TradingMode) from freqtrade.exceptions import DependencyException, OperationalException @@ -33,6 +34,7 @@ from freqtrade.optimize.optimize_reports import (generate_backtest_stats, genera show_backtest_results, store_backtest_analysis_results, store_backtest_stats) +from freqtrade.optimize.optimize_reports.bt_storage import store_backtest_market_change from freqtrade.persistence import (CustomDataWrapper, LocalTrade, Order, PairLocks, Trade, disable_database_use, enable_database_use) from freqtrade.plugins.pairlistmanager import PairListManager @@ -1422,6 +1424,8 @@ class Backtesting: dt_appendix = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") if self.config.get('export', 'none') in ('trades', 'signals'): store_backtest_stats(self.config['exportfilename'], self.results, dt_appendix) + combined_res = combined_dataframes_with_rel_mean(data, min_date, max_date) + store_backtest_market_change(self.config['exportfilename'], combined_res, dt_appendix) if (self.config.get('export', 'none') == 'signals' and self.dataprovider.runmode == RunMode.BACKTEST): diff --git a/freqtrade/optimize/optimize_reports/bt_storage.py b/freqtrade/optimize/optimize_reports/bt_storage.py index 47568cffd..61179a6e6 100644 --- a/freqtrade/optimize/optimize_reports/bt_storage.py +++ b/freqtrade/optimize/optimize_reports/bt_storage.py @@ -2,6 +2,8 @@ import logging from pathlib import Path from typing import Dict +from pandas import DataFrame + from freqtrade.constants import LAST_BT_RESULT_FN from freqtrade.misc import file_dump_joblib, file_dump_json from freqtrade.optimize.backtest_caching import get_backtest_metadata_filename @@ -81,3 +83,20 @@ def store_backtest_analysis_results( dtappendix: str) -> None: _store_backtest_analysis_data(recordfilename, candles, dtappendix, "signals") _store_backtest_analysis_data(recordfilename, trades, dtappendix, "rejected") + + +def store_backtest_market_change( + recordfilename: Path, data: DataFrame, dtappendix: str) -> Path: + """ + Stores backtest market change average + :param recordfilename: 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, /backtest-result-_.pkl will be used + as filename + :param candles: Dict containing the backtesting data for analysis + :param dtappendix: Datetime to use for the filename + """ + filename = _generate_filename(recordfilename, f"{dtappendix}_market_change", '.feather') + data.reset_index().to_feather(filename, compression_level=9, compression='lz4') + + return filename