]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
fix(qav3): improve numerical stability at TP computation
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 19 May 2025 12:38:08 +0000 (14:38 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 19 May 2025 12:38:08 +0000 (14:38 +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 100f1643d7fbb29888ca0ab57a1ee9858d80dca4..eb3135e03333778ef1201139d0c138c2e52a0b4b 100644 (file)
@@ -915,8 +915,8 @@ def zigzag(
 
     def calculate_depth(
         pos: int,
-        min_depth: int = 5,
-        max_depth: int = 30,
+        min_depth: int = 6,
+        max_depth: int = 36,
     ) -> int:
         if len(pivots_indices) < 2:
             return depth
@@ -974,6 +974,7 @@ def zigzag(
         pivots_directions.append(direction)
         last_pivot_pos = pos
         depth = calculate_depth(pos)
+        reset_candidate_pivot()
 
     def is_reversal_confirmed(
         candidate_pivot_pos: int,
@@ -1128,7 +1129,6 @@ def zigzag(
                 and is_reversal_confirmed(candidate_pivot_pos, i, TrendDirection.DOWN)
             ):
                 add_pivot(candidate_pivot_pos, candidate_pivot_value, TrendDirection.UP)
-                reset_candidate_pivot()
                 state = TrendDirection.DOWN
         elif state == TrendDirection.DOWN:
             if np.isnan(candidate_pivot_value) or current_low < candidate_pivot_value:
@@ -1142,7 +1142,6 @@ def zigzag(
                 add_pivot(
                     candidate_pivot_pos, candidate_pivot_value, TrendDirection.DOWN
                 )
-                reset_candidate_pivot()
                 state = TrendDirection.UP
 
     return pivots_indices, pivots_values, pivots_directions
index 597eef5ede0a81ca30b83bc25e97d3e6f4101d29..e7bfda61482447f6b376b494a24c1aca17a680f0 100644 (file)
@@ -58,7 +58,7 @@ class QuickAdapterV3(IStrategy):
     INTERFACE_VERSION = 3
 
     def version(self) -> str:
-        return "3.3.41"
+        return "3.3.42"
 
     timeframe = "5m"
 
@@ -487,7 +487,7 @@ class QuickAdapterV3(IStrategy):
         self, df: DataFrame, trade: Trade, current_rate: float
     ) -> Optional[float]:
         trade_duration_candles = self.get_trade_duration_candles(df, trade)
-        if QuickAdapterV3.is_trade_duration_valid(trade_duration_candles) is False:
+        if not QuickAdapterV3.is_trade_duration_valid(trade_duration_candles):
             return None
         current_natr = df["natr_label_period_candles"].iloc[-1]
         if isna(current_natr) or current_natr < 0:
@@ -501,7 +501,7 @@ class QuickAdapterV3(IStrategy):
 
     def get_take_profit_distance(self, df: DataFrame, trade: Trade) -> Optional[float]:
         trade_duration_candles = self.get_trade_duration_candles(df, trade)
-        if QuickAdapterV3.is_trade_duration_valid(trade_duration_candles) is False:
+        if not QuickAdapterV3.is_trade_duration_valid(trade_duration_candles):
             return None
         entry_natr = self.get_trade_entry_natr(df, trade)
         if isna(entry_natr) or entry_natr < 0:
@@ -511,28 +511,29 @@ class QuickAdapterV3(IStrategy):
             return None
         entry_natr_weight = 0.5
         current_natr_weight = 0.5
-        natr_pct_change = abs(current_natr - entry_natr) / entry_natr
-        natr_pct_change_thresholds = [
-            (1.0, 0.5),  # (threshold, adjustment)
-            (0.8, 0.4),
-            (0.6, 0.3),
-            (0.4, 0.2),
-            (0.2, 0.1),
-        ]
-        weight_adjustment = 0.0
-        for threshold, adjustment in natr_pct_change_thresholds:
-            if natr_pct_change > threshold:
-                weight_adjustment = adjustment
-                break
-        if weight_adjustment > 0:
-            if current_natr > entry_natr:
-                entry_natr_weight -= weight_adjustment
-                current_natr_weight += weight_adjustment
-            else:
-                entry_natr_weight += weight_adjustment
-                current_natr_weight -= weight_adjustment
-        entry_natr_weight = np.clip(entry_natr_weight, 0.0, 1.0)
-        current_natr_weight = np.clip(current_natr_weight, 0.0, 1.0)
+        if not np.isclose(entry_natr, 0):
+            natr_pct_change = abs(current_natr - entry_natr) / entry_natr
+            natr_pct_change_thresholds = [
+                (1.0, 0.5),  # (threshold, adjustment)
+                (0.8, 0.4),
+                (0.6, 0.3),
+                (0.4, 0.2),
+                (0.2, 0.1),
+            ]
+            weight_adjustment = 0.0
+            for threshold, adjustment in natr_pct_change_thresholds:
+                if natr_pct_change > threshold:
+                    weight_adjustment = adjustment
+                    break
+            if weight_adjustment > 0:
+                if current_natr > entry_natr:
+                    entry_natr_weight -= weight_adjustment
+                    current_natr_weight += weight_adjustment
+                else:
+                    entry_natr_weight += weight_adjustment
+                    current_natr_weight -= weight_adjustment
+            entry_natr_weight = np.clip(entry_natr_weight, 0.0, 1.0)
+            current_natr_weight = np.clip(current_natr_weight, 0.0, 1.0)
         take_profit_natr = (
             entry_natr_weight * entry_natr + current_natr_weight * current_natr
         )
index 6315583c64551ebc74f3bfe0f281f6682facf137..84f12a11167773df39cd790ef74e178e074d6271 100644 (file)
@@ -412,8 +412,8 @@ def zigzag(
 
     def calculate_depth(
         pos: int,
-        min_depth: int = 5,
-        max_depth: int = 30,
+        min_depth: int = 6,
+        max_depth: int = 36,
     ) -> int:
         if len(pivots_indices) < 2:
             return depth
@@ -471,6 +471,7 @@ def zigzag(
         pivots_directions.append(direction)
         last_pivot_pos = pos
         depth = calculate_depth(pos)
+        reset_candidate_pivot()
 
     def is_reversal_confirmed(
         candidate_pivot_pos: int,
@@ -625,7 +626,6 @@ def zigzag(
                 and is_reversal_confirmed(candidate_pivot_pos, i, TrendDirection.DOWN)
             ):
                 add_pivot(candidate_pivot_pos, candidate_pivot_value, TrendDirection.UP)
-                reset_candidate_pivot()
                 state = TrendDirection.DOWN
         elif state == TrendDirection.DOWN:
             if np.isnan(candidate_pivot_value) or current_low < candidate_pivot_value:
@@ -639,7 +639,6 @@ def zigzag(
                 add_pivot(
                     candidate_pivot_pos, candidate_pivot_value, TrendDirection.DOWN
                 )
-                reset_candidate_pivot()
                 state = TrendDirection.UP
 
     return pivots_indices, pivots_values, pivots_directions