]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor(qav3): move extrema smoothing code to utils
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 6 Aug 2025 20:04:01 +0000 (22:04 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 6 Aug 2025 20:04:01 +0000 (22:04 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 7a6f472c230077e0aefb87cdeaa0c8b99c7dc94f..913033815341f94dd7171cbff5ad317a63faf343 100644 (file)
@@ -24,14 +24,12 @@ from Utils import (
     calculate_quantile,
     ewo,
     get_distance,
-    get_gaussian_std,
-    get_odd_window,
     get_zl_ma_fn,
     non_zero_diff,
     price_retracement_percent,
+    smooth_extrema,
     top_change_percent,
     vwapb,
-    zero_phase,
     zigzag,
     zlema,
 )
@@ -479,9 +477,11 @@ class QuickAdapterV3(IStrategy):
             logger.info(
                 f"{pair}: labeled {len(pivots_indices)} extrema (label_period={QuickAdapterV3.td_format(label_period)} / {label_period_candles=} / {label_natr_ratio=:.2f})"
             )
-        dataframe[EXTREMA_COLUMN] = self.smooth_extrema(
+        dataframe[EXTREMA_COLUMN] = smooth_extrema(
             dataframe[EXTREMA_COLUMN],
-            self.freqai_info.get("extrema_smoothing_window", 5),
+            str(self.freqai_info.get("extrema_smoothing", "gaussian")),
+            int(self.freqai_info.get("extrema_smoothing_window", 5)),
+            float(self.freqai_info.get("extrema_smoothing_beta", 8.0)),
         )
         if debug:
             extrema = dataframe[EXTREMA_COLUMN]
@@ -1179,51 +1179,6 @@ class QuickAdapterV3(IStrategy):
         else:
             raise ValueError(f"Invalid trading_mode: {trading_mode}")
 
-    def smooth_extrema(
-        self,
-        series: Series,
-        window: int,
-    ) -> Series:
-        extrema_smoothing = str(self.freqai_info.get("extrema_smoothing", "gaussian"))
-        std = get_gaussian_std(window)
-        extrema_smoothing_beta = float(
-            self.freqai_info.get("extrema_smoothing_beta", 8.0)
-        )
-        if debug:
-            logger.info(
-                f"{extrema_smoothing=}, {window=}, {std=}, {extrema_smoothing_beta=}"
-            )
-        odd_window = get_odd_window(window)
-        smoothing_methods: dict[str, Series] = {
-            "gaussian": zero_phase(
-                series=series,
-                window=window,
-                win_type="gaussian",
-                std=std,
-                beta=extrema_smoothing_beta,
-            ),
-            "kaiser": zero_phase(
-                series=series,
-                window=window,
-                win_type="kaiser",
-                std=std,
-                beta=extrema_smoothing_beta,
-            ),
-            "triang": zero_phase(
-                series=series,
-                window=window,
-                win_type="triang",
-                std=std,
-                beta=extrema_smoothing_beta,
-            ),
-            "smm": series.rolling(window=odd_window, center=True).median(),
-            "sma": series.rolling(window=odd_window, center=True).mean(),
-        }
-        return smoothing_methods.get(
-            extrema_smoothing,
-            smoothing_methods["gaussian"],
-        )
-
     def optuna_load_best_params(
         self, pair: str, namespace: str
     ) -> Optional[dict[str, Any]]:
index 6b8d5f4d5e7ca9c00327598abbf6fd70946c28fe..88d000e59cdfad033f6f03d012345bc4115f8d7c 100644 (file)
@@ -76,6 +76,42 @@ def zero_phase(
     return pd.Series(filtered_values, index=series.index)
 
 
+def smooth_extrema(
+    series: pd.Series, method: str, window: int, beta: float
+) -> pd.Series:
+    std = get_gaussian_std(window)
+    odd_window = get_odd_window(window)
+    smoothing_methods: dict[str, pd.Series] = {
+        "gaussian": zero_phase(
+            series=series,
+            window=window,
+            win_type="gaussian",
+            std=std,
+            beta=beta,
+        ),
+        "kaiser": zero_phase(
+            series=series,
+            window=window,
+            win_type="kaiser",
+            std=std,
+            beta=beta,
+        ),
+        "triang": zero_phase(
+            series=series,
+            window=window,
+            win_type="triang",
+            std=std,
+            beta=beta,
+        ),
+        "smm": series.rolling(window=odd_window, center=True).median(),
+        "sma": series.rolling(window=odd_window, center=True).mean(),
+    }
+    return smoothing_methods.get(
+        method,
+        smoothing_methods["gaussian"],
+    )
+
+
 @lru_cache(maxsize=128)
 def calculate_min_extrema(
     size: int, fit_live_predictions_candles: int, min_extrema: int = 4