From 3baf0245c0642691e09d440dce075e51e3f4ed94 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 3 Jun 2025 13:48:30 +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 | 22 +++++++++++-------- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 18 +++++++++------ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 814b903..ce3f629 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -1,6 +1,7 @@ from enum import IntEnum import logging import json +from statistics import median import time import numpy as np import pandas as pd @@ -45,7 +46,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): https://github.com/sponsors/robcaulk """ - version = "3.7.75" + version = "3.7.76" @cached_property def _optuna_config(self) -> dict: @@ -1074,8 +1075,8 @@ def zigzag( natr_period: int = 14, natr_ratio: float = 6.0, ) -> tuple[list[int], list[float], list[int]]: - min_confirmation_window: int = 2 - max_confirmation_window: int = 6 + min_confirmation_window: int = 3 + max_confirmation_window: int = 5 n = len(df) if df.empty or n < max(natr_period, 2 * max_confirmation_window + 1): return [], [], [] @@ -1128,7 +1129,7 @@ def zigzag( ) -> int: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return int(round(np.median([min_window, max_window]))) + return int(round(median([min_window, max_window]))) return np.clip( round(max_window - (max_window - min_window) * volatility_quantile), @@ -1139,11 +1140,11 @@ def zigzag( def calculate_depth( pos: int, min_depth: int = 6, - max_depth: int = 24, + max_depth: int = 26, ) -> int: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return int(round(np.median([min_depth, max_depth]))) + return int(round(median([min_depth, max_depth]))) return np.clip( round(max_depth - (max_depth - min_depth) * volatility_quantile), @@ -1155,12 +1156,15 @@ def zigzag( pos: int, min_strength: float = 0.5, max_strength: float = 1.5, + volatility_exponent: float = 1.5, ) -> float: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return np.median([min_strength, max_strength]) + return median([min_strength, max_strength]) - return min_strength + (max_strength - min_strength) * volatility_quantile + return min_strength + (max_strength - min_strength) * ( + volatility_quantile**volatility_exponent + ) def update_candidate_pivot(pos: int, value: float, direction: TrendDirection): nonlocal candidate_pivot_pos, candidate_pivot_value, candidate_pivot_direction @@ -1378,7 +1382,7 @@ def label_objective( max_label_period_candles, step=candles_step, ) - label_natr_ratio = trial.suggest_float("label_natr_ratio", 4.0, 16.0, step=0.01) + label_natr_ratio = trial.suggest_float("label_natr_ratio", 2.0, 10.0, step=0.01) df = df.iloc[ -( diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index f723862..1c022f3 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -60,7 +60,7 @@ class QuickAdapterV3(IStrategy): INTERFACE_VERSION = 3 def version(self) -> str: - return "3.3.79" + return "3.3.80" timeframe = "5m" diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index a641914..0c2cd95 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -1,5 +1,6 @@ from enum import IntEnum from functools import lru_cache +from statistics import median import numpy as np import pandas as pd import scipy as sp @@ -379,8 +380,8 @@ def zigzag( natr_period: int = 14, natr_ratio: float = 6.0, ) -> tuple[list[int], list[float], list[int]]: - min_confirmation_window: int = 2 - max_confirmation_window: int = 6 + min_confirmation_window: int = 3 + max_confirmation_window: int = 5 n = len(df) if df.empty or n < max(natr_period, 2 * max_confirmation_window + 1): return [], [], [] @@ -433,7 +434,7 @@ def zigzag( ) -> int: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return int(round(np.median([min_window, max_window]))) + return int(round(median([min_window, max_window]))) return np.clip( round(max_window - (max_window - min_window) * volatility_quantile), @@ -444,11 +445,11 @@ def zigzag( def calculate_depth( pos: int, min_depth: int = 6, - max_depth: int = 24, + max_depth: int = 26, ) -> int: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return int(round(np.median([min_depth, max_depth]))) + return int(round(median([min_depth, max_depth]))) return np.clip( round(max_depth - (max_depth - min_depth) * volatility_quantile), @@ -460,12 +461,15 @@ def zigzag( pos: int, min_strength: float = 0.5, max_strength: float = 1.5, + volatility_exponent: float = 1.5, ) -> float: volatility_quantile = calculate_volatility_quantile(pos) if np.isnan(volatility_quantile): - return np.median([min_strength, max_strength]) + return median([min_strength, max_strength]) - return min_strength + (max_strength - min_strength) * volatility_quantile + return min_strength + (max_strength - min_strength) * ( + volatility_quantile**volatility_exponent + ) def update_candidate_pivot(pos: int, value: float, direction: TrendDirection): nonlocal candidate_pivot_pos, candidate_pivot_value, candidate_pivot_direction -- 2.43.0