From 31ca68b0668565b0d8a02c76e22cc00d48bcfb8c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 19 May 2025 01:09:51 +0200 Subject: [PATCH] fix(qav3): handle assets with close to zero at pivot labeling MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit use a log space for prices Signed-off-by: Jérôme Benoit --- .../freqaimodels/QuickAdapterRegressorV3.py | 35 ++++++++++--------- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 33 ++++++++--------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 4991301..dd79c6b 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -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 diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index ffbcc94..2387ea7 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -58,7 +58,7 @@ class QuickAdapterV3(IStrategy): INTERFACE_VERSION = 3 def version(self) -> str: - return "3.3.37" + return "3.3.38" timeframe = "5m" diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index b01947f..3e0d417 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -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 -- 2.43.0