]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor(qav3): readd label period optimization
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 20 Feb 2025 09:20:41 +0000 (10:20 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 20 Feb 2025 09:20:41 +0000 (10:20 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
quickadapter/user_data/config-template.json
quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py
quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py
quickadapter/user_data/strategies/QuickAdapterV3.py

index 64dca39e5074619c43571c8b1f38d53e94fdb63e..5c77e1fdfb8280b49850d76db403d175d6e6e0ba 100644 (file)
       "DI_cutoff": 2,
       "&s-minima_threshold": -2,
       "&s-maxima_threshold": 2,
-      // "label_period_candles": 100,
+      "label_period_candles": 100,
       "hp_rmse": -1,
       "period_rmse": -1
     },
index 460e743a3915e43f70a2df8df7ee10c4bef5ee59..34a3acef1ad50e5bff6fd91f6f5779d5f1e85629 100644 (file)
@@ -127,12 +127,12 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
                 y_test = y_test.tail(test_window)
                 test_weights = test_weights[-test_window:]
 
-                # FIXME: find a better way to propagate optuna computed params to strategy
-                if dk.pair not in self.freqai_info["feature_parameters"]:
-                    self.freqai_info["feature_parameters"][dk.pair] = {}
-                self.freqai_info["feature_parameters"][dk.pair][
-                    "label_period_candles"
-                ] = self.__optuna_period_params[dk.pair].get("label_period_candles")
+                # FIXME: find a better way to propagate optuna computed params to strategy
+                if dk.pair not in self.freqai_info["feature_parameters"]:
+                    self.freqai_info["feature_parameters"][dk.pair] = {}
+                self.freqai_info["feature_parameters"][dk.pair][
+                    "label_period_candles"
+                ] = self.__optuna_period_params[dk.pair].get("label_period_candles")
 
         model = LGBMRegressor(
             objective="regression", metric="rmse", **model_training_parameters
@@ -178,13 +178,12 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
             dk.data["extra_returns_per_train"][MINIMA_THRESHOLD_COLUMN] = -2
             dk.data["extra_returns_per_train"][MAXIMA_THRESHOLD_COLUMN] = 2
         else:
-            # if self.__optuna_hyperopt:
-            #     label_period_candles = self.__optuna_period_params.get(pair, {}).get(
-            #         "label_period_candles", self.ft_params["label_period_candles"]
-            #     )
-            # else:
-            #     label_period_candles = self.ft_params["label_period_candles"]
-            label_period_candles = self.ft_params["label_period_candles"]
+            if self.__optuna_hyperopt:
+                label_period_candles = self.__optuna_period_params.get(pair, {}).get(
+                    "label_period_candles", self.ft_params["label_period_candles"]
+                )
+            else:
+                label_period_candles = self.ft_params["label_period_candles"]
             min_pred, max_pred = self.min_max_pred(
                 pred_df_full,
                 num_candles,
@@ -223,11 +222,11 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
         dk.data["extra_returns_per_train"]["DI_value_param3"] = f[2]
         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"]
-            )
-        )
+        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"]
+            )
+        )
         dk.data["extra_returns_per_train"]["hp_rmse"] = self.__optuna_hp_rmse.get(
             pair, -1
         )
@@ -400,6 +399,7 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
                     y_test,
                     test_weights,
                     self.data_split_parameters.get("test_size", TEST_SIZE),
+                    self.freqai_info.get("fit_live_predictions_candles", 100),
                     self.__optuna_config.get("candles_step", 100),
                     model_training_parameters,
                 ),
@@ -529,6 +529,7 @@ def period_objective(
     y_test,
     test_weights,
     test_size,
+    fit_live_predictions_candles,
     candles_step,
     model_training_parameters,
 ) -> float:
@@ -571,6 +572,16 @@ 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)
+    label_period_candles = trial.suggest_int(
+        "label_period_candles",
+        min_label_period_candles,
+        max_label_period_candles,
+    )
+    y_test = y_test.tail(label_period_candles)
+    y_pred = y_pred[-label_period_candles:]
+
     error = sklearn.metrics.root_mean_squared_error(y_test, y_pred)
 
     return error
index 75e77d92c818c9e250a8b0b7c28410f65f46c3fd..b22cbe17eaf0b27f261a241a7abc1702a17aaeda 100644 (file)
@@ -127,12 +127,12 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
                 y_test = y_test.tail(test_window)
                 test_weights = test_weights[-test_window:]
 
