]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
perf(qav3): fine tune pivots labeling confirmation
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 15 Jun 2025 21:53:18 +0000 (23:53 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 15 Jun 2025 21:53:18 +0000 (23:53 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index b29d39e1c05067db6f645d68e93eba9bc38684dc..fca8a2749987fa64b7dee0ec6407923187478869 100644 (file)
@@ -14,7 +14,7 @@ import sklearn
 import warnings
 import talib.abstract as ta
 
-from functools import cached_property
+from functools import cached_property, lru_cache
 from typing import Any, Callable, Optional
 from pathlib import Path
 from freqtrade.freqai.base_models.BaseRegressionModel import BaseRegressionModel
@@ -50,7 +50,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     https://github.com/sponsors/robcaulk
     """
 
-    version = "3.7.90"
+    version = "3.7.91"
 
     @cached_property
     def _optuna_config(self) -> dict:
@@ -1325,13 +1325,14 @@ def zigzag(
             max_window,
         ).astype(int)
 
+    @lru_cache(maxsize=8)
+    def calculate_slopes_ok_min_max(slopes_ok_threshold: float) -> tuple[int, int]:
+        raw_bound1 = math.ceil(1 / slopes_ok_threshold)
+        raw_bound2 = math.ceil(1 / (1 - slopes_ok_threshold))
+        return min(raw_bound1, raw_bound2), max(raw_bound1, raw_bound2)
+
     def calculate_min_slopes_ok(pos: int, slopes_ok_threshold: float) -> int:
-        min_slopes_ok = max(
-            math.ceil(1 / slopes_ok_threshold),
-            math.ceil(1 / (1 - slopes_ok_threshold)),
-            4,
-        )
-        max_slopes_ok = math.ceil(min_slopes_ok * 2)
+        min_slopes_ok, max_slopes_ok = calculate_slopes_ok_min_max(slopes_ok_threshold)
         volatility_quantile = calculate_volatility_quantile(pos)
         if np.isnan(volatility_quantile):
             return int(round(median([min_slopes_ok, max_slopes_ok])))
@@ -1422,7 +1423,7 @@ def zigzag(
         direction: TrendDirection,
         enable_weighting: bool = False,
         min_slope: float = np.finfo(float).eps,
-        slopes_ok_threshold: float = 0.75,
+        slopes_ok_threshold: float = 0.65,
     ) -> bool:
         slope_confirmation_window = calculate_slope_confirmation_window(
             candidate_pivot_pos
index ca0cc7970854819667806565460929d752e2782a..c404e4af83c0aa8d2c6cc9038688ea6ba9fcfdeb 100644 (file)
@@ -64,7 +64,7 @@ class QuickAdapterV3(IStrategy):
     INTERFACE_VERSION = 3
 
     def version(self) -> str:
-        return "3.3.94"
+        return "3.3.95"
 
     timeframe = "5m"
 
index ad88660649e0f5803a16a7ac54c245e828e11540..7fbd6ed7d9aeecfb05402aef320459cd2b143651 100644 (file)
@@ -45,7 +45,7 @@ def derive_gaussian_std_from_window(window: int) -> float:
     return (window - 1) / 6.0 if window > 1 else 0.5
 
 
-@lru_cache(maxsize=64)
+@lru_cache(maxsize=8)
 def _calculate_coeffs(
     window: int, win_type: Literal["gaussian", "kaiser"], std: float, beta: float
 ) -> np.ndarray:
@@ -449,13 +449,14 @@ def zigzag(
             max_window,
         ).astype(int)
 
+    @lru_cache(maxsize=8)
+    def calculate_slopes_ok_min_max(slopes_ok_threshold: float) -> tuple[int, int]:
+        raw_bound1 = math.ceil(1 / slopes_ok_threshold)
+        raw_bound2 = math.ceil(1 / (1 - slopes_ok_threshold))
+        return min(raw_bound1, raw_bound2), max(raw_bound1, raw_bound2)
+
     def calculate_min_slopes_ok(pos: int, slopes_ok_threshold: float) -> int:
-        min_slopes_ok = max(
-            math.ceil(1 / slopes_ok_threshold),
-            math.ceil(1 / (1 - slopes_ok_threshold)),
-            4,
-        )
-        max_slopes_ok = math.ceil(min_slopes_ok * 2)
+        min_slopes_ok, max_slopes_ok = calculate_slopes_ok_min_max(slopes_ok_threshold)
         volatility_quantile = calculate_volatility_quantile(pos)
         if np.isnan(volatility_quantile):
             return int(round(median([min_slopes_ok, max_slopes_ok])))
@@ -546,7 +547,7 @@ def zigzag(
         direction: TrendDirection,
         enable_weighting: bool = False,
         min_slope: float = np.finfo(float).eps,
-        slopes_ok_threshold: float = 0.75,
+        slopes_ok_threshold: float = 0.65,
     ) -> bool:
         slope_confirmation_window = calculate_slope_confirmation_window(
             candidate_pivot_pos