]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
fix(quickadapter): track exact label availability (#113)
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 24 Jul 2026 14:00:43 +0000 (16:00 +0200)
committerGitHub <noreply@github.com>
Fri, 24 Jul 2026 14:00:43 +0000 (16:00 +0200)
Record the exact row where each Zigzag label becomes final, include TA-Lib NATR warmup/backfill in label provenance, leave unresolved trailing labels unavailable, compose centered smoothing availability over the complete kernel support, keep the incomplete right smoothing edge unavailable, reject circular wrap smoothing in causal mode, and preserve the public nine-element zigzag() tuple API.

Adds a per-row known_at_lookahead availability channel for labels and weights (weight availability lags the label by one pivot), with an optional local Gaussian fill band; the causal purge folds label and weight availability row-wise. Default path (strategy=none, fill=zero) stays byte-identical; the knn/neighbors>=2 residual is bounded, non-default, and documented.

README.md
quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 5ac33d919fdb272eafb891e46a27fba3e8c38deb..149e28225e30973d4324124f916ec0ba5c930dee 100644 (file)
--- a/README.md
+++ b/README.md
@@ -37,114 +37,114 @@ docker compose up -d --build
 
 ### Configuration tunables
 
-| Path                                                           | Default                       | Type / Range                                                                                                                                                                                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
-| -------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| _Protections_                                                  |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| custom_protections.trade_duration_candles                      | 72                            | int >= 1                                                                                                                                                                                                     | Estimated trade duration in candles. Scales protections stop duration candles and trade limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| custom_protections.lookback_period_fraction                    | 0.5                           | float (0,1]                                                                                                                                                                                                  | Fraction of `fit_live_predictions_candles` used to calculate `lookback_period_candles` for _MaxDrawdown_ and _StoplossGuard_ protections.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
-| custom_protections.cooldown.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _CooldownPeriod_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
-| custom_protections.cooldown.stop_duration_candles              | 4                             | int >= 1                                                                                                                                                                                                     | Number of candles to wait before allowing new trades after a trade is closed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| custom_protections.drawdown.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _MaxDrawdown_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-| custom_protections.drawdown.max_allowed_drawdown               | 0.2                           | float (0,1)                                                                                                                                                                                                  | Maximum allowed drawdown.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
-| custom_protections.stoploss.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _StoplossGuard_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
-| _Leverage_                                                     |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| leverage                                                       | `proposed_leverage`           | float [1.0, max_leverage]                                                                                                                                                                                    | Leverage. Fallback to `proposed_leverage` for the pair.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
-| _Exit pricing_                                                 |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| exit_pricing.trade_price_target_method                         | `moving_average`              | enum {`moving_average`,`quantile_interpolation`,`weighted_average`}                                                                                                                                          | Trade NATR computation method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| exit_pricing.thresholds_calibration.decline_quantile           | 0.5                           | float (0,1)                                                                                                                                                                                                  | PnL decline quantile threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| _Reversal confirmation_                                        |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| reversal_confirmation.lookback_period_candles                  | 0                             | int >= 0                                                                                                                                                                                                     | Prior confirming candles; 0 = none.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| reversal_confirmation.decay_fraction                           | 0.5                           | float (0,1]                                                                                                                                                                                                  | Geometric per-candle volatility adjusted reversal threshold relaxation factor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| reversal_confirmation.min_natr_multiplier_fraction             | 0.0095                        | float [0,1]                                                                                                                                                                                                  | Lower bound fraction for volatility adjusted reversal threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| reversal_confirmation.max_natr_multiplier_fraction             | 0.0125                        | float [0,1]                                                                                                                                                                                                  | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| _Regressor model_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.regressor                                               | `xgboost`                     | enum {`xgboost`,`lightgbm`,`histgradientboostingregressor`,`ngboost`,`catboost`}                                                                                                                             | Machine learning regressor algorithm.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| _Model training parameters_                                    |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.model_training_parameters.gpu_vram_gb                   | 80                            | enum {8,10,12,16,24,32,40,48,64,80}                                                                                                                                                                          | Available GPU VRAM (GB) for CatBoost, not total. Constrains `depth`, `border_count`, and `max_ctr_complexity` ranges.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| _Data split parameters_                                        |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.data_split_parameters.method                            | `train_test_split`            | enum {`train_test_split`,`timeseries_split`}                                                                                                                                                                 | Data splitting strategy. `train_test_split` for sequential split, `timeseries_split` for chronological split with configurable gap.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| freqai.data_split_parameters.test_size                         | 0.1 / None                    | float (0,1) \| int >= 1 \| None                                                                                                                                                                              | Test set size. Float for fraction, int for count. Default: 0.1 for `train_test_split`, None for `timeseries_split` (sklearn dynamic sizing).                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
-| freqai.data_split_parameters.n_splits                          | 5                             | int >= 2                                                                                                                                                                                                     | Controls train/test proportions for `timeseries_split` (higher = larger train set).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| freqai.data_split_parameters.gap                               | 0                             | int >= 0                                                                                                                                                                                                     | Samples to exclude between train/test for `timeseries_split`. When `0` and `causal_mode=true` (default), auto-set from `label_horizon_candles`; when `0` and `causal_mode=false`, auto-set from `label_period_candles`. Under `causal_mode=true`, an explicit `gap<label_horizon_candles` is rejected.                                                                                                                                                                                                                                                                                                     |
-| freqai.data_split_parameters.max_train_size                    | None                          | int >= 1 \| None                                                                                                                                                                                             | Maximum training set size for `timeseries_split`. When set, creates a sliding window instead of expanding train set. None = no limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| _Label smoothing_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.label_smoothing.method                                  | `gaussian`                    | enum {`none`,`gaussian`,`kaiser`,`kaiser_bessel_derived`,`triang`,`smm`,`sma`,`savgol`,`gaussian_filter1d`}                                                                                                  | Label smoothing method (`kaiser_bessel_derived` uses an even-length Kaiser-Bessel-derived zero-phase kernel; `smm`=median, `sma`=mean, `savgol`=Savitzky–Golay).                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.label_smoothing.window_candles                          | 5                             | int >= 3                                                                                                                                                                                                     | Smoothing window length (candles).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-| freqai.label_smoothing.beta                                    | 8.0                           | float > 0                                                                                                                                                                                                    | Shape parameter for `kaiser` and `kaiser_bessel_derived` kernels.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| freqai.label_smoothing.polyorder                               | 3                             | int >= 0                                                                                                                                                                                                     | Polynomial order for `savgol` smoothing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-| freqai.label_smoothing.mode                                    | `mirror`                      | enum {`mirror`,`constant`,`nearest`,`wrap`,`interp`}                                                                                                                                                         | Boundary mode for `savgol` and `gaussian_filter1d`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| freqai.label_smoothing.sigma                                   | 1.0                           | float > 0                                                                                                                                                                                                    | Gaussian `sigma` for `gaussian_filter1d` smoothing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| _Label weighting_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.label_weighting.strategy                                | `none`                        | enum {`none`,`uniform`,`amplitude`,`amplitude_threshold_ratio`,`volume_rate`,`speed`,`efficiency_ratio`,`volume_weighted_efficiency_ratio`,`combined`}                                                       | Label weighting metric: none (`none`), uniform unit weight on every detected pivot (`uniform`), swing amplitude (`amplitude`), swing amplitude / median volatility-threshold ratio (`amplitude_threshold_ratio`), swing volume per candle (`volume_rate`), swing speed (`speed`), swing efficiency ratio (`efficiency_ratio`), swing volume-weighted efficiency ratio (`volume_weighted_efficiency_ratio`), or combined metrics aggregation (`combined`). Switching between `none` and any other strategy requires deleting trained models to realign training emphasis.                                   |
-| freqai.label_weighting.metric_coefficients                     | {}                            | dict[str, float]                                                                                                                                                                                             | Per-metric coefficients for `combined` strategy. Keys: `amplitude`, `amplitude_threshold_ratio`, `volume_rate`, `speed`, `efficiency_ratio`, `volume_weighted_efficiency_ratio`.                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.label_weighting.aggregation                             | `arithmetic_mean`             | enum {`arithmetic_mean`,`geometric_mean`,`harmonic_mean`,`quadratic_mean`,`weighted_median`,`softmax`}                                                                                                       | Metric aggregation method for `combined` strategy. `arithmetic_mean`=(Σ(w·m)/Σ(w)), `geometric_mean`=(∏(m^w))^(1/Σw), `harmonic_mean`=Σ(w)/(Σ(w/m)), `quadratic_mean`=(Σ(w·m²)/Σ(w))^(1/2), `weighted_median`=Q₀.₅(m,w), `softmax`=Σ(m·s_i) where s_i=w_i·exp(m_i/T)/Σ(w_j·exp(m_j/T)).                                                                                                                                                                                                                                                                                                                    |
-| freqai.label_weighting.softmax_temperature                     | 1.0                           | float > 0                                                                                                                                                                                                    | Temperature T for `softmax` aggregation, controls distribution sharpness.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
-| freqai.label_weighting.fill_method                             | `zero`                        | enum {`zero`,`epsilon`,`gaussian`,`epsilon_gaussian`}                                                                                                                                                        | Off-pivot weighting scheme. `zero` hard-zeros off-pivot rows; `epsilon` applies the epsilon floor `fill_epsilon * <fill_epsilon_baseline>(pivot_weights)`; `gaussian` applies per-pivot Gaussian bumps; `epsilon_gaussian` sums the `epsilon` floor and the `gaussian` bumps. Pivot rows take the max of their raw weight and the off-pivot field at their index (no-op for `zero`). Switching away from `zero` may require retuning tree-leaf regularization (`min_child_weight`, `lambda`) and resetting any prior Optuna study. Changing this parameter requires deleting trained models.               |
-| freqai.label_weighting.fill_epsilon                            | 0.000001                      | float [0,1]                                                                                                                                                                                                  | Off-pivot fraction of the pivot baseline. Ignored when `fill_method` not in {`epsilon`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
-| freqai.label_weighting.fill_epsilon_baseline                   | `mean`                        | enum {`mean`,`median`}                                                                                                                                                                                       | Pivot baseline statistic. `mean` tracks central tendency; `median` is robust against pivot-weight skew. Ignored when `fill_method` not in {`epsilon`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                                                                                                                                  |
-| freqai.label_weighting.fill_sigma_candles                      | 25.0                          | float >= 0.5                                                                                                                                                                                                 | Gaussian standard deviation in candles for the per-pivot bumps. Acts as the upper bound on per-pivot sigma when `fill_bandwidth == "knn"`. Lower bound 0.5 prevents severe underflow in the Gaussian tail. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                              |
-| freqai.label_weighting.fill_sigma_min_candles                  | 0.5                           | float >= 0.5                                                                                                                                                                                                 | Lower bound on per-pivot sigma in candles when `fill_bandwidth == "knn"`. Clipped to `fill_sigma_candles` when larger. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                                                                     |
-| freqai.label_weighting.fill_bandwidth                          | `fixed`                       | enum {`fixed`,`knn`}                                                                                                                                                                                         | Per-pivot Gaussian bandwidth selector. `fixed` applies a constant `fill_sigma_candles` to every pivot (legacy behavior). `knn` adapts each pivot's sigma to local pivot density via `sigma_p = clip(fill_bandwidth_alpha * d_k(p), fill_sigma_min_candles, fill_sigma_candles)` where `d_k(p)` is the index distance to the `k`-th nearest pivot neighbor (Loftsgaarden & Quesenberry 1965; Silverman 1986, §5.2). Mitigates the crushing of weaker pivots by stronger neighbors in dense clusters. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`}.                                     |
-| freqai.label_weighting.fill_bandwidth_neighbors                | 1                             | int >= 1                                                                                                                                                                                                     | `k` for the k-nearest-neighbor bandwidth selector. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-| freqai.label_weighting.fill_bandwidth_alpha                    | 0.5                           | float > 0                                                                                                                                                                                                    | Multiplicative factor on the k-th neighbor distance. Smaller values produce sharper, more separated Gaussians; larger values approach the `fixed` behavior. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                                |
-| freqai.label_weighting.support_policy                          | `fallback`                    | enum {`fallback`,`raise`}                                                                                                                                                                                    | Policy when active label weighting fails support checks (after row filtering and causal split guards). `raise` aborts the fit with `ValueError`; `fallback` logs a `WARNING` and uses sanitized base sample weights for that fit. Eval (test/val) weights bypass this policy and always fall back on composition errors.                                                                                                                                                                                                                                                                                   |
-| freqai.label_weighting.min_pivot_equivalent_count              | 3                             | int >= 1                                                                                                                                                                                                     | Minimum number of surviving pivot-equivalent label weights required after filtering. Pivot-equivalent rows are weights at least 10% of the surviving maximum label weight.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
-| freqai.label_weighting.min_positive_label_weight_fraction      | 0.01                          | float [0,1]                                                                                                                                                                                                  | Minimum fraction of filtered training rows with finite positive label weights.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| freqai.label_weighting.min_effective_sample_size               | 3.0                           | float >= 1                                                                                                                                                                                                   | Minimum Kish effective sample size of the final composed training weights.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
-| _Label pipeline_                                               |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.label_pipeline.standardization                          | `none`                        | enum {`none`,`zscore`,`robust`,`mmad`,`power_yj`}                                                                                                                                                            | Standardization method applied to labels before normalization. `none`=w, `zscore`=(w-μ)/σ, `robust`=(w-median)/(Q₃-Q₁), `mmad`=(w-median)/(MAD·k), `power_yj`=YJ(w).                                                                                                                                                                                                                                                                                                                                                                                                                                       |
-| freqai.label_pipeline.robust_quantiles                         | [0.25, 0.75]                  | list[float] where 0 <= Q1 < Q3 <= 1                                                                                                                                                                          | Quantile range for robust standardization, Q1 and Q3.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| freqai.label_pipeline.mmad_scaling_factor                      | 1.4826                        | float > 0                                                                                                                                                                                                    | Scaling factor for MMAD standardization.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-| freqai.label_pipeline.normalization                            | `maxabs`                      | enum {`maxabs`,`minmax`,`sigmoid`,`none`}                                                                                                                                                                    | Normalization method applied to labels. `maxabs`=w/max(\|w\|), `minmax`=low+(w-min)/(max-min)·(high-low), `sigmoid`=2·σ(scale·w)-1, `none`=w.                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| freqai.label_pipeline.minmax_range                             | [-1.0, 1.0]                   | list[float]                                                                                                                                                                                                  | Target range for `minmax` normalization, min and max.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| freqai.label_pipeline.sigmoid_scale                            | 1.0                           | float > 0                                                                                                                                                                                                    | Scale parameter for `sigmoid` normalization, controls steepness.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.label_pipeline.gamma                                    | 1.0                           | float (0,10]                                                                                                                                                                                                 | Contrast exponent applied to labels after normalization: >1 emphasizes extrema, values between 0 and 1 soften.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| _Feature parameters_                                           |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.feature_parameters.label_period_candles                 | min/max midpoint              | int >= 1                                                                                                                                                                                                     | Zigzag labeling NATR period.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
-| freqai.feature_parameters.label_horizon_candles                | `label_period_candles`        | int >= 1                                                                                                                                                                                                     | Number of candles after a label row before the label is considered known by causal split guards. Recommended: cover the zigzag pivot confirmation lag (the smoothing kernel half-width is added automatically by `set_freqai_targets`). Used by causal split guards and `<label>_known_at_lookahead` metadata. When unset, falls back to `label_period_candles`.                                                                                                                                                                                                                                           |
-| freqai.feature_parameters.causal_mode                          | true                          | bool                                                                                                                                                                                                         | Causal split guard toggle. When `true` (default): rejects `data_split_parameters.shuffle=true`, `shuffle_after_split=true`, `reverse_train_test_order=true`; for `timeseries_split` auto-sets `gap=label_horizon_candles` when unset/`0` (rejects explicit `gap<label_horizon_candles`); for `train_test_split` drops train rows where position `>=first_test_position-label_horizon_candles`; with `<label>_known_at_lookahead` columns, additionally drops rows where `local_position + row-wise max(<label>_known_at_lookahead) >= first_test_position`. `false` is deprecated; acausal baselines only. |
-| freqai.feature_parameters.min_label_period_candles             | 12                            | int >= 1                                                                                                                                                                                                     | Minimum labeling NATR period used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| freqai.feature_parameters.max_label_period_candles             | 24                            | int >= 1                                                                                                                                                                                                     | Maximum labeling NATR period used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| freqai.feature_parameters.label_natr_multiplier                | min/max midpoint              | float > 0                                                                                                                                                                                                    | Zigzag labeling NATR multiplier.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.feature_parameters.min_label_natr_multiplier            | 9.0                           | float > 0                                                                                                                                                                                                    | Minimum labeling NATR multiplier used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| freqai.feature_parameters.max_label_natr_multiplier            | 12.0                          | float > 0                                                                                                                                                                                                    | Maximum labeling NATR multiplier 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_weights                        | [1/7,1/7,1/7,1/7,1/7,1/7,1/7] | list[float]                                                                                                                                                                                                  | Per-objective weights for trial selection methods. Objectives: (1) number of detected reversals, (2) median swing amplitude, (3) median (swing amplitude / median volatility-threshold ratio), (4) median swing volume per candle, (5) median swing speed, (6) median swing efficiency ratio, (7) median swing volume-weighted efficiency ratio.                                                                                                                                                                                                                                                           |
-| freqai.feature_parameters.label_p_order                        | None                          | float \| None                                                                                                                                                                                                | Lp exponent for parameterized metrics. Used by `minkowski` distance (default 2.0) and `power_mean` aggregation (default 1.0). Ignored by other metrics.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
-| freqai.feature_parameters.label_method                         | `compromise_programming`      | enum {`compromise_programming`,`topsis`,`kmeans`,`kmeans2`,`kmedoids`,`knn`,`medoid`}                                                                                                                        | HPO `label` Pareto front trial selection method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.feature_parameters.label_distance_metric                | `euclidean`                   | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`,`harmonic_mean`,`geometric_mean`,`arithmetic_mean`,`quadratic_mean`,`cubic_mean`,`power_mean`,`weighted_sum`} | Distance metric for `compromise_programming` and `topsis` methods. Invalid values warn and fall back to `euclidean`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
-| freqai.feature_parameters.label_cluster_metric                 | `euclidean`                   | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`}                                                                                                              | Distance metric for `kmeans`, `kmeans2`, and `kmedoids` methods. Invalid values warn and fall back to `euclidean`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-| freqai.feature_parameters.label_cluster_selection_method       | `topsis`                      | enum {`compromise_programming`,`topsis`}                                                                                                                                                                     | Cluster selection method for clustering-based label methods.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
-| freqai.feature_parameters.label_cluster_trial_selection_method | `topsis`                      | enum {`compromise_programming`,`topsis`}                                                                                                                                                                     | Best cluster trial selection method for clustering-based label methods.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
-| freqai.feature_parameters.label_density_metric                 | method-dependent              | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`}                                                                                                              | Distance metric for `knn` and `medoid` methods. Invalid values warn and fall back to the method's natural default (`minkowski` for `knn`, `euclidean` for `medoid`).                                                                                                                                                                                                                                                                                                                                                                                                                                       |
-| freqai.feature_parameters.label_density_aggregation            | `power_mean`                  | enum {`power_mean`,`quantile`,`min`,`max`}                                                                                                                                                                   | Aggregation method for KNN neighbor distances.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| freqai.feature_parameters.label_density_n_neighbors            | 5                             | int >= 1                                                                                                                                                                                                     | Number of neighbors for KNN.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
-| freqai.feature_parameters.label_density_aggregation_param      | aggregation-dependent         | float \| None                                                                                                                                                                                                | Tunable for KNN neighbor distance aggregation: Lp exponent (`power_mean`) or quantile value (`quantile`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
-| freqai.feature_parameters.scaler                               | `minmax`                      | enum {`minmax`,`maxabs`,`standard`,`robust`}                                                                                                                                                                 | Feature scaling method. `minmax`=MinMaxScaler, `maxabs`=MaxAbsScaler, `standard`=StandardScaler, `robust`=RobustScaler. Changing this parameter requires deleting trained models.                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| freqai.feature_parameters.range                                | [-1.0, 1.0]                   | list[float]                                                                                                                                                                                                  | Target range for `minmax` scaler, min and max. Changing this parameter requires deleting trained models.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-| _Label prediction_                                             |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.label_prediction.method                                 | `thresholding`                | enum {`none`,`thresholding`}                                                                                                                                                                                 | Prediction method. `none` disables threshold computation, `thresholding` enables adaptive threshold calculation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
-| freqai.label_prediction.selection_method                       | `rank_extrema`                | enum {`rank_extrema`,`rank_peaks`,`partition`}                                                                                                                                                               | Extrema selection method. `rank_extrema` ranks extrema values, `rank_peaks` ranks detected peak values, `partition` uses sign-based partitioning.                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| freqai.label_prediction.threshold_method                       | `mean`                        | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`soft_extremum`}                                                                                                                      | Thresholding method for prediction thresholds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| freqai.label_prediction.soft_extremum_alpha                    | 12.0                          | float >= 0                                                                                                                                                                                                   | Alpha for `soft_extremum` threshold method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
-| freqai.label_prediction.outlier_quantile                       | 0.999                         | float (0,1)                                                                                                                                                                                                  | Quantile threshold for predictions outlier filtering.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
-| freqai.label_prediction.keep_fraction                          | 0.0075                        | float (0,1]                                                                                                                                                                                                  | Fraction of extrema used for thresholds. 1 uses all, lower values keep only most significant. Applies to `rank_extrema` and `rank_peaks`; ignored for `partition`.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-| _Optuna / HPO_                                                 |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
-| freqai.optuna_hyperopt.enabled                                 | false                         | bool                                                                                                                                                                                                         | Enables regressor and dynamic label HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-| freqai.optuna_hyperopt.sampler                                 | `tpe`                         | enum {`tpe`,`auto`}                                                                                                                                                                                          | HPO sampler algorithm for `hp` namespace. `tpe` uses [TPESampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.TPESampler.html) with multivariate, group, and constant_liar (when multiple workers), `auto` uses [AutoSampler](https://hub.optuna.org/samplers/auto_sampler).                                                                                                                                                                                                                                                                                      |
-| freqai.optuna_hyperopt.label_sampler                           | `auto`                        | enum {`auto`,`tpe`,`nsgaii`,`nsgaiii`}                                                                                                                                                                       | HPO sampler algorithm for multi-objective `label` namespace. `nsgaii` uses [NSGAIISampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.NSGAIISampler.html), `nsgaiii` uses [NSGAIIISampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.NSGAIIISampler.html).                                                                                                                                                                                                                                                            |
-| freqai.optuna_hyperopt.storage                                 | `file`                        | enum {`file`,`sqlite`}                                                                                                                                                                                       | HPO storage backend.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
-| freqai.optuna_hyperopt.continuous                              | true                          | bool                                                                                                                                                                                                         | Continuous HPO. Forced for both namespaces in backtest and hyperopt, resetting the study on each optimization.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
-| freqai.optuna_hyperopt.warm_start                              | true                          | bool                                                                                                                                                                                                         | Warm start HPO with previous best value(s). Persisted values are loaded and saved only in live and dry-run modes; non-live runs reuse only values produced earlier in the same run.                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| 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 period `label` search space.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
-| freqai.optuna_hyperopt.space_reduction                         | false                         | bool                                                                                                                                                                                                         | Enable/disable `hp` search space reduction based on previous best parameters.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| freqai.optuna_hyperopt.space_fraction                          | 0.4                           | float [0,1]                                                                                                                                                                                                  | Fraction of the `hp` search space to use with `space_reduction`. Lower values create narrower search ranges around the best parameters.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
-| freqai.optuna_hyperopt.min_resource                            | 3                             | int >= 1                                                                                                                                                                                                     | Minimum resource per [HyperbandPruner](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.pruners.HyperbandPruner.html) rung.                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
-| freqai.optuna_hyperopt.seed                                    | 1                             | int >= 0                                                                                                                                                                                                     | HPO RNG seed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| Path                                                           | Default                       | Type / Range                                                                                                                                                                                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| -------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| _Protections_                                                  |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| custom_protections.trade_duration_candles                      | 72                            | int >= 1                                                                                                                                                                                                     | Estimated trade duration in candles. Scales protections stop duration candles and trade limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| custom_protections.lookback_period_fraction                    | 0.5                           | float (0,1]                                                                                                                                                                                                  | Fraction of `fit_live_predictions_candles` used to calculate `lookback_period_candles` for _MaxDrawdown_ and _StoplossGuard_ protections.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+| custom_protections.cooldown.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _CooldownPeriod_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| custom_protections.cooldown.stop_duration_candles              | 4                             | int >= 1                                                                                                                                                                                                     | Number of candles to wait before allowing new trades after a trade is closed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| custom_protections.drawdown.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _MaxDrawdown_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| custom_protections.drawdown.max_allowed_drawdown               | 0.2                           | float (0,1)                                                                                                                                                                                                  | Maximum allowed drawdown.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+| custom_protections.stoploss.enabled                            | true                          | bool                                                                                                                                                                                                         | Enable/disable _StoplossGuard_ protection.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
+| _Leverage_                                                     |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| leverage                                                       | `proposed_leverage`           | float [1.0, max_leverage]                                                                                                                                                                                    | Leverage. Fallback to `proposed_leverage` for the pair.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+| _Exit pricing_                                                 |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| exit_pricing.trade_price_target_method                         | `moving_average`              | enum {`moving_average`,`quantile_interpolation`,`weighted_average`}                                                                                                                                          | Trade NATR computation method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| exit_pricing.thresholds_calibration.decline_quantile           | 0.5                           | float (0,1)                                                                                                                                                                                                  | PnL decline quantile threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| _Reversal confirmation_                                        |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| reversal_confirmation.lookback_period_candles                  | 0                             | int >= 0                                                                                                                                                                                                     | Prior confirming candles; 0 = none.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| reversal_confirmation.decay_fraction                           | 0.5                           | float (0,1]                                                                                                                                                                                                  | Geometric per-candle volatility adjusted reversal threshold relaxation factor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| reversal_confirmation.min_natr_multiplier_fraction             | 0.0095                        | float [0,1]                                                                                                                                                                                                  | Lower bound fraction for volatility adjusted reversal threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| reversal_confirmation.max_natr_multiplier_fraction             | 0.0125                        | float [0,1]                                                                                                                                                                                                  | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| _Regressor model_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.regressor                                               | `xgboost`                     | enum {`xgboost`,`lightgbm`,`histgradientboostingregressor`,`ngboost`,`catboost`}                                                                                                                             | Machine learning regressor algorithm.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| _Model training parameters_                                    |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.model_training_parameters.gpu_vram_gb                   | 80                            | enum {8,10,12,16,24,32,40,48,64,80}                                                                                                                                                                          | Available GPU VRAM (GB) for CatBoost, not total. Constrains `depth`, `border_count`, and `max_ctr_complexity` ranges.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| _Data split parameters_                                        |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.data_split_parameters.method                            | `train_test_split`            | enum {`train_test_split`,`timeseries_split`}                                                                                                                                                                 | Data splitting strategy. `train_test_split` for sequential split, `timeseries_split` for chronological split with configurable gap.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| freqai.data_split_parameters.test_size                         | 0.1 / None                    | float (0,1) \| int >= 1 \| None                                                                                                                                                                              | Test set size. Float for fraction, int for count. Default: 0.1 for `train_test_split`, None for `timeseries_split` (sklearn dynamic sizing).                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+| freqai.data_split_parameters.n_splits                          | 5                             | int >= 2                                                                                                                                                                                                     | Controls train/test proportions for `timeseries_split` (higher = larger train set).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| freqai.data_split_parameters.gap                               | 0                             | int >= 0                                                                                                                                                                                                     | Samples to exclude between train/test for `timeseries_split`. When `0` and `causal_mode=true` (default), auto-set from `label_horizon_candles`; when `0` and `causal_mode=false`, auto-set from `label_period_candles`. Under `causal_mode=true`, an explicit `gap<label_horizon_candles` is rejected.                                                                                                                                                                                                                                                                                                   |
+| freqai.data_split_parameters.max_train_size                    | None                          | int >= 1 \| None                                                                                                                                                                                             | Maximum training set size for `timeseries_split`. When set, creates a sliding window instead of expanding train set. None = no limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| _Label smoothing_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.label_smoothing.method                                  | `gaussian`                    | enum {`none`,`gaussian`,`kaiser`,`kaiser_bessel_derived`,`triang`,`smm`,`sma`,`savgol`,`gaussian_filter1d`}                                                                                                  | Label smoothing method (`kaiser_bessel_derived` uses an even-length Kaiser-Bessel-derived zero-phase kernel; `smm`=median, `sma`=mean, `savgol`=Savitzky–Golay).                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.label_smoothing.window_candles                          | 5                             | int >= 3                                                                                                                                                                                                     | Smoothing window length (candles).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
+| freqai.label_smoothing.beta                                    | 8.0                           | float > 0                                                                                                                                                                                                    | Shape parameter for `kaiser` and `kaiser_bessel_derived` kernels.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| freqai.label_smoothing.polyorder                               | 3                             | int >= 0                                                                                                                                                                                                     | Polynomial order for `savgol` smoothing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| freqai.label_smoothing.mode                                    | `mirror`                      | enum {`mirror`,`constant`,`nearest`,`wrap`,`interp`}                                                                                                                                                         | Boundary mode for `savgol` and `gaussian_filter1d`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| freqai.label_smoothing.sigma                                   | 1.0                           | float > 0                                                                                                                                                                                                    | Gaussian `sigma` for `gaussian_filter1d` smoothing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| _Label weighting_                                              |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.label_weighting.strategy                                | `none`                        | enum {`none`,`uniform`,`amplitude`,`amplitude_threshold_ratio`,`volume_rate`,`speed`,`efficiency_ratio`,`volume_weighted_efficiency_ratio`,`combined`}                                                       | Label weighting metric: none (`none`), uniform unit weight on every detected pivot (`uniform`), swing amplitude (`amplitude`), swing amplitude / median volatility-threshold ratio (`amplitude_threshold_ratio`), swing volume per candle (`volume_rate`), swing speed (`speed`), swing efficiency ratio (`efficiency_ratio`), swing volume-weighted efficiency ratio (`volume_weighted_efficiency_ratio`), or combined metrics aggregation (`combined`). Switching between `none` and any other strategy requires deleting trained models to realign training emphasis.                                 |
+| freqai.label_weighting.metric_coefficients                     | {}                            | dict[str, float]                                                                                                                                                                                             | Per-metric coefficients for `combined` strategy. Keys: `amplitude`, `amplitude_threshold_ratio`, `volume_rate`, `speed`, `efficiency_ratio`, `volume_weighted_efficiency_ratio`.                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.label_weighting.aggregation                             | `arithmetic_mean`             | enum {`arithmetic_mean`,`geometric_mean`,`harmonic_mean`,`quadratic_mean`,`weighted_median`,`softmax`}                                                                                                       | Metric aggregation method for `combined` strategy. `arithmetic_mean`=(Σ(w·m)/Σ(w)), `geometric_mean`=(∏(m^w))^(1/Σw), `harmonic_mean`=Σ(w)/(Σ(w/m)), `quadratic_mean`=(Σ(w·m²)/Σ(w))^(1/2), `weighted_median`=Q₀.₅(m,w), `softmax`=Σ(m·s_i) where s_i=w_i·exp(m_i/T)/Σ(w_j·exp(m_j/T)).                                                                                                                                                                                                                                                                                                                  |
+| freqai.label_weighting.softmax_temperature                     | 1.0                           | float > 0                                                                                                                                                                                                    | Temperature T for `softmax` aggregation, controls distribution sharpness.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+| freqai.label_weighting.fill_method                             | `zero`                        | enum {`zero`,`epsilon`,`gaussian`,`epsilon_gaussian`}                                                                                                                                                        | Off-pivot weighting scheme. `zero` hard-zeros off-pivot rows; `epsilon` applies the epsilon floor `fill_epsilon * <fill_epsilon_baseline>(pivot_weights)`; `gaussian` applies per-pivot Gaussian bumps; `epsilon_gaussian` sums the `epsilon` floor and the `gaussian` bumps. Pivot rows take the max of their raw weight and the off-pivot field at their index (no-op for `zero`). Switching away from `zero` may require retuning tree-leaf regularization (`min_child_weight`, `lambda`) and resetting any prior Optuna study. Changing this parameter requires deleting trained models.             |
+| freqai.label_weighting.fill_epsilon                            | 0.000001                      | float [0,1]                                                                                                                                                                                                  | Off-pivot fraction of the pivot baseline. Ignored when `fill_method` not in {`epsilon`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| freqai.label_weighting.fill_epsilon_baseline                   | `mean`                        | enum {`mean`,`median`}                                                                                                                                                                                       | Pivot baseline statistic. `mean` tracks central tendency; `median` is robust against pivot-weight skew. Ignored when `fill_method` not in {`epsilon`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                                                                                                                                |
+| freqai.label_weighting.fill_sigma_candles                      | 25.0                          | float >= 0.5                                                                                                                                                                                                 | Gaussian standard deviation in candles for the per-pivot bumps. Acts as the upper bound on per-pivot sigma when `fill_bandwidth == "knn"`. Lower bound 0.5 prevents severe underflow in the Gaussian tail. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`}.                                                                                                                                                                                                                                                                                                                            |
+| freqai.label_weighting.fill_sigma_min_candles                  | 0.5                           | float >= 0.5                                                                                                                                                                                                 | Lower bound on per-pivot sigma in candles when `fill_bandwidth == "knn"`. Clipped to `fill_sigma_candles` when larger. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                                                                   |
+| freqai.label_weighting.fill_bandwidth                          | `fixed`                       | enum {`fixed`,`knn`}                                                                                                                                                                                         | Per-pivot Gaussian bandwidth selector. `fixed` applies a constant `fill_sigma_candles` to every pivot (legacy behavior). `knn` adapts each pivot's sigma to local pivot density via `sigma_p = clip(fill_bandwidth_alpha * d_k(p), fill_sigma_min_candles, fill_sigma_candles)` where `d_k(p)` is the index distance to the `k`-th nearest pivot neighbor (Loftsgaarden & Quesenberry 1965; Silverman 1986, §5.2). Mitigates the crushing of weaker pivots by stronger neighbors in dense clusters. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`}.                                   |
+| freqai.label_weighting.fill_bandwidth_neighbors                | 1                             | int >= 1                                                                                                                                                                                                     | `k` for the k-nearest-neighbor bandwidth selector. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
+| freqai.label_weighting.fill_bandwidth_alpha                    | 0.5                           | float > 0                                                                                                                                                                                                    | Multiplicative factor on the k-th neighbor distance. Smaller values produce sharper, more separated Gaussians; larger values approach the `fixed` behavior. Ignored when `fill_method` not in {`gaussian`,`epsilon_gaussian`} or `fill_bandwidth != "knn"`.                                                                                                                                                                                                                                                                                                                                              |
+| freqai.label_weighting.support_policy                          | `fallback`                    | enum {`fallback`,`raise`}                                                                                                                                                                                    | Policy when active label weighting fails support checks (after row filtering and causal split guards). `raise` aborts the fit with `ValueError`; `fallback` logs a `WARNING` and uses sanitized base sample weights for that fit. Eval (test/val) weights bypass this policy and always fall back on composition errors.                                                                                                                                                                                                                                                                                 |
+| freqai.label_weighting.min_pivot_equivalent_count              | 3                             | int >= 1                                                                                                                                                                                                     | Minimum number of surviving pivot-equivalent label weights required after filtering. Pivot-equivalent rows are weights at least 10% of the surviving maximum label weight.                                                                                                                                                                                                                                                                                                                                                                                                                               |
+| freqai.label_weighting.min_positive_label_weight_fraction      | 0.01                          | float [0,1]                                                                                                                                                                                                  | Minimum fraction of filtered training rows with finite positive label weights.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| freqai.label_weighting.min_effective_sample_size               | 3.0                           | float >= 1                                                                                                                                                                                                   | Minimum Kish effective sample size of the final composed training weights.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
+| _Label pipeline_                                               |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.label_pipeline.standardization                          | `none`                        | enum {`none`,`zscore`,`robust`,`mmad`,`power_yj`}                                                                                                                                                            | Standardization method applied to labels before normalization. `none`=w, `zscore`=(w-μ)/σ, `robust`=(w-median)/(Q₃-Q₁), `mmad`=(w-median)/(MAD·k), `power_yj`=YJ(w).                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+| freqai.label_pipeline.robust_quantiles                         | [0.25, 0.75]                  | list[float] where 0 <= Q1 < Q3 <= 1                                                                                                                                                                          | Quantile range for robust standardization, Q1 and Q3.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| freqai.label_pipeline.mmad_scaling_factor                      | 1.4826                        | float > 0                                                                                                                                                                                                    | Scaling factor for MMAD standardization.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| freqai.label_pipeline.normalization                            | `maxabs`                      | enum {`maxabs`,`minmax`,`sigmoid`,`none`}                                                                                                                                                                    | Normalization method applied to labels. `maxabs`=w/max(\|w\|), `minmax`=low+(w-min)/(max-min)·(high-low), `sigmoid`=2·σ(scale·w)-1, `none`=w.                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| freqai.label_pipeline.minmax_range                             | [-1.0, 1.0]                   | list[float]                                                                                                                                                                                                  | Target range for `minmax` normalization, min and max.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| freqai.label_pipeline.sigmoid_scale                            | 1.0                           | float > 0                                                                                                                                                                                                    | Scale parameter for `sigmoid` normalization, controls steepness.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.label_pipeline.gamma                                    | 1.0                           | float (0,10]                                                                                                                                                                                                 | Contrast exponent applied to labels after normalization: >1 emphasizes extrema, values between 0 and 1 soften.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| _Feature parameters_                                           |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.feature_parameters.label_period_candles                 | min/max midpoint              | int >= 1                                                                                                                                                                                                     | Zigzag labeling NATR period.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+| freqai.feature_parameters.label_horizon_candles                | `label_period_candles`        | int >= 1                                                                                                                                                                                                     | Conservative fixed purge used by causal train/test guards and as the default `timeseries_split` gap. Zigzag labels additionally expose their exact row-wise confirmation time; centered smoothing composes the maximum availability time across each kernel support. When unset, falls back to `label_period_candles`.                                                                                                                                                                                                                                                                                   |
+| freqai.feature_parameters.causal_mode                          | true                          | bool                                                                                                                                                                                                         | Causal split guard toggle. When `true` (default): rejects `data_split_parameters.shuffle=true`, `shuffle_after_split=true`, `reverse_train_test_order=true`; for `timeseries_split` auto-sets `gap=label_horizon_candles` when unset/`0` (rejects explicit `gap<label_horizon_candles`); for `train_test_split` applies the same fixed purge; both split methods additionally remove train rows whose exact Zigzag confirmation (and, under active weighting, one-pivot-later weight availability) plus smoothing availability reaches the test boundary. `false` is deprecated; acausal baselines only. |
+| freqai.feature_parameters.min_label_period_candles             | 12                            | int >= 1                                                                                                                                                                                                     | Minimum labeling NATR period used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| freqai.feature_parameters.max_label_period_candles             | 24                            | int >= 1                                                                                                                                                                                                     | Maximum labeling NATR period used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| freqai.feature_parameters.label_natr_multiplier                | min/max midpoint              | float > 0                                                                                                                                                                                                    | Zigzag labeling NATR multiplier.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.feature_parameters.min_label_natr_multiplier            | 9.0                           | float > 0                                                                                                                                                                                                    | Minimum labeling NATR multiplier used for reversals labeling HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| freqai.feature_parameters.max_label_natr_multiplier            | 12.0                          | float > 0                                                                                                                                                                                                    | Maximum labeling NATR multiplier 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_weights                        | [1/7,1/7,1/7,1/7,1/7,1/7,1/7] | list[float]                                                                                                                                                                                                  | Per-objective weights for trial selection methods. Objectives: (1) number of detected reversals, (2) median swing amplitude, (3) median (swing amplitude / median volatility-threshold ratio), (4) median swing volume per candle, (5) median swing speed, (6) median swing efficiency ratio, (7) median swing volume-weighted efficiency ratio.                                                                                                                                                                                                                                                         |
+| freqai.feature_parameters.label_p_order                        | None                          | float \| None                                                                                                                                                                                                | Lp exponent for parameterized metrics. Used by `minkowski` distance (default 2.0) and `power_mean` aggregation (default 1.0). Ignored by other metrics.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+| freqai.feature_parameters.label_method                         | `compromise_programming`      | enum {`compromise_programming`,`topsis`,`kmeans`,`kmeans2`,`kmedoids`,`knn`,`medoid`}                                                                                                                        | HPO `label` Pareto front trial selection method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.feature_parameters.label_distance_metric                | `euclidean`                   | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`,`harmonic_mean`,`geometric_mean`,`arithmetic_mean`,`quadratic_mean`,`cubic_mean`,`power_mean`,`weighted_sum`} | Distance metric for `compromise_programming` and `topsis` methods. Invalid values warn and fall back to `euclidean`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+| freqai.feature_parameters.label_cluster_metric                 | `euclidean`                   | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`}                                                                                                              | Distance metric for `kmeans`, `kmeans2`, and `kmedoids` methods. Invalid values warn and fall back to `euclidean`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
+| freqai.feature_parameters.label_cluster_selection_method       | `topsis`                      | enum {`compromise_programming`,`topsis`}                                                                                                                                                                     | Cluster selection method for clustering-based label methods.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+| freqai.feature_parameters.label_cluster_trial_selection_method | `topsis`                      | enum {`compromise_programming`,`topsis`}                                                                                                                                                                     | Best cluster trial selection method for clustering-based label methods.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+| freqai.feature_parameters.label_density_metric                 | method-dependent              | enum {`euclidean`,`minkowski`,`chebyshev`,`cityblock`,`sqeuclidean`,`seuclidean`,`mahalanobis`}                                                                                                              | Distance metric for `knn` and `medoid` methods. Invalid values warn and fall back to the method's natural default (`minkowski` for `knn`, `euclidean` for `medoid`).                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+| freqai.feature_parameters.label_density_aggregation            | `power_mean`                  | enum {`power_mean`,`quantile`,`min`,`max`}                                                                                                                                                                   | Aggregation method for KNN neighbor distances.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| freqai.feature_parameters.label_density_n_neighbors            | 5                             | int >= 1                                                                                                                                                                                                     | Number of neighbors for KNN.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+| freqai.feature_parameters.label_density_aggregation_param      | aggregation-dependent         | float \| None                                                                                                                                                                                                | Tunable for KNN neighbor distance aggregation: Lp exponent (`power_mean`) or quantile value (`quantile`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+| freqai.feature_parameters.scaler                               | `minmax`                      | enum {`minmax`,`maxabs`,`standard`,`robust`}                                                                                                                                                                 | Feature scaling method. `minmax`=MinMaxScaler, `maxabs`=MaxAbsScaler, `standard`=StandardScaler, `robust`=RobustScaler. Changing this parameter requires deleting trained models.                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| freqai.feature_parameters.range                                | [-1.0, 1.0]                   | list[float]                                                                                                                                                                                                  | Target range for `minmax` scaler, min and max. Changing this parameter requires deleting trained models.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| _Label prediction_                                             |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.label_prediction.method                                 | `thresholding`                | enum {`none`,`thresholding`}                                                                                                                                                                                 | Prediction method. `none` disables threshold computation, `thresholding` enables adaptive threshold calculation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| freqai.label_prediction.selection_method                       | `rank_extrema`                | enum {`rank_extrema`,`rank_peaks`,`partition`}                                                                                                                                                               | Extrema selection method. `rank_extrema` ranks extrema values, `rank_peaks` ranks detected peak values, `partition` uses sign-based partitioning.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| freqai.label_prediction.threshold_method                       | `mean`                        | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`soft_extremum`}                                                                                                                      | Thresholding method for prediction thresholds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| freqai.label_prediction.soft_extremum_alpha                    | 12.0                          | float >= 0                                                                                                                                                                                                   | Alpha for `soft_extremum` threshold method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
+| freqai.label_prediction.outlier_quantile                       | 0.999                         | float (0,1)                                                                                                                                                                                                  | Quantile threshold for predictions outlier filtering.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| freqai.label_prediction.keep_fraction                          | 0.0075                        | float (0,1]                                                                                                                                                                                                  | Fraction of extrema used for thresholds. 1 uses all, lower values keep only most significant. Applies to `rank_extrema` and `rank_peaks`; ignored for `partition`.                                                                                                                                                                                                                                                                                                                                                                                                                                       |
+| _Optuna / HPO_                                                 |                               |                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+| freqai.optuna_hyperopt.enabled                                 | false                         | bool                                                                                                                                                                                                         | Enables regressor and dynamic label HPO.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| freqai.optuna_hyperopt.sampler                                 | `tpe`                         | enum {`tpe`,`auto`}                                                                                                                                                                                          | HPO sampler algorithm for `hp` namespace. `tpe` uses [TPESampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.TPESampler.html) with multivariate, group, and constant_liar (when multiple workers), `auto` uses [AutoSampler](https://hub.optuna.org/samplers/auto_sampler).                                                                                                                                                                                                                                                                                    |
+| freqai.optuna_hyperopt.label_sampler                           | `auto`                        | enum {`auto`,`tpe`,`nsgaii`,`nsgaiii`}                                                                                                                                                                       | HPO sampler algorithm for multi-objective `label` namespace. `nsgaii` uses [NSGAIISampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.NSGAIISampler.html), `nsgaiii` uses [NSGAIIISampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.NSGAIIISampler.html).                                                                                                                                                                                                                                                          |
+| freqai.optuna_hyperopt.storage                                 | `file`                        | enum {`file`,`sqlite`}                                                                                                                                                                                       | HPO storage backend.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+| freqai.optuna_hyperopt.continuous                              | true                          | bool                                                                                                                                                                                                         | Continuous HPO. Forced for both namespaces in backtest and hyperopt, resetting the study on each optimization.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| freqai.optuna_hyperopt.warm_start                              | true                          | bool                                                                                                                                                                                                         | Warm start HPO with previous best value(s). Persisted values are loaded and saved only in live and dry-run modes; non-live runs reuse only values produced earlier in the same run.                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| 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 period `label` search space.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| freqai.optuna_hyperopt.space_reduction                         | false                         | bool                                                                                                                                                                                                         | Enable/disable `hp` search space reduction based on previous best parameters.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| freqai.optuna_hyperopt.space_fraction                          | 0.4                           | float [0,1]                                                                                                                                                                                                  | Fraction of the `hp` search space to use with `space_reduction`. Lower values create narrower search ranges around the best parameters.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+| freqai.optuna_hyperopt.min_resource                            | 3                             | int >= 1                                                                                                                                                                                                     | Minimum resource per [HyperbandPruner](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.pruners.HyperbandPruner.html) rung.                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
+| freqai.optuna_hyperopt.seed                                    | 1                             | int >= 0                                                                                                                                                                                                     | HPO RNG seed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
 
 ## ReforceXY
 
index dfe3d08dac28583c4bdd9b2f1711d3abb824caa5..d021d053abeebee378757e53d8938a4dafa8f296 100644 (file)
@@ -94,6 +94,7 @@ from Utils import (
     get_optuna_study_model_parameters,
     label_known_at_lookahead_column_name,
     label_weight_column_name,
+    label_weight_known_at_lookahead_column_name,
     migrate_config,
     optuna_load_best_params,
     optuna_save_best_params,
@@ -482,25 +483,27 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         row's LOCAL position in ``unfiltered_df`` to recover the local
         index at which the label becomes causally available.
 
-        Row-wise ``max`` of every present ``<label>_known_at_lookahead``
-        column; labels with a missing column or any NaN are skipped
-        silently (opt-in by emission). Returns ``None`` when no label is
-        usable; callers then fall back to the position-based purge.
+        Row-wise ``max`` of every present ``<label>_known_at_lookahead`` and
+        ``<label>_weight_known_at_lookahead`` column (weight availability lags
+        the label by one pivot); columns missing or with any NaN are skipped
+        silently (opt-in by emission). Returns ``None`` when none is usable;
+        callers then fall back to the position-based purge.
         """
         QuickAdapterRegressorV3._validate_index_alignment(
             filtered_dataframe, unfiltered_df
         )
         series_list: list[pd.Series] = []
         for label_col in LABEL_COLUMNS:
-            known_at_lookahead_col = label_known_at_lookahead_column_name(label_col)
-            if known_at_lookahead_col not in unfiltered_df.columns:
-                continue
-            lookahead = unfiltered_df.loc[
-                filtered_dataframe.index, known_at_lookahead_col
-            ]
-            if lookahead.isna().any():
-                continue
-            series_list.append(pd.to_numeric(lookahead, errors="raise"))
+            for lookahead_col in (
+                label_known_at_lookahead_column_name(label_col),
+                label_weight_known_at_lookahead_column_name(label_col),
+            ):
+                if lookahead_col not in unfiltered_df.columns:
+                    continue
+                lookahead = unfiltered_df.loc[filtered_dataframe.index, lookahead_col]
+                if lookahead.isna().any():
+                    continue
+                series_list.append(pd.to_numeric(lookahead, errors="raise"))
         if not series_list:
             return None
         if len(series_list) == 1:
@@ -525,7 +528,11 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         if removed:
             logger.info(f"{context}: removed {removed} causal-unsafe train rows")
         if not keep_mask.any():
-            raise ValueError(f"{context}: causal guard removed all train rows")
+            raise ValueError(
+                f"{context}: causal guard removed all train rows "
+                f"(pivot-sparse training window; widen fit_live_predictions_candles "
+                f"or lower label_natr_multiplier)"
+            )
         return (
             train_features.loc[keep_mask],
             train_labels.loc[keep_mask],
index ee51f65c7746928db7e1d913a91e5d937d76a096..b1ff5b94926049a33c526d296aa415262ab6193c 100644 (file)
@@ -26,14 +26,15 @@ from LabelTransformer import (
     COMBINED_AGGREGATIONS,
     FILL_METHODS,
     SMOOTHING_METHODS,
+    SMOOTHING_MODES,
     WEIGHT_STRATEGIES,
     get_label_column_config,
 )
 from pandas import DataFrame, Series, isna, to_numeric
 from scipy.stats import pearsonr, t
 from technical.pivots_points import pivots_points
-
 from Utils import (
+    _OPTUNA_NAMESPACES,
     DEFAULT_FIT_LIVE_PREDICTIONS_CANDLES,
     EXTREMA_COLUMN,
     EXTREMA_DIRECTION_COLUMN,
@@ -42,11 +43,12 @@ from Utils import (
     EXTREMA_WEIGHT_SMOOTHED_COLUMN,
     LABEL_COLUMNS,
     TRADE_PRICE_TARGETS,
-    _OPTUNA_NAMESPACES,
     OptunaNamespace,
     alligator,
     bottom_log_return,
     calculate_quantile,
+    compose_label_lookahead,
+    compute_label_weight_known_at_lookahead,
     compute_label_weights,
     ensure_datetime_series,
     ewo,
@@ -54,26 +56,29 @@ from Utils import (
     format_number,
     generate_label_data,
     get_callable_sha256,
+    get_causal_mode,
     get_distance,
     get_label_defaults,
     get_label_horizon_candles,
     get_label_smoothing_config,
     get_label_weighting_config,
+    get_smoothing_kernel_half_width,
     get_zl_ma_fn,
     is_finite_number,
     label_known_at_lookahead_column_name,
     label_weight_column_name,
+    label_weight_known_at_lookahead_column_name,
     migrate_config,
     nan_average,
     non_zero_diff,
     optuna_load_best_params,
-    get_smoothing_kernel_half_width,
     price_retracement_percent,
     safe_divide,
     smooth,
     top_log_return,
     validate_range,
     vwapb,
+    weight_fill_radius,
     zlema,
 )
 
@@ -458,6 +463,24 @@ class QuickAdapterV3(IStrategy):
             / self.freqai_info.get("identifier")
         )
         feature_parameters = self.freqai_info.get("feature_parameters", {})
+        if get_causal_mode(feature_parameters, logger):
+            label_smoothing = self.label_smoothing
+            for label_col in LABEL_COLUMNS:
+                col_smoothing_config = get_label_column_config(
+                    label_col, label_smoothing["default"], label_smoothing["columns"]
+                )
+                if (
+                    col_smoothing_config["method"]
+                    in (
+                        SMOOTHING_METHODS[7],  # "savgol"
+                        SMOOTHING_METHODS[8],  # "gaussian_filter1d"
+                    )
+                    and col_smoothing_config["mode"] == SMOOTHING_MODES[3]
+                ):  # "wrap"
+                    raise ValueError(
+                        "label_smoothing.mode='wrap' is incompatible with "
+                        "feature_parameters.causal_mode=true"
+                    )
         default_label_period_candles, default_label_natr_multiplier = (
             self._label_defaults
         )
@@ -1019,6 +1042,14 @@ class QuickAdapterV3(IStrategy):
                     weighting_config=col_weighting_config,
                     logger=logger,
                 )
+                if label_data.known_at_lookahead is not None:
+                    dataframe[
+                        label_weight_known_at_lookahead_column_name(label_col)
+                    ] = compute_label_weight_known_at_lookahead(
+                        known_at_lookahead=label_data.known_at_lookahead,
+                        indices=label_data.indices,
+                        fill_radius=weight_fill_radius(col_weighting_config),
+                    )
 
             if label_col == EXTREMA_COLUMN:
                 dataframe[EXTREMA_DIRECTION_COLUMN] = dataframe[label_col]
@@ -1040,16 +1071,18 @@ class QuickAdapterV3(IStrategy):
                 )
 
             # Zero-phase smoothing reads future candles within the kernel
-            # half-width; extend the per-row label lookahead so causal
-            # split guards account for the smoothing lookahead.
-            known_at_lookahead_column = label_known_at_lookahead_column_name(label_col)
-            if known_at_lookahead_column in dataframe.columns:
-                kernel_half_width = get_smoothing_kernel_half_width(
-                    col_smoothing_config, series_length=series_length
-                )
-                if kernel_half_width > 0:
-                    dataframe[known_at_lookahead_column] = (
-                        dataframe[known_at_lookahead_column] + kernel_half_width
+            # half-width; extend the per-row lookahead so causal split guards
+            # account for the smoothing lookahead.
+            kernel_half_width = get_smoothing_kernel_half_width(
+                col_smoothing_config, series_length=series_length
+            )
+            for lookahead_column in (
+                label_known_at_lookahead_column_name(label_col),
+                label_weight_known_at_lookahead_column_name(label_col),
+            ):
+                if lookahead_column in dataframe.columns:
+                    dataframe[lookahead_column] = compose_label_lookahead(
+                        dataframe[lookahead_column], kernel_half_width
                     )
 
             if label_col == EXTREMA_COLUMN:
index 2537527c6639e6a79fbddbbd4f3a7b4c957eb49d..ba3b9637632f998434fb40b3a972c04626a37bf9 100644 (file)
@@ -544,6 +544,7 @@ EXTREMA_WEIGHT_SMOOTHED_COLUMN: Final[str] = "extrema_weight_smoothed"
 
 _LABEL_WEIGHT_SUFFIX: Final[str] = "_weight"
 _LABEL_KNOWN_AT_LOOKAHEAD_SUFFIX: Final[str] = "_known_at_lookahead"
+_LABEL_WEIGHT_KNOWN_AT_LOOKAHEAD_SUFFIX: Final[str] = "_weight_known_at_lookahead"
 
 LABEL_COLUMNS: Final[tuple[str, ...]] = (EXTREMA_COLUMN,)
 
@@ -594,6 +595,11 @@ def label_known_at_lookahead_column_name(label_col: str) -> str:
     return _label_aux_column_name(label_col, _LABEL_KNOWN_AT_LOOKAHEAD_SUFFIX)
 
 
+def label_weight_known_at_lookahead_column_name(label_col: str) -> str:
+    """Return the weight-availability lookahead column name for ``label_col``."""
+    return _label_aux_column_name(label_col, _LABEL_WEIGHT_KNOWN_AT_LOOKAHEAD_SUFFIX)
+
+
 @dataclass
 class LabelData:
     """Output of a label generator.
@@ -716,50 +722,34 @@ def _generate_extrema_label(
 ) -> LabelData:
     natr_period = params.get("natr_period", 14)
     natr_multiplier = params.get("natr_multiplier", 9.0)
-    label_horizon_candles = get_label_horizon_candles(params, logger)
-
-    (
-        pivots_indices,
-        _,
-        pivots_directions,
-        pivots_amplitudes,
-        pivots_amplitude_threshold_ratios,
-        pivots_volume_rates,
-        pivots_speeds,
-        pivots_efficiency_ratios,
-        pivots_volume_weighted_efficiency_ratios,
-    ) = zigzag(
+    result = _zigzag(
         dataframe,
         natr_period=natr_period,
         natr_multiplier=natr_multiplier,
     )
 
     series = pd.Series(0.0, index=dataframe.index)
-    if pivots_indices:
-        series.loc[pivots_indices] = pivots_directions
+    if result.indices:
+        series.loc[result.indices] = result.directions
 
     metrics: dict[str, list[float]] = {
-        "amplitude": pivots_amplitudes,
-        "amplitude_threshold_ratio": pivots_amplitude_threshold_ratios,
-        "volume_rate": pivots_volume_rates,
-        "speed": pivots_speeds,
-        "efficiency_ratio": pivots_efficiency_ratios,
-        "volume_weighted_efficiency_ratio": pivots_volume_weighted_efficiency_ratios,
+        "amplitude": result.amplitudes,
+        "amplitude_threshold_ratio": result.amplitude_threshold_ratios,
+        "volume_rate": result.volume_rates,
+        "speed": result.speeds,
+        "efficiency_ratio": result.efficiency_ratios,
+        "volume_weighted_efficiency_ratio": result.volume_weighted_efficiency_ratios,
     }
 
-    # Per-row label lookahead (in candles), NOT an absolute position:
-    # freqtrade's ``dk.slice_dataframe`` runs AFTER ``set_freqai_targets``,
-    # so any pre-slice absolute position would no longer match the causal
-    # guard's local ``np.arange(len(unfiltered_df))`` coordinate system.
     known_at_lookahead = pd.Series(
-        int(label_horizon_candles),
+        result.known_at_positions - np.arange(len(dataframe), dtype=np.int64),
         index=dataframe.index,
         dtype=np.int64,
     )
 
     return LabelData(
         series=series,
-        indices=pivots_indices,
+        indices=result.indices,
         metrics=metrics,
         known_at_lookahead=known_at_lookahead,
     )
@@ -853,6 +843,63 @@ def get_smoothing_kernel_half_width(
     return effective_window // 2
 
 
+def _sanitize_known_at_lookahead(
+    known_at_lookahead: pd.Series,
+) -> tuple[NDArray[np.int64], NDArray[np.int64]]:
+    """Row positions and non-finite-guarded int64 lookahead values.
+
+    Non-finite lookahead casts to garbage int64 (silent, with a RuntimeWarning)
+    and a spurious ``0`` reads as "available now", keeping a row whose
+    availability is actually unknown. Map non-finite so its known_at position is
+    ``n`` (maximally unavailable) and such rows are always purged near a boundary.
+    """
+    n = len(known_at_lookahead)
+    positions = np.arange(n, dtype=np.int64)
+    raw = known_at_lookahead.to_numpy(dtype=float)
+    if n and not np.isfinite(raw).all():
+        raw = np.where(np.isfinite(raw), raw, (n - positions).astype(float))
+    return positions, raw.astype(np.int64)
+
+
+def compose_label_lookahead(
+    known_at_lookahead: pd.Series,
+    kernel_half_width: int,
+) -> pd.Series:
+    """Compose row-wise label availability with a centered smoothing kernel.
+
+    Values within the current frame's right kernel boundary stay unavailable
+    until enough future rows exist to provide the complete smoothing window.
+    """
+    if known_at_lookahead.empty:
+        return known_at_lookahead.copy()
+    n = len(known_at_lookahead)
+    positions, known_at_lookahead_values = _sanitize_known_at_lookahead(
+        known_at_lookahead
+    )
+    if kernel_half_width <= 0:
+        return pd.Series(
+            known_at_lookahead_values,
+            index=known_at_lookahead.index,
+            dtype=np.int64,
+        )
+    known_at_positions = pd.Series(
+        positions + known_at_lookahead_values,
+        index=known_at_lookahead.index,
+    )
+    smoothed_known_at_positions = known_at_positions.rolling(
+        window=2 * kernel_half_width + 1,
+        center=True,
+        min_periods=1,
+    ).max()
+    right_edge_start = max(0, n - kernel_half_width)
+    smoothed_known_at_positions.iloc[right_edge_start:] = n
+    return pd.Series(
+        smoothed_known_at_positions.to_numpy(dtype=np.int64) - positions,
+        index=known_at_lookahead.index,
+        dtype=np.int64,
+    )
+
+
 TradePriceTarget = Literal[
     "moving_average", "quantile_interpolation", "weighted_average"
 ]
@@ -2191,6 +2238,99 @@ def compute_label_weights(
     )
 
 
+# k for the weight-fill availability band: rows within k*fill_sigma_candles of a
+# pivot receive its Gaussian bump. Material radius (bump > 1% of pivot peak) is
+# sqrt(2*ln(100))=3.0349 sigma; k=4 -> tail exp(-8)=3.4e-4, ~30x below 1% with a
+# margin robust to sigma rounding (k=3 under-covers for larger sigma).
+_WEIGHT_FILL_RADIUS_SIGMA_MULTIPLIER: Final[float] = 4.0
+
+
+def weight_fill_radius(weighting_config: dict[str, Any]) -> int:
+    """Row radius over which a pivot's Gaussian-fill weight is causally shared.
+
+    Zero unless the off-pivot fill spreads a pivot's weight into neighbors
+    (``gaussian``/``epsilon_gaussian``). ``fill_sigma_candles`` upper-bounds the
+    per-pivot sigma (including ``knn``, which clips below it), so
+    ``ceil(k*fill_sigma_candles)`` covers every pivot's material Gaussian
+    support. The additive epsilon floor is a global O(fill_epsilon) term, left
+    unconstrained (negligible).
+    """
+    label_weighting = {**DEFAULTS_LABEL_WEIGHTING, **weighting_config}
+    if label_weighting["fill_method"] not in (
+        FILL_METHODS[2],  # "gaussian"
+        FILL_METHODS[3],  # "epsilon_gaussian"
+    ):
+        return 0
+    return math.ceil(
+        _WEIGHT_FILL_RADIUS_SIGMA_MULTIPLIER
+        * float(label_weighting["fill_sigma_candles"])
+    )
+
+
+def compute_label_weight_known_at_lookahead(
+    known_at_lookahead: pd.Series,
+    indices: Sequence[int] | NDArray[np.integer],
+    fill_radius: int = 0,
+) -> pd.Series:
+    """Per-row causal availability (in candles) of the label WEIGHT column.
+
+    A pivot's swing metric (its weight source) is backfilled from the adjacent
+    closing pivot, so it only becomes computable at the next pivot's
+    confirmation ``i_{k+1} == known_at_positions[indices[k+1]]``, one pivot
+    later than the pivot's own label availability ``i_k``. The trailing pivot has
+    no closing swing (weight 0 via ``_impute_weights``, so it never resolves
+    in-frame -> ``n``). Pivot rows are bumped to that lag; off-pivot rows keep
+    their label availability, EXCEPT that a Gaussian fill spreads each pivot's
+    weight over a local band ``[idx-fill_radius, idx+fill_radius]``
+    (0 disables), whose availability is bounded too. The band is LOCAL per pivot,
+    never a global max (a global bound forces ``n`` on all rows -> total train
+    purge). Folded via ``max(label, weight)`` by the causal purge.
+
+    The ``i_{k+1}`` availability is exact for ``fill_bandwidth='fixed'`` and for
+    ``knn`` with ``fill_bandwidth_neighbors=1`` (a pivot sigma then depends only
+    on already-confirmed adjacent pivots), up to each pivot's material Gaussian
+    support (the tail beyond ``fill_radius`` is immaterial by design, see
+    ``weight_fill_radius``). Under ``knn`` with ``fill_bandwidth_neighbors>=2`` a
+    pivot sigma can depend on a k-th nearest neighbor confirmed after ``i_{k+1}``,
+    making ``i_{k+1}`` a lower bound. This understates the band availability only
+    when that neighbor also lies outside ``fill_radius``, which requires
+    ``fill_bandwidth_alpha < 0.25`` (otherwise ``fill_radius = ceil(4 *
+    fill_sigma_candles)`` covers it and the neighbor's own later availability
+    dominates the ``max`` fold): the understatement is nil at the default
+    ``fill_bandwidth_alpha=0.5`` and can otherwise reach a large fraction of the
+    peak weight on the affected rows. Prefer ``fill_bandwidth='fixed'``,
+    ``fill_bandwidth_neighbors=1``, or ``fill_bandwidth_alpha>=0.25`` for
+    exactness.
+    """
+    n = len(known_at_lookahead)
+    positions, known_at_lookahead_values = _sanitize_known_at_lookahead(
+        known_at_lookahead
+    )
+    if n == 0:
+        return pd.Series(positions, index=known_at_lookahead.index, dtype=np.int64)
+    known_at_positions = positions + known_at_lookahead_values
+    idx = np.asarray(indices, dtype=int)
+    idx = np.sort(idx[(idx >= 0) & (idx < n)])
+    base = known_at_positions.copy()
+    if idx.size:
+        avail_pivot = np.empty(idx.size, dtype=np.int64)
+        avail_pivot[:-1] = known_at_positions[idx[1:]]
+        avail_pivot[-1] = n
+        base[idx] = np.maximum(base[idx], avail_pivot)
+        if fill_radius > 0:
+            for pivot_pos, pivot_avail in zip(idx.tolist(), avail_pivot.tolist()):
+                # Skip any pivot whose weight never resolves in-frame (sentinel
+                # availability == n): its Gaussian bump is 0, so it contributes
+                # to no row (on real _zigzag output only the trailing pivot).
+                if pivot_avail >= n:
+                    continue
+                lo = max(0, pivot_pos - fill_radius)
+                hi = min(n, pivot_pos + fill_radius + 1)
+                np.maximum(base[lo:hi], pivot_avail, out=base[lo:hi])
+    base = np.clip(base, positions, n)
+    return pd.Series(base - positions, index=known_at_lookahead.index, dtype=np.int64)
+
+
 def get_callable_sha256(fn: Callable[..., Any]) -> str:
     if not callable(fn):
         raise ValueError(f"Invalid fn value {type(fn).__name__!r}: must be callable")
@@ -2799,14 +2939,7 @@ class TrendDirection(IntEnum):
     DOWN = -1
 
 
-def zigzag(
-    df: pd.DataFrame,
-    natr_period: int = 14,
-    natr_multiplier: float = 9.0,
-    normalize: bool = False,
-    *,
-    logger: Logger | None = None,
-) -> tuple[
+ZigzagTuple = tuple[
     list[int],
     list[float],
     list[TrendDirection],
@@ -2816,22 +2949,66 @@ def zigzag(
     list[float],
     list[float],
     list[float],
-]:
+]
+
+
+@dataclass(frozen=True, slots=True)
+class ZigzagResult:
+    indices: list[int]
+    values_log: list[float]
+    directions: list[TrendDirection]
+    amplitudes: list[float]
+    amplitude_threshold_ratios: list[float]
+    volume_rates: list[float]
+    speeds: list[float]
+    efficiency_ratios: list[float]
+    volume_weighted_efficiency_ratios: list[float]
+    known_at_positions: NDArray[np.integer]
+
+    def as_tuple(self) -> ZigzagTuple:
+        """Return the stable public tuple representation."""
+        return (
+            self.indices,
+            self.values_log,
+            self.directions,
+            self.amplitudes,
+            self.amplitude_threshold_ratios,
+            self.volume_rates,
+            self.speeds,
+            self.efficiency_ratios,
+            self.volume_weighted_efficiency_ratios,
+        )
+
+
+def _zigzag(
+    df: pd.DataFrame,
+    natr_period: int = 14,
+    natr_multiplier: float = 9.0,
+    normalize: bool = False,
+    *,
+    logger: Logger | None = None,
+) -> ZigzagResult:
     n = len(df)
     if df.empty or n < natr_period:
-        return (
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
+        return ZigzagResult(
+            indices=[],
+            values_log=[],
+            directions=[],
+            amplitudes=[],
+            amplitude_threshold_ratios=[],
+            volume_rates=[],
+            speeds=[],
+            efficiency_ratios=[],
+            volume_weighted_efficiency_ratios=[],
+            known_at_positions=np.full(n, n, dtype=np.int64),
         )
 
-    natr_values = (ta.NATR(df, timeperiod=natr_period).bfill() / 100.0).to_numpy()
+    natr = ta.NATR(df, timeperiod=natr_period) / 100.0
+    finite_natr_positions = np.flatnonzero(np.isfinite(natr.to_numpy(dtype=float)))
+    natr_warmup_end_pos = (
+        int(finite_natr_positions[0]) if finite_natr_positions.size > 0 else n
+    )
+    natr_values = natr.bfill().to_numpy()
 
     indices: list[int] = df.index.tolist()
     thresholds: NDArray[np.floating] = natr_values * natr_multiplier
@@ -2872,6 +3049,9 @@ def zigzag(
     pivots_speeds: list[float] = []
     pivots_efficiency_ratios: list[float] = []
     pivots_volume_weighted_efficiency_ratios: list[float] = []
+    known_at_positions: NDArray[np.integer] = np.full(n, n, dtype=np.int64)
+    last_resolved_pos = -1
+    latest_confirmation_pos = -1
     last_pivot_pos: int = -1
 
     candidate_pivot_pos: int = -1
@@ -3078,11 +3258,38 @@ def zigzag(
 
         return vw_net_move / vw_path_length
 
-    def add_pivot(pos: int, value_log: float, direction: TrendDirection):
-        nonlocal last_pivot_pos
+    def add_pivot(
+        pos: int,
+        value_log: float,
+        direction: TrendDirection,
+        confirmed_at_pos: int,
+        resolve_through_pos: int,
+    ) -> None:
+        nonlocal last_pivot_pos, last_resolved_pos, latest_confirmation_pos
+        # Monotonic confirmation watermark: a pivot replayed after the initial
+        # orientation (scan restarts at initial_pivot_pos+1, before the
+        # orientation confirmation candle i) must not claim availability earlier
+        # than i, since its label depends on that orientation. Fold the latest
+        # confirmation seen so far so known_at never understates it.
+        confirmed_at_pos = max(
+            confirmed_at_pos,
+            resolve_through_pos,
+            natr_warmup_end_pos,
+            latest_confirmation_pos,
+        )
+        latest_confirmation_pos = confirmed_at_pos
+        known_at_positions[last_resolved_pos + 1 : resolve_through_pos + 1] = (
+            confirmed_at_pos
+        )
+        last_resolved_pos = max(last_resolved_pos, resolve_through_pos)
         if pivots_indices and indices[pos] == pivots_indices[-1]:
             return
 
+        # These swing metrics are backfilled onto the previous pivot from the
+        # adjacent closing pivot, confirmed at this pivot's known_at. The weight
+        # is therefore causally available one pivot later than its label;
+        # compute_label_weight_known_at_lookahead derives that lag so the causal
+        # purge masks weights on max(label, weight) availability.
         if (
             pivots_values_log
             and last_pivot_pos >= 0
@@ -3227,33 +3434,58 @@ def zigzag(
         )
         if is_initial_high_move_significant and is_initial_low_move_significant:
             if initial_move_from_high > initial_move_from_low:
-                add_pivot(initial_high_pos, initial_high_log, TrendDirection.UP)
+                add_pivot(
+                    initial_high_pos,
+                    initial_high_log,
+                    TrendDirection.UP,
+                    i,
+                    initial_high_pos,
+                )
                 state = TrendDirection.DOWN
                 break
             else:
-                add_pivot(initial_low_pos, initial_low_log, TrendDirection.DOWN)
+                add_pivot(
+                    initial_low_pos,
+                    initial_low_log,
+                    TrendDirection.DOWN,
+                    i,
+                    initial_low_pos,
+                )
                 state = TrendDirection.UP
                 break
         else:
             if is_initial_high_move_significant:
-                add_pivot(initial_high_pos, initial_high_log, TrendDirection.UP)
+                add_pivot(
+                    initial_high_pos,
+                    initial_high_log,
+                    TrendDirection.UP,
+                    i,
+                    initial_high_pos,
+                )
                 state = TrendDirection.DOWN
                 break
             elif is_initial_low_move_significant:
-                add_pivot(initial_low_pos, initial_low_log, TrendDirection.DOWN)
+                add_pivot(
+                    initial_low_pos,
+                    initial_low_log,
+                    TrendDirection.DOWN,
+                    i,
+                    initial_low_pos,
+                )
                 state = TrendDirection.UP
                 break
     else:
-        return (
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
-            [],
+        return ZigzagResult(
+            indices=[],
+            values_log=[],
+            directions=[],
+            amplitudes=[],
+            amplitude_threshold_ratios=[],
+            volume_rates=[],
+            speeds=[],
+            efficiency_ratios=[],
+            volume_weighted_efficiency_ratios=[],
+            known_at_positions=known_at_positions,
         )
 
     for i in range(last_pivot_pos + 1, n):
@@ -3271,6 +3503,8 @@ def zigzag(
                     candidate_pivot_pos,
                     highs_log[candidate_pivot_pos],
                     TrendDirection.UP,
+                    i,
+                    i,
                 )
                 state = TrendDirection.DOWN
 
@@ -3288,34 +3522,51 @@ def zigzag(
                     candidate_pivot_pos,
                     lows_log[candidate_pivot_pos],
                     TrendDirection.DOWN,
+                    i,
+                    i,
                 )
                 state = TrendDirection.UP
 
-    if normalize:
-        return (
-            pivots_indices,
-            pivots_values_log,
-            pivots_directions,
-            minmax_scale(pivots_amplitudes),
-            minmax_scale(pivots_amplitude_threshold_ratios),
-            minmax_scale(pivots_volume_rates),
-            minmax_scale(pivots_speeds),
-            pivots_efficiency_ratios,
-            pivots_volume_weighted_efficiency_ratios,
-        )
-    return (
-        pivots_indices,
-        pivots_values_log,
-        pivots_directions,
-        pivots_amplitudes,
-        pivots_amplitude_threshold_ratios,
-        pivots_volume_rates,
-        pivots_speeds,
-        pivots_efficiency_ratios,
-        pivots_volume_weighted_efficiency_ratios,
+    return ZigzagResult(
+        indices=pivots_indices,
+        values_log=pivots_values_log,
+        directions=pivots_directions,
+        amplitudes=(
+            minmax_scale(pivots_amplitudes) if normalize else pivots_amplitudes
+        ),
+        amplitude_threshold_ratios=(
+            minmax_scale(pivots_amplitude_threshold_ratios)
+            if normalize
+            else pivots_amplitude_threshold_ratios
+        ),
+        volume_rates=(
+            minmax_scale(pivots_volume_rates) if normalize else pivots_volume_rates
+        ),
+        speeds=minmax_scale(pivots_speeds) if normalize else pivots_speeds,
+        efficiency_ratios=pivots_efficiency_ratios,
+        volume_weighted_efficiency_ratios=pivots_volume_weighted_efficiency_ratios,
+        known_at_positions=known_at_positions,
     )
 
 
+def zigzag(
+    df: pd.DataFrame,
+    natr_period: int = 14,
+    natr_multiplier: float = 9.0,
+    normalize: bool = False,
+    *,
+    logger: Logger | None = None,
+) -> ZigzagTuple:
+    """Return Zigzag outputs while preserving the existing public API."""
+    return _zigzag(
+        df,
+        natr_period=natr_period,
+        natr_multiplier=natr_multiplier,
+        normalize=normalize,
+        logger=logger,
+    ).as_tuple()
+
+
 Regressor = Literal[
     "xgboost", "lightgbm", "histgradientboostingregressor", "ngboost", "catboost"
 ]