-                # FIXME: find a better way to propagate optuna computed params to strategy
-                if dk.pair not in self.freqai_info["feature_parameters"]:
-                    self.freqai_info["feature_parameters"][dk.pair] = {}
-                self.freqai_info["feature_parameters"][dk.pair][
-                    "label_period_candles"
-                ] = self.__optuna_period_params[dk.pair].get("label_period_candles")
+                # FIXME: find a better way to propagate optuna computed params to strategy
+                if dk.pair not in self.freqai_info["feature_parameters"]:
+                    self.freqai_info["feature_parameters"][dk.pair] = {}
+                self.freqai_info["feature_parameters"][dk.pair][
+                    "label_period_candles"
+                ] = self.__optuna_period_params[dk.pair].get("label_period_candles")
 
         model = XGBRegressor(
             objective="reg:squarederror",
@@ -179,13 +179,12 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
             dk.data["extra_returns_per_train"][MINIMA_THRESHOLD_COLUMN] = -2
             dk.data["extra_returns_per_train"][MAXIMA_THRESHOLD_COLUMN] = 2
         else:
-            # if self.__optuna_hyperopt:
-            #     label_period_candles = self.__optuna_period_params.get(pair, {}).get(
-            #         "label_period_candles", self.ft_params["label_period_candles"]
-            #     )
-            # else:
-            #     label_period_candles = self.ft_params["label_period_candles"]
-            label_period_candles = self.ft_params["label_period_candles"]
+            if self.__optuna_hyperopt:
+                label_period_candles = self.__optuna_period_params.get(pair, {}).get(
+                    "label_period_candles", self.ft_params["label_period_candles"]
+                )
+            else:
+                label_period_candles = self.ft_params["label_period_candles"]
             min_pred, max_pred = self.min_max_pred(
                 pred_df_full,
                 num_candles,
@@ -224,11 +223,11 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
         dk.data["extra_returns_per_train"]["DI_value_param3"] = f[2]
         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"]
-            )
-        )
+        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"]
+            )
+        )
         dk.data["extra_returns_per_train"]["hp_rmse"] = self.__optuna_hp_rmse.get(
             pair, -1
         )
@@ -401,6 +400,7 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
                     y_test,
                     test_weights,
                     self.data_split_parameters.get("test_size", TEST_SIZE),
+                    self.freqai_info.get("fit_live_predictions_candles", 100),
                     self.__optuna_config.get("candles_step", 100),
                     model_training_parameters,
                 ),
@@ -530,6 +530,7 @@ def period_objective(
     y_test,
     test_weights,
     test_size,
+    fit_live_predictions_candles,
     candles_step,
     model_training_parameters,
 ) -> float:
@@ -575,6 +576,16 @@ 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)
+    label_period_candles = trial.suggest_int(
+        "label_period_candles",
+        min_label_period_candles,
+        max_label_period_candles,
+    )
+    y_test = y_test.tail(label_period_candles)
+    y_pred = y_pred[-label_period_candles:]
+
     error = sklearn.metrics.root_mean_squared_error(y_test, y_pred)
 
     return error
index 13cb7e6d0db6c165ce98fb288fdc92726495a4fa..0159c7b38dd73ba78d416446f6808bdf488f30aa 100644 (file)
@@ -240,16 +240,14 @@ class QuickAdapterV3(IStrategy):
 
     def set_freqai_targets(self, dataframe, metadata, **kwargs):
         pair = str(metadata.get("pair"))
-        # label_period_candles = (
-        #     self.freqai_info["feature_parameters"]
-        #     .get(pair, {})
-        #     .get(
-        #         "label_period_candles",
-        #         self.freqai_info["feature_parameters"]["label_period_candles"],
-        #     )
-        # )
-        label_period_candles = self.freqai_info["feature_parameters"]["label_period_candles"]
-        dataframe[EXTREMA_COLUMN] = 0
+        label_period_candles = (
+            self.freqai_info["feature_parameters"]
+            .get(pair, {})
+            .get(
+                "label_period_candles",
+                self.freqai_info["feature_parameters"]["label_period_candles"],
+            )
+        )
         min_peaks, _ = find_peaks(
             -dataframe["low"].values,
             distance=label_period_candles,
@@ -258,6 +256,7 @@ class QuickAdapterV3(IStrategy):
             dataframe["high"].values,
             distance=label_period_candles,
         )
+        dataframe[EXTREMA_COLUMN] = 0
         for mp in min_peaks:
             dataframe.at[mp, EXTREMA_COLUMN] = -1
         for mp in max_peaks: