]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor(qav3): use scipy for zero phase gaussian smoothing
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 28 May 2025 20:37:12 +0000 (22:37 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 28 May 2025 20:37:12 +0000 (22:37 +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 e7afb108be230ddb958150a78a5d1f03d1a783b9..7cdde0889f4d89ac8d4da5ab1167b07ee12d4497 100644 (file)
@@ -712,7 +712,7 @@ class QuickAdapterV3(IStrategy):
                 center=True,
             ).mean(std=std),
             "zero_phase_gaussian": zero_phase_gaussian(
-                series=series, window=gaussian_window, std=std
+                series=series, window=window, std=std
             ),
             "boxcar": series.rolling(
                 window=odd_window, win_type="boxcar", center=True
index b7a6f7f29a46f26e6da3721b440af3adba3d5e78..70b163c1f15b6061b08572b705fe82f0f0d226d1 100644 (file)
@@ -1,10 +1,9 @@
 from enum import IntEnum
 import numpy as np
 import pandas as pd
+import scipy as sp
 import talib.abstract as ta
 from typing import Callable, Union
-from scipy.signal import convolve
-from scipy.signal.windows import gaussian
 from technical import qtpylib
 
 
@@ -44,18 +43,16 @@ def derive_gaussian_std_from_window(window: int) -> float:
 
 
 def zero_phase_gaussian(series: pd.Series, window: int, std: float) -> pd.Series:
-    kernel = gaussian(window, std=std)
-    kernel /= kernel.sum()
-
-    padding_length = window - 1
-    padded_series_values = np.pad(
-        series.values, (padding_length, padding_length), mode="edge"
-    )
-
-    forward = convolve(padded_series_values, kernel, mode="valid")
-    backward = convolve(forward[::-1], kernel, mode="valid")[::-1]
-
-    return pd.Series(backward, index=series.index)
+    if len(series) == 0:
+        return series
+    if len(series) < window:
+        raise ValueError("Series length must be greater than or equal to window size")
+    series_values = series.to_numpy()
+    gaussian_coeffs = sp.signal.windows.gaussian(M=window, std=std, sym=True)
+    b = gaussian_coeffs / np.sum(gaussian_coeffs)
+    a = 1.0
+    filtered_values = sp.signal.filtfilt(b, a, series_values)
+    return pd.Series(filtered_values, index=series.index)
 
 
 def top_change_percent(dataframe: pd.DataFrame, period: int) -> pd.Series: