From 1f6ec6c77d4d238945a6d7c3da253667b7467163 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 22 May 2025 21:13:53 +0200 Subject: [PATCH] fix(qav3): recalibrate pivot optimization to avoid failed study MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- ReforceXY/user_data/freqaimodels/ReforceXY.py | 6 ++++-- .../freqaimodels/QuickAdapterRegressorV3.py | 21 ++++++++++++------- .../user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 11 +++++----- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/ReforceXY/user_data/freqaimodels/ReforceXY.py b/ReforceXY/user_data/freqaimodels/ReforceXY.py index c9ff9c4..ebc3b9d 100644 --- a/ReforceXY/user_data/freqaimodels/ReforceXY.py +++ b/ReforceXY/user_data/freqaimodels/ReforceXY.py @@ -20,7 +20,7 @@ from optuna.exceptions import ExperimentalWarning from optuna.pruners import HyperbandPruner from optuna.samplers import TPESampler from optuna.study import Study, StudyDirection -from optuna.storages import JournalStorage, BaseStorage +from optuna.storages import BaseStorage, JournalStorage, RDBStorage from optuna.storages.journal import JournalFileBackend from pandas import DataFrame, concat, merge from sb3_contrib.common.maskable.callbacks import MaskableEvalCallback @@ -494,7 +494,9 @@ class ReforceXY(BaseReinforcementLearningModel): storage_filename = f"optuna-{pair.split('/')[0]}" if pair else "optuna" storage_backend = self.rl_config_optuna.get("storage", "sqlite") if storage_backend == "sqlite": - storage = f"sqlite:///{storage_dir}/{storage_filename}.sqlite" + storage = RDBStorage( + url=f"sqlite:///{storage_dir}/{storage_filename}.sqlite" + ) elif storage_backend == "file": storage = JournalStorage( JournalFileBackend(f"{storage_dir}/{storage_filename}.log") diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 3a775f1..0ead289 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.54" + version = "3.7.55" @cached_property def _optuna_config(self) -> dict: @@ -535,7 +535,13 @@ class QuickAdapterRegressorV3(BaseRegressionModel): storage_filename = f"optuna-{pair.split('/')[0]}" storage_backend = self._optuna_config.get("storage") if storage_backend == "sqlite": - storage = f"sqlite:///{storage_dir}/{storage_filename}.sqlite" + storage = optuna.storages.RDBStorage( + url=f"sqlite:///{storage_dir}/{storage_filename}.sqlite", + heartbeat_interval=60, + failed_trial_callback=optuna.storages.RetryFailedTrialCallback( + max_retry=3 + ), + ) elif storage_backend == "file": storage = optuna.storages.JournalStorage( optuna.storages.journal.JournalFileBackend( @@ -929,21 +935,22 @@ def zigzag( min_depth: int = 6, max_depth: int = 36, ) -> int: - if len(pivots_indices) < 2: + if not pivots_indices: return min_depth + depth_factor = calculate_depth_factor(pos) + if len(pivots_indices) < 2: + return np.clip(int(min_depth * depth_factor), min_depth, max_depth) previous_periods = np.diff(pivots_indices[-3:]) weights = np.linspace(0.5, 1.5, len(previous_periods)) average_period = np.average(previous_periods, weights=weights) - depth_factor = calculate_depth_factor(pos) - return np.clip(int(average_period * depth_factor), min_depth, max_depth) def calculate_min_slope_strength( pos: int, - min_strength: float = 1.025, - max_strength: float = 1.525, + min_strength: float = 1.0 + np.finfo(float).eps, + max_strength: float = 1.5 + np.finfo(float).eps, ) -> float: start = max(0, pos - natr_period) end = min(pos + 1, n) diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index dacf292..74cfa27 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.54" + return "3.3.55" timeframe = "5m" diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index 7f8a596..142c1d7 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -418,21 +418,22 @@ def zigzag( min_depth: int = 6, max_depth: int = 36, ) -> int: - if len(pivots_indices) < 2: + if not pivots_indices: return min_depth + depth_factor = calculate_depth_factor(pos) + if len(pivots_indices) < 2: + return np.clip(int(min_depth * depth_factor), min_depth, max_depth) previous_periods = np.diff(pivots_indices[-3:]) weights = np.linspace(0.5, 1.5, len(previous_periods)) average_period = np.average(previous_periods, weights=weights) - depth_factor = calculate_depth_factor(pos) - return np.clip(int(average_period * depth_factor), min_depth, max_depth) def calculate_min_slope_strength( pos: int, - min_strength: float = 1.025, - max_strength: float = 1.525, + min_strength: float = 1.0 + np.finfo(float).eps, + max_strength: float = 1.5 + np.finfo(float).eps, ) -> float: start = max(0, pos - natr_period) end = min(pos + 1, n) -- 2.43.0