]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
fix(qav3): handle assets with close to zero at pivot labeling
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 18 May 2025 23:09:51 +0000 (01:09 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 18 May 2025 23:09:51 +0000 (01:09 +0200)
use a log space for prices

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 499130173b5705ea7a8e7a3735278c73555cc33e..dd79c6b0dade773b211e1ae95c1263dd85743e6e 100644 (file)
@@ -45,7 +45,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     https://github.com/sponsors/robcaulk
     """
 
-    version = "3.7.40"
+    version = "3.7.41"
 
     @cached_property
     def _optuna_config(self) -> dict:
@@ -932,8 +932,8 @@ def zigzag(
     def calculate_min_slope_strength(
         pos: int,
         lookback_period: int = 20,
-        min_value: float = 0.3,
-        max_value: float = 0.7,
+        min_value: float = 0.03,
+        max_value: float = 0.07,
     ) -> float:
         start = max(0, pos - lookback_period)
         end = min(pos + 1, n)
@@ -980,7 +980,7 @@ def zigzag(
         next_confirmation_pos: int,
         direction: TrendDirection,
         extrema_threshold: float = 0.85,
-        min_slope_volatility: float = 0.00075,
+        min_slope_volatility: float = 0.0095,
         move_away_ratio: float = 0.25,
     ) -> bool:
         next_start = next_confirmation_pos + 1
@@ -1024,13 +1024,14 @@ def zigzag(
             return False
 
         slope_ok = False
-        next_closes_std = np.std(next_closes)
-        if len(next_closes) >= 2 and next_closes_std > min_slope_volatility:
-            weights = np.linspace(0.5, 1.5, len(next_closes))
-            next_slope = np.polyfit(range(len(next_closes)), next_closes, 1, w=weights)[
-                0
-            ]
-            next_slope_strength = next_slope / next_closes_std
+        log_next_closes = np.log(next_closes)
+        log_next_closes_std = np.std(log_next_closes)
+        if len(next_closes) >= 2 and log_next_closes_std > min_slope_volatility:
+            weights = np.linspace(0.5, 1.5, len(log_next_closes))
+            log_next_slope = np.polyfit(
+                range(len(log_next_closes)), log_next_closes, 1, w=weights
+            )[0]
+            next_slope_strength = log_next_slope / log_next_closes_std
             min_slope_strength = calculate_min_slope_strength(candidate_pivot_pos)
             if direction == TrendDirection.DOWN:
                 slope_ok = next_slope_strength < -min_slope_strength
@@ -1042,16 +1043,16 @@ def zigzag(
         significant_move_away_ok = False
         if direction == TrendDirection.DOWN:
             if np.any(
-                next_lows
-                < highs[candidate_pivot_pos]
-                (1 - thresholds[candidate_pivot_pos] * move_away_ratio)
+                np.log(next_lows)
+                < np.log(highs[candidate_pivot_pos])
+                + np.log(1 - thresholds[candidate_pivot_pos] * move_away_ratio)
             ):
                 significant_move_away_ok = True
         elif direction == TrendDirection.UP:
             if np.any(
-                next_highs
-                > lows[candidate_pivot_pos]
-                (1 + thresholds[candidate_pivot_pos] * move_away_ratio)
+                np.log(next_highs)
+                > np.log(lows[candidate_pivot_pos])
+                + np.log(1 + thresholds[candidate_pivot_pos] * move_away_ratio)
             ):
                 significant_move_away_ok = True
         return significant_move_away_ok
index ffbcc94fb0b44b4c997b1652c69606325dcaba6a..2387ea7305f53724ccaa49f712535749fcddb756 100644 (file)
@@ -58,7 +58,7 @@ class QuickAdapterV3(IStrategy):
     INTERFACE_VERSION = 3
 
     def version(self) -> str:
-        return "3.3.37"
+        return "3.3.38"
 
     timeframe = "5m"
 
index b01947ff764a857c6100861c6d67ec8ba1aa22ec..3e0d417937a8be7fd4bf5ba83ffefb463e70da67 100644 (file)
@@ -429,8 +429,8 @@ def zigzag(
     def calculate_min_slope_strength(
         pos: int,
         lookback_period: int = 20,
-        min_value: float = 0.3,
-        max_value: float = 0.7,
+        min_value: float = 0.03,
+        max_value: float = 0.07,
     ) -> float:
         start = max(0, pos - lookback_period)
         end = min(pos + 1, n)
@@ -477,7 +477,7 @@ def zigzag(
         next_confirmation_pos: int,
         direction: TrendDirection,
         extrema_threshold: float = 0.85,
-        min_slope_volatility: float = 0.00075,
+        min_slope_volatility: float = 0.0095,
         move_away_ratio: float = 0.25,
     ) -> bool:
         next_start = next_confirmation_pos + 1
@@ -521,13 +521,14 @@ def zigzag(
             return False
 
         slope_ok = False
-        next_closes_std = np.std(next_closes)
-        if len(next_closes) >= 2 and next_closes_std > min_slope_volatility:
-            weights = np.linspace(0.5, 1.5, len(next_closes))
-            next_slope = np.polyfit(range(len(next_closes)), next_closes, 1, w=weights)[
-                0
-            ]
-            next_slope_strength = next_slope / next_closes_std
+        log_next_closes = np.log(next_closes)
+        log_next_closes_std = np.std(log_next_closes)
+        if len(next_closes) >= 2 and log_next_closes_std > min_slope_volatility:
+            weights = np.linspace(0.5, 1.5, len(log_next_closes))
+            log_next_slope = np.polyfit(
+                range(len(log_next_closes)), log_next_closes, 1, w=weights
+            )[0]
+            next_slope_strength = log_next_slope / log_next_closes_std
             min_slope_strength = calculate_min_slope_strength(candidate_pivot_pos)
             if direction == TrendDirection.DOWN:
                 slope_ok = next_slope_strength < -min_slope_strength
@@ -539,16 +540,16 @@ def zigzag(
         significant_move_away_ok = False
         if direction == TrendDirection.DOWN:
             if np.any(
-                next_lows
-                < highs[candidate_pivot_pos]
-                (1 - thresholds[candidate_pivot_pos] * move_away_ratio)
+                np.log(next_lows)
+                < np.log(highs[candidate_pivot_pos])
+                + np.log(1 - thresholds[candidate_pivot_pos] * move_away_ratio)
             ):
                 significant_move_away_ok = True
         elif direction == TrendDirection.UP:
             if np.any(
-                next_highs
-                > lows[candidate_pivot_pos]
-                (1 + thresholds[candidate_pivot_pos] * move_away_ratio)
+                np.log(next_highs)
+                > np.log(lows[candidate_pivot_pos])
+                + np.log(1 + thresholds[candidate_pivot_pos] * move_away_ratio)
             ):
                 significant_move_away_ok = True
         return significant_move_away_ok