From dc39fb027dfd651822366ab051819a29cb9ab0c7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 15 Jun 2025 23:53:18 +0200 Subject: [PATCH] perf(qav3): fine tune pivots labeling confirmation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../freqaimodels/QuickAdapterRegressorV3.py | 19 ++++++++++--------- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 17 +++++++++-------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index b29d39e..fca8a27 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -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 diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index ca0cc79..c404e4a 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -64,7 +64,7 @@ class QuickAdapterV3(IStrategy): INTERFACE_VERSION = 3 def version(self) -> str: - return "3.3.94" + return "3.3.95" timeframe = "5m" diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index ad88660..7fbd6ed 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -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 -- 2.43.0