From 187d95afc46eab33cd4bc5183e3d0d48ca514353 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 20 Nov 2025 11:23:06 +0100 Subject: [PATCH] !refactor(qav3): cleanup predictions handling tunables MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 10 +++++----- quickadapter/user_data/config-template.json | 5 +++-- .../freqaimodels/QuickAdapterRegressorV3.py | 14 +++++++------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 233cb0c..07b0f2a 100644 --- a/README.md +++ b/README.md @@ -78,11 +78,11 @@ docker compose up -d --build | freqai.feature_parameters.label_knn_metric | `minkowski` | string | Distance metric for KNN. | | freqai.feature_parameters.label_knn_p_order | `None` | float | p-order for KNN Minkowski metric distance. (optional) | | freqai.feature_parameters.label_knn_n_neighbors | 5 | int >= 1 | Number of neighbors for KNN. | -| _Prediction thresholds_ | | | | -| freqai.prediction_extrema_selection | `extrema_rank` | enum {`peak_values`,`extrema_rank`,`partition`} | Extrema selection method. `peak_values` uses detected peaks, `extrema_rank` uses ranked extrema values, `partition` uses sign-based extrema partitioning. | -| freqai.prediction_thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`soft_extremum`} | Thresholding method for prediction thresholds smoothing. | -| freqai.prediction_thresholds_alpha | 12.0 | float > 0 | Alpha for `soft_extremum`. | -| freqai.outlier_threshold | 0.999 | float (0,1) | Quantile threshold for predictions outlier filtering. | +| _Predictions extrema_ | | | | +| freqai.predictions_extrema.selection_method | `extrema_rank` | enum {`peak_values`,`extrema_rank`,`partition`} | Extrema selection method. `peak_values` uses detected peaks, `extrema_rank` uses ranked extrema values, `partition` uses sign-based extrema partitioning. | +| freqai.predictions_extrema.thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`soft_extremum`} | Thresholding method for prediction thresholds smoothing. | +| freqai.predictions_extrema.thresholds_alpha | 12.0 | float > 0 | Alpha for `soft_extremum`. | +| freqai.predictions_extrema.threshold_outlier | 0.999 | float (0,1) | Quantile threshold for predictions outlier filtering. | | _Optuna / HPO_ | | | | | freqai.optuna_hyperopt.enabled | true | bool | Enables HPO. | | freqai.optuna_hyperopt.sampler | `tpe` | enum {`tpe`,`auto`} | HPO sampler algorithm. `tpe` uses TPESampler with multivariate and group, `auto` uses AutoSampler. | diff --git a/quickadapter/user_data/config-template.json b/quickadapter/user_data/config-template.json index 5e23f35..cb1cf1b 100644 --- a/quickadapter/user_data/config-template.json +++ b/quickadapter/user_data/config-template.json @@ -115,8 +115,9 @@ "fit_live_predictions_candles": 864, "data_kitchen_thread_count": 6, // set to number of CPU threads / 4 "track_performance": false, - "prediction_thresholds_smoothing": "isodata", - "outlier_threshold": 0.999, + "predictions_extrema": { + "thresholds_smoothing": "isodata" + }, "optuna_hyperopt": { "enabled": true, "n_jobs": 6, diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 055dc07..2f45f92 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -650,8 +650,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel): f = sp.stats.weibull_min.fit( pd.to_numeric(di_values, errors="coerce").dropna() ) + predictions_extrema = self.freqai_info.get("predictions_extrema", {}) cutoff = sp.stats.weibull_min.ppf( - self.freqai_info.get("outlier_threshold", 0.999), *f + predictions_extrema.get("threshold_outlier", 0.999), *f ) dk.data["DI_value_mean"] = di_values.mean() @@ -720,9 +721,10 @@ class QuickAdapterRegressorV3(BaseRegressionModel): pred_extrema = pred_df.get(EXTREMA_COLUMN).iloc[-thresholds_candles:].copy() + predictions_extrema = self.freqai_info.get("predictions_extrema", {}) extrema_selection = str( - self.freqai_info.get( - "prediction_extrema_selection", + predictions_extrema.get( + "selection_method", QuickAdapterRegressorV3._EXTREMA_SELECTION_METHODS[1], ) ) @@ -732,7 +734,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): f"Supported methods are {', '.join(self._EXTREMA_SELECTION_METHODS)}" ) thresholds_smoothing = str( - self.freqai_info.get("prediction_thresholds_smoothing", "mean") + predictions_extrema.get("thresholds_smoothing", "mean") ) skimage_thresholds_smoothing_methods = { "isodata", @@ -747,9 +749,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): {"soft_extremum"} ) if thresholds_smoothing == "soft_extremum": - thresholds_alpha = float( - self.freqai_info.get("prediction_thresholds_alpha", 12.0) - ) + thresholds_alpha = float(predictions_extrema.get("thresholds_alpha", 12.0)) return QuickAdapterRegressorV3.soft_extremum_min_max( pred_extrema, thresholds_alpha, extrema_selection ) -- 2.43.0