From: Jérôme Benoit Date: Tue, 25 Nov 2025 13:51:11 +0000 (+0100) Subject: refactor: rename amplitude_excess -> amplitude_threshold_ratio and update docs X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=2712891c31442d8cea4c03760841c3cec7f3b355;p=freqai-strategies.git refactor: rename amplitude_excess -> amplitude_threshold_ratio and update docs --- diff --git a/README.md b/README.md index df3b26e..cce3d88 100644 --- a/README.md +++ b/README.md @@ -35,75 +35,75 @@ docker compose up -d --build ### Configuration tunables -| Path | Default | Type / Range | Description | -| ---------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| _Protections_ | | | | -| estimated_trade_duration_candles | 48 | int >= 1 | Heuristic for StoplossGuard tuning. | -| _Leverage_ | | | | -| leverage | proposed_leverage | float [1.0, max_leverage] | Leverage. Fallback to proposed_leverage for the pair. | -| _Exit pricing_ | | | | -| exit_pricing.trade_price_target | `moving_average` | enum {`moving_average`,`interpolation`,`weighted_interpolation`} | Trade NATR computation method. | -| exit_pricing.thresholds_calibration.decline_quantile | 0.90 | float (0,1) | PnL decline quantile threshold. | -| _Reversal confirmation_ | | | | -| reversal_confirmation.lookback_period | 0 | int >= 0 | Prior confirming candles; 0 = none. | -| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle relaxation factor. | -| reversal_confirmation.min_natr_ratio_percent | 0.01 | float [0,1] | Lower bound fraction for volatility adjusted reversal threshold. | -| reversal_confirmation.max_natr_ratio_percent | 0.1 | float [0,1] | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold. | -| _Regressor model_ | | | | -| freqai.regressor | `xgboost` | enum {`xgboost`,`lightgbm`} | Machine learning regressor algorithm. | -| _Extrema smoothing_ | | | | -| freqai.extrema_smoothing.method | `gaussian` | enum {`gaussian`,`kaiser`,`triang`,`smm`,`sma`} | Extrema smoothing kernel (smm=simple moving median, sma=simple moving average). | -| freqai.extrema_smoothing.window | 5 | int >= 3 | Window size for extrema smoothing. | -| freqai.extrema_smoothing.beta | 8.0 | float > 0 | Kaiser kernel shape parameter. | -| _Extrema weighting_ | | | | -| freqai.extrema_weighting.strategy | `none` | enum {`none`,`amplitude`,`amplitude_excess`} | Extrema weighting source: unweighted (`none`), swing amplitude (`amplitude`), or volatility-adjusted swing amplitude (`amplitude_excess`). | -| freqai.extrema_weighting.normalization | `minmax` | enum {`minmax`,`zscore`,`l1`,`l2`,`robust`,`softmax`,`tanh`,`rank`,`none`} | Normalization method for weights. | -| freqai.extrema_weighting.gamma | 1.0 | float (0,10] | Contrast exponent applied after normalization (>1 emphasizes extrema, 0 0 | Temperature parameter for softmax normalization (lower values sharpen distribution, higher values flatten it). | -| freqai.extrema_weighting.tanh_scale | 1.0 | float > 0 | Scale parameter for tanh normalization. | -| freqai.extrema_weighting.tanh_gain | 1.0 | float > 0 | Gain parameter for tanh normalization. | -| freqai.extrema_weighting.robust_quantiles | [0.25, 0.75] | list[float] where 0 <= q_low < q_high <= 1 | Quantile range for robust normalization. | -| freqai.extrema_weighting.rank_method | `average` | enum {`average`,`min`,`max`,`dense`,`ordinal`} | Ranking method for rank normalization. | -| _Feature parameters_ | | | | -| freqai.feature_parameters.label_period_candles | min/max midpoint | int >= 1 | Zigzag labeling NATR horizon. | -| freqai.feature_parameters.min_label_period_candles | 12 | int >= 1 | Minimum labeling NATR horizon used for reversals labeling HPO. | -| freqai.feature_parameters.max_label_period_candles | 24 | int >= 1 | Maximum labeling NATR horizon used for reversals labeling HPO. | -| freqai.feature_parameters.label_natr_ratio | min/max midpoint | float > 0 | Zigzag labeling NATR ratio. | -| freqai.feature_parameters.min_label_natr_ratio | 9.0 | float > 0 | Minimum labeling NATR ratio used for reversals labeling HPO. | -| freqai.feature_parameters.max_label_natr_ratio | 12.0 | float > 0 | Maximum labeling NATR ratio used for reversals labeling HPO. | -| freqai.feature_parameters.label_frequency_candles | `auto` | int >= 2 \| `auto` | Reversals labeling frequency. `auto` = max(2, 2 \* number of whitelisted pairs). | -| freqai.feature_parameters.label_metric | `euclidean` | string (supported: `euclidean`,`minkowski`,`cityblock`,`chebyshev`,`mahalanobis`,`seuclidean`,`jensenshannon`,`sqeuclidean`,...) | Metric used in distance calculations to ideal point. | -| freqai.feature_parameters.label_weights | [1/3,1/3,1/3] | list[float] | Per-objective weights used in distance calculations to ideal point. First objective is the number of detected reversals. Second objective is the median swing amplitude of Zigzag reversals (reversals quality). Third objective is the median volatility-adjusted swing amplitude. | -| freqai.feature_parameters.label_p_order | `None` | float | p-order used by Minkowski / power-mean calculations (optional). | -| freqai.feature_parameters.label_medoid_metric | `euclidean` | string | Metric used with `medoid`. | -| freqai.feature_parameters.label_kmeans_metric | `euclidean` | string | Metric used for k-means clustering. | -| freqai.feature_parameters.label_kmeans_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best kmeans cluster. | -| freqai.feature_parameters.label_kmedoids_metric | `euclidean` | string | Metric used for k-medoids clustering. | -| freqai.feature_parameters.label_kmedoids_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best k-medoids cluster. | -| 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. | -| _Predictions extrema_ | | | | -| freqai.predictions_extrema.selection_method | `rank` | enum {`rank`,`values`,`partition`} | Extrema selection method. `values` uses reversal values, `rank` uses ranked extrema values, `partition` uses sign-based partitioning. | -| freqai.predictions_extrema.thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`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. | -| freqai.optuna_hyperopt.storage | `file` | enum {`file`,`sqlite`} | HPO storage backend. | -| freqai.optuna_hyperopt.continuous | true | bool | Continuous HPO. | -| freqai.optuna_hyperopt.warm_start | true | bool | Warm start HPO with previous best value(s). | -| freqai.optuna_hyperopt.n_startup_trials | 15 | int >= 0 | HPO startup trials. | -| freqai.optuna_hyperopt.n_trials | 50 | int >= 1 | Maximum HPO trials. | -| freqai.optuna_hyperopt.n_jobs | CPU threads / 4 | int >= 1 | Parallel HPO workers. | -| freqai.optuna_hyperopt.timeout | 7200 | int >= 0 | HPO wall-clock timeout in seconds. | -| freqai.optuna_hyperopt.label_candles_step | 1 | int >= 1 | Step for Zigzag NATR horizon search space. | -| freqai.optuna_hyperopt.train_candles_step | 10 | int >= 1 | Step for training sets size search space. | -| freqai.optuna_hyperopt.space_reduction | false | bool | Enable/disable HPO search space reduction based on previous best parameters. | -| freqai.optuna_hyperopt.expansion_ratio | 0.4 | float [0,1] | HPO search space expansion ratio. | -| freqai.optuna_hyperopt.min_resource | 3 | int >= 1 | Minimum resource per Hyperband pruner rung. | -| freqai.optuna_hyperopt.seed | 1 | int >= 0 | HPO RNG seed. | +| Path | Default | Type / Range | Description | +| ---------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _Protections_ | | | | +| estimated_trade_duration_candles | 48 | int >= 1 | Heuristic for StoplossGuard tuning. | +| _Leverage_ | | | | +| leverage | proposed_leverage | float [1.0, max_leverage] | Leverage. Fallback to proposed_leverage for the pair. | +| _Exit pricing_ | | | | +| exit_pricing.trade_price_target | `moving_average` | enum {`moving_average`,`interpolation`,`weighted_interpolation`} | Trade NATR computation method. | +| exit_pricing.thresholds_calibration.decline_quantile | 0.90 | float (0,1) | PnL decline quantile threshold. | +| _Reversal confirmation_ | | | | +| reversal_confirmation.lookback_period | 0 | int >= 0 | Prior confirming candles; 0 = none. | +| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle relaxation factor. | +| reversal_confirmation.min_natr_ratio_percent | 0.01 | float [0,1] | Lower bound fraction for volatility adjusted reversal threshold. | +| reversal_confirmation.max_natr_ratio_percent | 0.1 | float [0,1] | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold. | +| _Regressor model_ | | | | +| freqai.regressor | `xgboost` | enum {`xgboost`,`lightgbm`} | Machine learning regressor algorithm. | +| _Extrema smoothing_ | | | | +| freqai.extrema_smoothing.method | `gaussian` | enum {`gaussian`,`kaiser`,`triang`,`smm`,`sma`} | Extrema smoothing kernel (smm=simple moving median, sma=simple moving average). | +| freqai.extrema_smoothing.window | 5 | int >= 3 | Window size for extrema smoothing. | +| freqai.extrema_smoothing.beta | 8.0 | float > 0 | Kaiser kernel shape parameter. | +| _Extrema weighting_ | | | | +| freqai.extrema_weighting.strategy | `none` | enum {`none`,`amplitude`,`amplitude_threshold_ratio`} | Extrema weighting source: unweighted (`none`), swing amplitude (`amplitude`), or volatility-threshold ratio adjusted swing amplitude (`amplitude_threshold_ratio`). | +| freqai.extrema_weighting.normalization | `minmax` | enum {`minmax`,`zscore`,`l1`,`l2`,`robust`,`softmax`,`tanh`,`rank`,`none`} | Normalization method for weights. | +| freqai.extrema_weighting.gamma | 1.0 | float (0,10] | Contrast exponent applied after normalization (>1 emphasizes extrema, 0 0 | Temperature parameter for softmax normalization (lower values sharpen distribution, higher values flatten it). | +| freqai.extrema_weighting.tanh_scale | 1.0 | float > 0 | Scale parameter for tanh normalization. | +| freqai.extrema_weighting.tanh_gain | 1.0 | float > 0 | Gain parameter for tanh normalization. | +| freqai.extrema_weighting.robust_quantiles | [0.25, 0.75] | list[float] where 0 <= q_low < q_high <= 1 | Quantile range for robust normalization. | +| freqai.extrema_weighting.rank_method | `average` | enum {`average`,`min`,`max`,`dense`,`ordinal`} | Ranking method for rank normalization. | +| _Feature parameters_ | | | | +| freqai.feature_parameters.label_period_candles | min/max midpoint | int >= 1 | Zigzag labeling NATR horizon. | +| freqai.feature_parameters.min_label_period_candles | 12 | int >= 1 | Minimum labeling NATR horizon used for reversals labeling HPO. | +| freqai.feature_parameters.max_label_period_candles | 24 | int >= 1 | Maximum labeling NATR horizon used for reversals labeling HPO. | +| freqai.feature_parameters.label_natr_ratio | min/max midpoint | float > 0 | Zigzag labeling NATR ratio. | +| freqai.feature_parameters.min_label_natr_ratio | 9.0 | float > 0 | Minimum labeling NATR ratio used for reversals labeling HPO. | +| freqai.feature_parameters.max_label_natr_ratio | 12.0 | float > 0 | Maximum labeling NATR ratio used for reversals labeling HPO. | +| freqai.feature_parameters.label_frequency_candles | `auto` | int >= 2 \| `auto` | Reversals labeling frequency. `auto` = max(2, 2 \* number of whitelisted pairs). | +| freqai.feature_parameters.label_metric | `euclidean` | string (supported: `euclidean`,`minkowski`,`cityblock`,`chebyshev`,`mahalanobis`,`seuclidean`,`jensenshannon`,`sqeuclidean`,...) | Metric used in distance calculations to ideal point. | +| freqai.feature_parameters.label_weights | [1/3,1/3,1/3] | list[float] | Per-objective weights used in distance calculations to ideal point. First objective is the number of detected reversals. Second objective is the median swing amplitude of Zigzag reversals (reversals quality). Third objective is the median volatility-threshold ratio adjusted swing amplitude. | +| freqai.feature_parameters.label_p_order | `None` | float | p-order used by Minkowski / power-mean calculations (optional). | +| freqai.feature_parameters.label_medoid_metric | `euclidean` | string | Metric used with `medoid`. | +| freqai.feature_parameters.label_kmeans_metric | `euclidean` | string | Metric used for k-means clustering. | +| freqai.feature_parameters.label_kmeans_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best kmeans cluster. | +| freqai.feature_parameters.label_kmedoids_metric | `euclidean` | string | Metric used for k-medoids clustering. | +| freqai.feature_parameters.label_kmedoids_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best k-medoids cluster. | +| 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. | +| _Predictions extrema_ | | | | +| freqai.predictions_extrema.selection_method | `rank` | enum {`rank`,`values`,`partition`} | Extrema selection method. `values` uses reversal values, `rank` uses ranked extrema values, `partition` uses sign-based partitioning. | +| freqai.predictions_extrema.thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`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. | +| freqai.optuna_hyperopt.storage | `file` | enum {`file`,`sqlite`} | HPO storage backend. | +| freqai.optuna_hyperopt.continuous | true | bool | Continuous HPO. | +| freqai.optuna_hyperopt.warm_start | true | bool | Warm start HPO with previous best value(s). | +| freqai.optuna_hyperopt.n_startup_trials | 15 | int >= 0 | HPO startup trials. | +| freqai.optuna_hyperopt.n_trials | 50 | int >= 1 | Maximum HPO trials. | +| freqai.optuna_hyperopt.n_jobs | CPU threads / 4 | int >= 1 | Parallel HPO workers. | +| freqai.optuna_hyperopt.timeout | 7200 | int >= 0 | HPO wall-clock timeout in seconds. | +| freqai.optuna_hyperopt.label_candles_step | 1 | int >= 1 | Step for Zigzag NATR horizon search space. | +| freqai.optuna_hyperopt.train_candles_step | 10 | int >= 1 | Step for training sets size search space. | +| freqai.optuna_hyperopt.space_reduction | false | bool | Enable/disable HPO search space reduction based on previous best parameters. | +| freqai.optuna_hyperopt.expansion_ratio | 0.4 | float [0,1] | HPO search space expansion ratio. | +| freqai.optuna_hyperopt.min_resource | 3 | int >= 1 | Minimum resource per Hyperband pruner rung. | +| freqai.optuna_hyperopt.seed | 1 | int >= 0 | HPO RNG seed. | ## ReforceXY diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 65f7c66..7b0a958 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -2147,7 +2147,7 @@ def label_objective( if df.empty: return 0, 0.0, 0.0 - _, pivots_values, _, pivots_amplitudes, pivots_amplitude_excesses = zigzag( + _, pivots_values, _, pivots_amplitudes, pivots_amplitude_threshold_ratios = zigzag( df, natr_period=label_period_candles, natr_ratio=label_natr_ratio, @@ -2157,10 +2157,10 @@ def label_objective( if not np.isfinite(median_amplitude): median_amplitude = 0.0 - median_amplitude_excess = np.nanmedian( - np.asarray(pivots_amplitude_excesses, dtype=float) + median_amplitude_threshold_ratio = np.nanmedian( + np.asarray(pivots_amplitude_threshold_ratios, dtype=float) ) - if not np.isfinite(median_amplitude_excess): - median_amplitude_excess = 0.0 + if not np.isfinite(median_amplitude_threshold_ratio): + median_amplitude_threshold_ratio = 0.0 - return len(pivots_values), median_amplitude, median_amplitude_excess + return len(pivots_values), median_amplitude, median_amplitude_threshold_ratio diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index fe6b7e1..4faa12c 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -197,7 +197,9 @@ class QuickAdapterV3(IStrategy): estimated_trade_duration_candles = int( self.config.get("estimated_trade_duration_candles", 48) ) - stoploss_guard_lookback_period_candles = int(fit_live_predictions_candles / 2) + stoploss_guard_lookback_period_candles = int( + round(fit_live_predictions_candles * 0.5) + ) stoploss_guard_trade_limit = max( 1, int( @@ -776,14 +778,14 @@ class QuickAdapterV3(IStrategy): def _get_weights( strategy: WeightStrategy, amplitudes: list[float], - amplitude_excesses: list[float], + amplitude_threshold_ratios: list[float], ) -> list[float]: if strategy == WEIGHT_STRATEGIES[1]: # "amplitude" return amplitudes - if strategy == WEIGHT_STRATEGIES[2]: # "amplitude_excess" + if strategy == WEIGHT_STRATEGIES[2]: # "amplitude_threshold_ratio" return ( - amplitude_excesses - if len(amplitude_excesses) == len(amplitudes) + amplitude_threshold_ratios + if len(amplitude_threshold_ratios) == len(amplitudes) else amplitudes ) return [] @@ -799,7 +801,7 @@ class QuickAdapterV3(IStrategy): _, pivots_directions, pivots_amplitudes, - pivots_amplitude_excesses, + pivots_amplitude_threshold_ratios, ) = zigzag( dataframe, natr_period=label_period_candles, @@ -835,7 +837,7 @@ class QuickAdapterV3(IStrategy): pivot_weights = QuickAdapterV3._get_weights( extrema_weighting_params["strategy"], pivots_amplitudes, - pivots_amplitude_excesses, + pivots_amplitude_threshold_ratios, ) weighted_extrema, _ = get_weighted_extrema( extrema=dataframe[EXTREMA_COLUMN], diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index 5c3bb12..1db99a9 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -18,11 +18,11 @@ from technical import qtpylib T = TypeVar("T", pd.Series, float) -WeightStrategy = Literal["none", "amplitude", "amplitude_excess"] +WeightStrategy = Literal["none", "amplitude", "amplitude_threshold_ratio"] WEIGHT_STRATEGIES: Final[tuple[WeightStrategy, ...]] = ( "none", "amplitude", - "amplitude_excess", + "amplitude_threshold_ratio", ) EXTREMA_COLUMN: Final = "&s-extrema" @@ -463,7 +463,7 @@ def get_weighted_extrema( if strategy in { WEIGHT_STRATEGIES[1], WEIGHT_STRATEGIES[2], - }: # "amplitude" or "amplitude_excess" + }: # "amplitude" or "amplitude_threshold_ratio" extrema_weights = calculate_extrema_weights( series=extrema, indices=indices, @@ -912,7 +912,7 @@ def zigzag( pivots_values: list[float] = [] pivots_directions: list[TrendDirection] = [] pivots_amplitudes: list[float] = [] - pivots_amplitude_excesses: list[float] = [] + pivots_amplitude_threshold_ratios: list[float] = [] last_pivot_pos: int = -1 candidate_pivot_pos: int = -1 @@ -974,14 +974,14 @@ def zigzag( and current_threshold > 0 and np.isfinite(amplitude) ): - amplitude_excess = amplitude / current_threshold + amplitude_threshold_ratio = amplitude / current_threshold else: - amplitude_excess = np.nan + amplitude_threshold_ratio = np.nan else: amplitude = np.nan - amplitude_excess = np.nan + amplitude_threshold_ratio = np.nan pivots_amplitudes.append(amplitude) - pivots_amplitude_excesses.append(amplitude_excess) + pivots_amplitude_threshold_ratios.append(amplitude_threshold_ratio) last_pivot_pos = pos reset_candidate_pivot() @@ -1134,7 +1134,7 @@ def zigzag( pivots_values, pivots_directions, pivots_amplitudes, - pivots_amplitude_excesses, + pivots_amplitude_threshold_ratios, )