From 963f7a17ae69667e8149891e827ea43706551468 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 25 Feb 2025 00:48:05 +0100 Subject: [PATCH] perf(qav3): fine tune labelling window optimisation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../LightGBMRegressorQuickAdapterV35.py | 22 +++++++-------- .../XGBoostRegressorQuickAdapterV35.py | 22 +++++++-------- .../user_data/strategies/QuickAdapterV3.py | 28 +++++++++++++------ 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py b/quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py index f30ae26..86725c9 100644 --- a/quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py +++ b/quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py @@ -71,9 +71,9 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel): ) self.freqai_info["feature_parameters"][pair] = {} self.freqai_info["feature_parameters"][pair]["label_period_candles"] = ( - self.__optuna_period_params[pair].get( - "label_period_candles", self.ft_params["label_period_candles"] - ) + self.__optuna_period_params[ + pair + ].get("label_period_candles", self.ft_params["label_period_candles"]) ) def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: @@ -230,9 +230,9 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel): dk.data["extra_returns_per_train"]["DI_cutoff"] = cutoff dk.data["extra_returns_per_train"]["label_period_candles"] = ( - self.__optuna_period_params.get(pair, {}).get( - "label_period_candles", self.ft_params["label_period_candles"] - ) + self.__optuna_period_params.get( + pair, {} + ).get("label_period_candles", self.ft_params["label_period_candles"]) ) dk.data["extra_returns_per_train"]["hp_rmse"] = self.__optuna_hp_rmse.get( pair, -1 @@ -494,7 +494,7 @@ def log_sum_exp_min_max_pred( pred_df: pd.DataFrame, fit_live_predictions_candles: int, label_period_candles: int ) -> tuple[float, float]: label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) extrema = pred_df.tail(label_period_candles * label_period_frequency)[ EXTREMA_COLUMN @@ -516,7 +516,7 @@ def mean_min_max_pred( ) label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) min_pred = pred_df_sorted.iloc[-label_period_frequency:].mean() max_pred = pred_df_sorted.iloc[:label_period_frequency].mean() @@ -533,7 +533,7 @@ def median_min_max_pred( ) label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) min_pred = pred_df_sorted.iloc[-label_period_frequency:].median() max_pred = pred_df_sorted.iloc[:label_period_frequency].median() @@ -592,8 +592,8 @@ def period_objective( ) y_pred = model.predict(X_test) - min_label_period_candles = int(fit_live_predictions_candles / 6) - max_label_period_candles = int(fit_live_predictions_candles / 2) + min_label_period_candles = int(fit_live_predictions_candles / 20) + max_label_period_candles = int(fit_live_predictions_candles / 4) label_period_candles = trial.suggest_int( "label_period_candles", min_label_period_candles, diff --git a/quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py b/quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py index 052095c..4654646 100644 --- a/quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py +++ b/quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py @@ -71,9 +71,9 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel): ) self.freqai_info["feature_parameters"][pair] = {} self.freqai_info["feature_parameters"][pair]["label_period_candles"] = ( - self.__optuna_period_params[pair].get( - "label_period_candles", self.ft_params["label_period_candles"] - ) + self.__optuna_period_params[ + pair + ].get("label_period_candles", self.ft_params["label_period_candles"]) ) def fit(self, data_dictionary: Dict, dk: FreqaiDataKitchen, **kwargs) -> Any: @@ -231,9 +231,9 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel): dk.data["extra_returns_per_train"]["DI_cutoff"] = cutoff dk.data["extra_returns_per_train"]["label_period_candles"] = ( - self.__optuna_period_params.get(pair, {}).get( - "label_period_candles", self.ft_params["label_period_candles"] - ) + self.__optuna_period_params.get( + pair, {} + ).get("label_period_candles", self.ft_params["label_period_candles"]) ) dk.data["extra_returns_per_train"]["hp_rmse"] = self.__optuna_hp_rmse.get( pair, -1 @@ -495,7 +495,7 @@ def log_sum_exp_min_max_pred( pred_df: pd.DataFrame, fit_live_predictions_candles: int, label_period_candles: int ) -> tuple[float, float]: label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) extrema = pred_df.tail(label_period_candles * label_period_frequency)[ EXTREMA_COLUMN @@ -517,7 +517,7 @@ def mean_min_max_pred( ) label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) min_pred = pred_df_sorted.iloc[-label_period_frequency:].mean() max_pred = pred_df_sorted.iloc[:label_period_frequency].mean() @@ -534,7 +534,7 @@ def median_min_max_pred( ) label_period_frequency: int = int( - fit_live_predictions_candles / label_period_candles + fit_live_predictions_candles / (label_period_candles * 2) ) min_pred = pred_df_sorted.iloc[-label_period_frequency:].median() max_pred = pred_df_sorted.iloc[:label_period_frequency].median() @@ -596,8 +596,8 @@ def period_objective( ) y_pred = model.predict(X_test) - min_label_period_candles = int(fit_live_predictions_candles / 6) - max_label_period_candles = int(fit_live_predictions_candles / 2) + min_label_period_candles = int(fit_live_predictions_candles / 20) + max_label_period_candles = int(fit_live_predictions_candles / 4) label_period_candles = trial.suggest_int( "label_period_candles", min_label_period_candles, diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 89b309a..9b36469 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -10,7 +10,7 @@ from freqtrade.strategy.interface import IStrategy from technical.pivots_points import pivots_points from freqtrade.exchange import timeframe_to_prev_date from freqtrade.persistence import Trade -from scipy.signal import find_peaks +from scipy.signal import argrelmin, argrelmax import numpy as np import pandas_ta as pta @@ -248,19 +248,31 @@ class QuickAdapterV3(IStrategy): self.freqai_info["feature_parameters"]["label_period_candles"], ) ) - min_peaks, _ = find_peaks( - -dataframe["low"].values, - distance=label_period_candles, + min_peaks = argrelmin( + dataframe["low"].values, + order=label_period_candles, ) - max_peaks, _ = find_peaks( + max_peaks = argrelmax( dataframe["high"].values, - distance=label_period_candles, + order=label_period_candles, ) + # min_peaks, _ = find_peaks( + # -dataframe["low"].values, + # distance=label_period_candles, + # ) + # max_peaks, _ = find_peaks( + # dataframe["high"].values, + # distance=label_period_candles, + # ) dataframe[EXTREMA_COLUMN] = 0 - for mp in min_peaks: + for mp in min_peaks[0]: dataframe.at[mp, EXTREMA_COLUMN] = -1 - for mp in max_peaks: + for mp in max_peaks[0]: dataframe.at[mp, EXTREMA_COLUMN] = 1 + # for mp in min_peaks: + # dataframe.at[mp, EXTREMA_COLUMN] = -1 + # for mp in max_peaks: + # dataframe.at[mp, EXTREMA_COLUMN] = 1 dataframe["minima"] = np.where(dataframe[EXTREMA_COLUMN] == -1, -1, 0) dataframe["maxima"] = np.where(dataframe[EXTREMA_COLUMN] == 1, 1, 0) dataframe[EXTREMA_COLUMN] = ( -- 2.43.0