From 60aee42aac694f4a36f2029017204eee3a0ff01f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 29 Jul 2025 16:19:04 +0200 Subject: [PATCH] perf(qav3): revert commit 81440b2 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../freqaimodels/QuickAdapterRegressorV3.py | 32 ++++++++++++++++--- .../user_data/strategies/QuickAdapterV3.py | 2 +- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 5f9d664..937a833 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -50,7 +50,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): https://github.com/sponsors/robcaulk """ - version = "3.7.97" + version = "3.7.98" @cached_property def _optuna_config(self) -> dict[str, Any]: @@ -518,15 +518,17 @@ class QuickAdapterRegressorV3(BaseRegressionModel): fit_live_predictions_candles: int, label_period_candles: int, ) -> tuple[float, float]: - q = float(self.freqai_info.get("prediction_thresholds_quantile", 0.95)) + temperature = float( + self.freqai_info.get("prediction_thresholds_temperature", 300.0) + ) extrema = pred_df.get(EXTREMA_COLUMN).iloc[ -( max(2, int(fit_live_predictions_candles / label_period_candles)) * label_period_candles ) : ] - min_pred = extrema.quantile(q=1 - q) - max_pred = extrema.quantile(q=q) + min_pred = smoothed_min(extrema, temperature=temperature) + max_pred = smoothed_max(extrema, temperature=temperature) return min_pred, max_pred def get_multi_objective_study_best_trial( @@ -1698,6 +1700,28 @@ def label_objective( return np.median(pivots_thresholds), len(pivots_values) +def smoothed_max(series: pd.Series, temperature=1.0) -> float: + data_array = series.to_numpy() + if data_array.size == 0: + return np.nan + if temperature < 0: + raise ValueError("temperature must be non-negative") + if np.isclose(temperature, 0): + return data_array.max() + return sp.special.logsumexp(temperature * data_array) / temperature + + +def smoothed_min(series: pd.Series, temperature=1.0) -> float: + data_array = series.to_numpy() + if data_array.size == 0: + return np.nan + if temperature < 0: + raise ValueError("temperature must be non-negative") + if np.isclose(temperature, 0): + return data_array.min() + return -sp.special.logsumexp(-temperature * data_array) / temperature + + def round_to_nearest_int(value: float, step: int) -> int: """ Round a value to the nearest multiple of a given step. diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index d3236fe..c2af228 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -65,7 +65,7 @@ class QuickAdapterV3(IStrategy): INTERFACE_VERSION = 3 def version(self) -> str: - return "3.3.105" + return "3.3.106" timeframe = "5m" -- 2.43.0