From deaf221cd1f3b58fdb77fe968d2d4c4ca4b0e17f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 10 May 2025 15:08:37 +0200 Subject: [PATCH] perf(qav3): tune pivot labeling optimization MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../freqaimodels/QuickAdapterRegressorV3.py | 46 +++++++++---------- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 42 ++++++++--------- 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 65b6845..3bf4961 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.31" + version = "3.7.32" @cached_property def _optuna_config(self) -> dict: @@ -914,8 +914,24 @@ def zigzag( previous_closes = closes[previous_slice] previous_highs = highs[previous_slice] previous_lows = lows[previous_slice] - if len(next_closes) == 0 or len(previous_closes) == 0: - return False + + local_extrema_ok = False + if direction == TrendDirection.DOWN: + if ( + np.all(next_closes < highs[candidate_pivot_pos]) + and np.all(previous_closes < highs[candidate_pivot_pos]) + and np.max(next_highs) <= highs[candidate_pivot_pos] + and np.max(previous_highs) <= highs[candidate_pivot_pos] + ): + local_extrema_ok = True + elif direction == TrendDirection.UP: + if ( + np.all(next_closes > lows[candidate_pivot_pos]) + and np.all(previous_closes > lows[candidate_pivot_pos]) + and np.min(next_lows) >= lows[candidate_pivot_pos] + and np.min(previous_lows) >= lows[candidate_pivot_pos] + ): + local_extrema_ok = True slope_ok = True if len(next_closes) >= 2: @@ -925,7 +941,7 @@ def zigzag( elif direction == TrendDirection.UP: slope_ok = next_slope > 0 - thresholds_ratio = 0.175 + thresholds_ratio = 0.25 significant_move_away_ok = False if direction == TrendDirection.DOWN: if np.any( @@ -942,25 +958,7 @@ def zigzag( ): significant_move_away_ok = True - if direction == TrendDirection.DOWN: - return ( - np.all(next_closes < highs[candidate_pivot_pos]) - and np.all(previous_closes < highs[candidate_pivot_pos]) - and np.max(next_highs) <= highs[candidate_pivot_pos] - and np.max(previous_highs) <= highs[candidate_pivot_pos] - and slope_ok - and significant_move_away_ok - ) - elif direction == TrendDirection.UP: - return ( - np.all(next_closes > lows[candidate_pivot_pos]) - and np.all(previous_closes > lows[candidate_pivot_pos]) - and np.min(next_lows) >= lows[candidate_pivot_pos] - and np.min(previous_lows) >= lows[candidate_pivot_pos] - and slope_ok - and significant_move_away_ok - ) - return False + return local_extrema_ok and slope_ok and significant_move_away_ok start_pos = 0 initial_high_pos = start_pos @@ -1052,7 +1050,7 @@ def label_objective( max_label_period_candles, step=candles_step, ) - label_natr_ratio = trial.suggest_float("label_natr_ratio", 0.07, 0.2) + label_natr_ratio = trial.suggest_float("label_natr_ratio", 0.08, 0.25) df = df.iloc[ -( diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index c0723bb..aa8df4e 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.27" + return "3.3.28" timeframe = "5m" diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index cda7e98..daf7d7e 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -408,8 +408,24 @@ def zigzag( previous_closes = closes[previous_slice] previous_highs = highs[previous_slice] previous_lows = lows[previous_slice] - if len(next_closes) == 0 or len(previous_closes) == 0: - return False + + local_extrema_ok = False + if direction == TrendDirection.DOWN: + if ( + np.all(next_closes < highs[candidate_pivot_pos]) + and np.all(previous_closes < highs[candidate_pivot_pos]) + and np.max(next_highs) <= highs[candidate_pivot_pos] + and np.max(previous_highs) <= highs[candidate_pivot_pos] + ): + local_extrema_ok = True + elif direction == TrendDirection.UP: + if ( + np.all(next_closes > lows[candidate_pivot_pos]) + and np.all(previous_closes > lows[candidate_pivot_pos]) + and np.min(next_lows) >= lows[candidate_pivot_pos] + and np.min(previous_lows) >= lows[candidate_pivot_pos] + ): + local_extrema_ok = True slope_ok = True if len(next_closes) >= 2: @@ -419,7 +435,7 @@ def zigzag( elif direction == TrendDirection.UP: slope_ok = next_slope > 0 - thresholds_ratio = 0.175 + thresholds_ratio = 0.25 significant_move_away_ok = False if direction == TrendDirection.DOWN: if np.any( @@ -436,25 +452,7 @@ def zigzag( ): significant_move_away_ok = True - if direction == TrendDirection.DOWN: - return ( - np.all(next_closes < highs[candidate_pivot_pos]) - and np.all(previous_closes < highs[candidate_pivot_pos]) - and np.max(next_highs) <= highs[candidate_pivot_pos] - and np.max(previous_highs) <= highs[candidate_pivot_pos] - and slope_ok - and significant_move_away_ok - ) - elif direction == TrendDirection.UP: - return ( - np.all(next_closes > lows[candidate_pivot_pos]) - and np.all(previous_closes > lows[candidate_pivot_pos]) - and np.min(next_lows) >= lows[candidate_pivot_pos] - and np.min(previous_lows) >= lows[candidate_pivot_pos] - and slope_ok - and significant_move_away_ok - ) - return False + return local_extrema_ok and slope_ok and significant_move_away_ok start_pos = 0 initial_high_pos = start_pos -- 2.43.0