]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor(qav3): use builtin method to propagate label_period_candles
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 13 Mar 2025 11:19:45 +0000 (12:19 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 13 Mar 2025 11:19:45 +0000 (12:19 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
quickadapter/user_data/freqaimodels/LightGBMRegressorQuickAdapterV35.py
quickadapter/user_data/freqaimodels/XGBoostRegressorQuickAdapterV35.py
quickadapter/user_data/strategies/QuickAdapterV3.py

index 65d2f25a2928f97c32165279b491c1ef8f20484c..35f40b6114552d76cb8c85e2bff6c644d363996c 100644 (file)
@@ -68,12 +68,6 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
             self.__optuna_period_params[pair] = (
                 self.optuna_load_best_params(pair, "period") or {}
             )
-            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"]
-                )
-            )
 
     def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
         """
@@ -140,11 +134,6 @@ class LightGBMRegressorQuickAdapterV35(BaseRegressionModel):
                 y_test = y_test.iloc[-test_window:]
                 test_weights = test_weights[-test_window:]
 
-                # FIXME: find a better way to propagate optuna computed params to strategy
-                self.freqai_info["feature_parameters"][dk.pair][
-                    "label_period_candles"
-                ] = self.__optuna_period_params[dk.pair].get("label_period_candles")
-
         model = LGBMRegressor(objective="regression", **model_training_parameters)
 
         eval_set, eval_weights = self.eval_set_and_weights(X_test, y_test, test_weights)
index eeaecbad4367aff2bb95f0909d51311f97bea2df..29a5efa4cbeb8ed00837401a5f073e047f3df719 100644 (file)
@@ -68,12 +68,6 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
             self.__optuna_period_params[pair] = (
                 self.optuna_load_best_params(pair, "period") or {}
             )
-            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"]
-                )
-            )
 
     def fit(self, data_dictionary: dict, dk: FreqaiDataKitchen, **kwargs) -> Any:
         """
@@ -140,11 +134,6 @@ class XGBoostRegressorQuickAdapterV35(BaseRegressionModel):
                 y_test = y_test.iloc[-test_window:]
                 test_weights = test_weights[-test_window:]
 
-                # FIXME: find a better way to propagate optuna computed params to strategy
-                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",
             eval_metric="rmse",
index 7c4cb54eb26c88860327fe43ffdf064b2a66f8eb..07cecb1701ce2e9c1e96a18f3245984f9aa77904 100644 (file)
@@ -1,6 +1,8 @@
+import json
 import logging
 from functools import reduce
 import datetime
+from pathlib import Path
 import talib.abstract as ta
 from pandas import DataFrame, Series
 from technical import qtpylib
@@ -122,6 +124,25 @@ class QuickAdapterV3(IStrategy):
     def startup_candle_count(self):
         return int(self.freqai_info.get("fit_live_predictions_candles", 100) / 2)
 
+    def __init__(self, config: dict) -> None:
+        super().__init__(config)
+        self.pairs = self.config.get("exchange", {}).get("pair_whitelist")
+        if not self.pairs:
+            raise ValueError(
+                "FreqAI strategy requires StaticPairList method defined in pairlists configuration and pair_whitelist defined in exchange section configuration"
+            )
+        self.models_full_path = Path(
+            self.config["user_data_dir"]
+            / "models"
+            / f"{self.config.get('freqai', {}).get('identifier', 'no_id_provided')}"
+        )
+        self.__period_params: dict[str, dict] = {}
+        for pair in self.pairs:
+            self.__period_params[pair] = self.load_period_best_params(pair) or {}
+            logger.info(
+                f"Loaded period best params for {pair}: {self.__period_params[pair]}"
+            )
+
     def feature_engineering_expand_all(self, dataframe, period, **kwargs):
         dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
         dataframe["%-aroonosc-period"] = ta.AROONOSC(dataframe, timeperiod=period)
@@ -249,13 +270,12 @@ 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.__period_params.get(pair, {}).get(
+            "label_period_candles",
+            self.freqai_info["feature_parameters"]["label_period_candles"],
+        )
+        logger.info(
+            f"label_period_candles: {label_period_candles} for {pair}"
         )
         min_peaks = argrelmin(
             dataframe["low"].values,
@@ -284,6 +304,17 @@ class QuickAdapterV3(IStrategy):
             1,
         )
 
+        # pair = str(metadata.get("pair"))
+        # self.__period_params[pair]["label_period_candles"] = dataframe[
+        #     "label_period_candles"
+        # ]
+        # logger.info(
+        #     f"label_period_candles: {self.__period_params[pair]['label_period_candles']}"
+        # )
+        # logger.info(
+        #     f"label_period_candles extra returns: {dataframe['label_period_candles']}"
+        # )
+
         dataframe["minima_threshold"] = dataframe[MINIMA_THRESHOLD_COLUMN]
         dataframe["maxima_threshold"] = dataframe[MAXIMA_THRESHOLD_COLUMN]
 
@@ -439,6 +470,17 @@ class QuickAdapterV3(IStrategy):
             ),
         )
 
+    def load_period_best_params(self, pair: str) -> dict | None:
+        namespace = "period"
+        best_params_path = Path(
+            self.models_full_path
+            / f"optuna-{namespace}-best-params-{pair.split('/')[0]}.json"
+        )
+        if best_params_path.is_file():
+            with best_params_path.open("r", encoding="utf-8") as read_file:
+                return json.load(read_file)
+        return None
+
 
 def top_change_percent(dataframe: DataFrame, period: int) -> Series:
     """