### 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 | `moving_average` | enum {`moving_average`,`interpolation`,`weighted_interpolation`} | Trade NATR computation method. |
-| exit_pricing.thresholds_calibration.decline_quantile | 0.90 | float (0,1) | PnL decline quantile threshold. |
-| _Reversal confirmation_ | | | |
-| reversal_confirmation.lookback_period | 0 | int >= 0 | Prior confirming candles; 0 = none. |
-| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle volatility adjusted reversal threshold relaxation factor. |
-| reversal_confirmation.min_natr_ratio_percent | 0.0095 | float [0,1] | Lower bound fraction for volatility adjusted reversal threshold. |
-| reversal_confirmation.max_natr_ratio_percent | 0.075 | float [0,1] | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold. |
-| _Regressor model_ | | | |
-| freqai.regressor | `xgboost` | enum {`xgboost`,`lightgbm`} | Machine learning regressor algorithm. |
-| _Extrema smoothing_ | | | |
-| freqai.extrema_smoothing.method | `gaussian` | enum {`gaussian`,`kaiser`,`triang`,`smm`,`sma`,`savgol`,`nadaraya_watson`} | Extrema smoothing method (`smm`=median, `sma`=mean, `savgol`=Savitzky–Golay, `nadaraya_watson`=Gaussian kernel regression). |
-| freqai.extrema_smoothing.window | 5 | int >= 3 | Smoothing window length (candles). |
-| freqai.extrema_smoothing.beta | 8.0 | float > 0 | Shape parameter for `kaiser` kernel. |
-| freqai.extrema_smoothing.polyorder | 3 | int >= 1 | Polynomial order for `savgol` smoothing. |
-| freqai.extrema_smoothing.mode | `mirror` | enum {`mirror`,`constant`,`nearest`,`wrap`,`interp`} | Boundary mode for `savgol` and `nadaraya_watson`. |
-| freqai.extrema_smoothing.bandwidth | 1.0 | float > 0 | Gaussian bandwidth for `nadaraya_watson`. |
-| _Extrema weighting_ | | | |
-| freqai.extrema_weighting.strategy | `none` | enum {`none`,`amplitude`,`amplitude_threshold_ratio`,`volume`} | Extrema weighting source: unweighted (`none`), swing amplitude (`amplitude`), swing amplitude / median volatility-threshold ratio (`amplitude_threshold_ratio`), or swing volume (`volume`). |
-| freqai.extrema_weighting.standardization | `none` | enum {`none`,`zscore`,`robust`,`mmad`} | Standardization method applied before normalization. `none`=no standardization, `zscore`=(w-μ)/σ, `robust`=(w-median)/IQR, `mmad`=(w-median)/MAD. |
-| freqai.extrema_weighting.robust_quantiles | [0.25, 0.75] | list[float] where 0 <= Q1 < Q3 <= 1 | Quantile range for robust standardization, Q1 and Q3. |
-| freqai.extrema_weighting.mmad_scaling_factor | 1.4826 | float > 0 | Scaling factor for MMAD standardization. |
-| freqai.extrema_weighting.normalization | `minmax` | enum {`minmax`,`sigmoid`,`softmax`,`l1`,`l2`,`rank`,`none`} | Normalization method for weights. |
-| freqai.extrema_weighting.minmax_range | [0.0, 1.0] | list[float] | Target range for `minmax` normalization, min and max. |
-| freqai.extrema_weighting.sigmoid_scale | 1.0 | float > 0 | Scale parameter for `sigmoid` normalization, controls steepness. |
-| freqai.extrema_weighting.softmax_temperature | 1.0 | float > 0 | Temperature parameter for `softmax` normalization: lower values sharpen distribution, higher values flatten it. |
-| freqai.extrema_weighting.rank_method | `average` | enum {`average`,`min`,`max`,`dense`,`ordinal`} | Ranking method for `rank` normalization. |
-| freqai.extrema_weighting.gamma | 1.0 | float (0,10] | Contrast exponent applied 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 horizon. |
-| freqai.feature_parameters.min_label_period_candles | 12 | int >= 1 | Minimum labeling NATR horizon used for reversals labeling HPO. |
-| freqai.feature_parameters.max_label_period_candles | 24 | int >= 1 | Maximum labeling NATR horizon used for reversals labeling HPO. |
-| freqai.feature_parameters.label_natr_ratio | min/max midpoint | float > 0 | Zigzag labeling NATR ratio. |
-| freqai.feature_parameters.min_label_natr_ratio | 9.0 | float > 0 | Minimum labeling NATR ratio used for reversals labeling HPO. |
-| freqai.feature_parameters.max_label_natr_ratio | 12.0 | float > 0 | Maximum labeling NATR ratio used for reversals labeling HPO. |
-| freqai.feature_parameters.label_frequency_candles | `auto` | int >= 2 \| `auto` | Reversals labeling frequency. `auto` = max(2, 2 \* number of whitelisted pairs). |
-| freqai.feature_parameters.label_metric | `euclidean` | string (supported: `euclidean`,`minkowski`,`cityblock`,`chebyshev`,`mahalanobis`,`seuclidean`,`jensenshannon`,`sqeuclidean`,...) | Metric used in distance calculations to ideal point. |
-| freqai.feature_parameters.label_weights | [1/4,1/4,1/4,1/4] | list[float] | Per-objective weights used in distance calculations to ideal point. Objectives: (1) number of detected reversals, (2) median swing amplitude, (3) median swing amplitude / median volatility-threshold ratio, (4) median swing volume. |
-| freqai.feature_parameters.label_p_order | `None` | float \| None | p-order used by `minkowski` / `power_mean` (optional). |
-| freqai.feature_parameters.label_medoid_metric | `euclidean` | string | Metric used with `medoid`. |
-| freqai.feature_parameters.label_kmeans_metric | `euclidean` | string | Metric used for k-means clustering. |
-| freqai.feature_parameters.label_kmeans_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best kmeans cluster. |
-| freqai.feature_parameters.label_kmedoids_metric | `euclidean` | string | Metric used for k-medoids clustering. |
-| freqai.feature_parameters.label_kmedoids_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best k-medoids cluster. |
-| freqai.feature_parameters.label_knn_metric | `minkowski` | string | Distance metric for KNN. |
-| freqai.feature_parameters.label_knn_p_order | `None` | float \| None | Tunable for KNN neighbor distances aggregation methods: p-order (`knn_power_mean`, default: 1.0) or quantile (`knn_quantile`, default: 0.5). (optional) |
-| freqai.feature_parameters.label_knn_n_neighbors | 5 | int >= 1 | Number of neighbors for KNN. |
-| _Predictions extrema_ | | | |
-| freqai.predictions_extrema.selection_method | `rank` | enum {`rank`,`values`,`partition`} | Extrema selection method. `values` uses reversal values, `rank` uses ranked extrema values, `partition` uses sign-based partitioning. |
-| freqai.predictions_extrema.thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`soft_extremum`} | Thresholding method for prediction thresholds smoothing. |
-| freqai.predictions_extrema.thresholds_alpha | 12.0 | float > 0 | Alpha for `soft_extremum`. |
-| freqai.predictions_extrema.threshold_outlier | 0.999 | float (0,1) | Quantile threshold for predictions outlier filtering. |
-| freqai.predictions_extrema.extrema_fraction | 1.0 | float (0,1] | Fraction of extrema used for thresholds. `1.0` uses all, lower values keep only most significant. Applies to `rank` and `values`; ignored for `partition`. |
-| _Optuna / HPO_ | | | |
-| freqai.optuna_hyperopt.enabled | true | bool | Enables HPO. |
-| freqai.optuna_hyperopt.sampler | `tpe` | enum {`tpe`,`auto`} | HPO sampler algorithm. `tpe` uses [TPESampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.TPESampler.html) with multivariate and group, `auto` uses [AutoSampler](https://hub.optuna.org/samplers/auto_sampler). |
-| freqai.optuna_hyperopt.storage | `file` | enum {`file`,`sqlite`} | HPO storage backend. |
-| freqai.optuna_hyperopt.continuous | true | bool | Continuous HPO. |
-| freqai.optuna_hyperopt.warm_start | true | bool | Warm start HPO with previous best value(s). |
-| freqai.optuna_hyperopt.n_startup_trials | 15 | int >= 0 | HPO startup trials. |
-| freqai.optuna_hyperopt.n_trials | 50 | int >= 1 | Maximum HPO trials. |
-| freqai.optuna_hyperopt.n_jobs | CPU threads / 4 | int >= 1 | Parallel HPO workers. |
-| freqai.optuna_hyperopt.timeout | 7200 | int >= 0 | HPO wall-clock timeout in seconds. |
-| freqai.optuna_hyperopt.label_candles_step | 1 | int >= 1 | Step for Zigzag NATR horizon search space. |
-| freqai.optuna_hyperopt.train_candles_step | 10 | int >= 1 | Step for training sets size search space. |
-| freqai.optuna_hyperopt.space_reduction | false | bool | Enable/disable HPO search space reduction based on previous best parameters. |
-| freqai.optuna_hyperopt.expansion_ratio | 0.4 | float [0,1] | HPO search space expansion ratio. |
-| freqai.optuna_hyperopt.min_resource | 3 | int >= 1 | Minimum resource per Hyperband pruner rung. |
-| freqai.optuna_hyperopt.seed | 1 | int >= 0 | HPO RNG seed. |
+| Path | Default | Type / Range | Description |
+| ---------------------------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| _Protections_ | | | |
+| 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 | `moving_average` | enum {`moving_average`,`interpolation`,`weighted_interpolation`} | Trade NATR computation method. |
+| exit_pricing.thresholds_calibration.decline_quantile | 0.90 | float (0,1) | PnL decline quantile threshold. |
+| _Reversal confirmation_ | | | |
+| reversal_confirmation.lookback_period | 0 | int >= 0 | Prior confirming candles; 0 = none. |
+| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle volatility adjusted reversal threshold relaxation factor. |
+| reversal_confirmation.min_natr_ratio_percent | 0.0095 | float [0,1] | Lower bound fraction for volatility adjusted reversal threshold. |
+| reversal_confirmation.max_natr_ratio_percent | 0.075 | float [0,1] | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold. |
+| _Regressor model_ | | | |
+| freqai.regressor | `xgboost` | enum {`xgboost`,`lightgbm`} | Machine learning regressor algorithm. |
+| _Extrema smoothing_ | | | |
+| freqai.extrema_smoothing.method | `gaussian` | enum {`gaussian`,`kaiser`,`triang`,`smm`,`sma`,`savgol`,`nadaraya_watson`} | Extrema smoothing method (`smm`=median, `sma`=mean, `savgol`=Savitzky–Golay, `nadaraya_watson`=Gaussian kernel regression). |
+| freqai.extrema_smoothing.window | 5 | int >= 3 | Smoothing window length (candles). |
+| freqai.extrema_smoothing.beta | 8.0 | float > 0 | Shape parameter for `kaiser` kernel. |
+| freqai.extrema_smoothing.polyorder | 3 | int >= 1 | Polynomial order for `savgol` smoothing. |
+| freqai.extrema_smoothing.mode | `mirror` | enum {`mirror`,`constant`,`nearest`,`wrap`,`interp`} | Boundary mode for `savgol` and `nadaraya_watson`. |
+| freqai.extrema_smoothing.bandwidth | 1.0 | float > 0 | Gaussian bandwidth for `nadaraya_watson`. |
+| _Extrema weighting_ | | | |
+| freqai.extrema_weighting.strategy | `none` | enum {`none`,`amplitude`,`amplitude_threshold_ratio`,`volume`,`speed`,`efficiency_ratio`} | Extrema weighting source: unweighted (`none`), swing amplitude (`amplitude`), swing amplitude / median volatility-threshold ratio (`amplitude_threshold_ratio`), swing volume (`volume`), swing speed (`speed`), or swing efficiency ratio (`efficiency_ratio`). |
+| freqai.extrema_weighting.standardization | `none` | enum {`none`,`zscore`,`robust`,`mmad`} | Standardization method applied before normalization. `none`=no standardization, `zscore`=(w-μ)/σ, `robust`=(w-median)/IQR, `mmad`=(w-median)/MAD. |
+| freqai.extrema_weighting.robust_quantiles | [0.25, 0.75] | list[float] where 0 <= Q1 < Q3 <= 1 | Quantile range for robust standardization, Q1 and Q3. |
+| freqai.extrema_weighting.mmad_scaling_factor | 1.4826 | float > 0 | Scaling factor for MMAD standardization. |
+| freqai.extrema_weighting.normalization | `minmax` | enum {`minmax`,`sigmoid`,`softmax`,`l1`,`l2`,`rank`,`none`} | Normalization method for weights. |
+| freqai.extrema_weighting.minmax_range | [0.0, 1.0] | list[float] | Target range for `minmax` normalization, min and max. |
+| freqai.extrema_weighting.sigmoid_scale | 1.0 | float > 0 | Scale parameter for `sigmoid` normalization, controls steepness. |
+| freqai.extrema_weighting.softmax_temperature | 1.0 | float > 0 | Temperature parameter for `softmax` normalization: lower values sharpen distribution, higher values flatten it. |
+| freqai.extrema_weighting.rank_method | `average` | enum {`average`,`min`,`max`,`dense`,`ordinal`} | Ranking method for `rank` normalization. |
+| freqai.extrema_weighting.gamma | 1.0 | float (0,10] | Contrast exponent applied 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 horizon. |
+| freqai.feature_parameters.min_label_period_candles | 12 | int >= 1 | Minimum labeling NATR horizon used for reversals labeling HPO. |
+| freqai.feature_parameters.max_label_period_candles | 24 | int >= 1 | Maximum labeling NATR horizon used for reversals labeling HPO. |
+| freqai.feature_parameters.label_natr_ratio | min/max midpoint | float > 0 | Zigzag labeling NATR ratio. |
+| freqai.feature_parameters.min_label_natr_ratio | 9.0 | float > 0 | Minimum labeling NATR ratio used for reversals labeling HPO. |
+| freqai.feature_parameters.max_label_natr_ratio | 12.0 | float > 0 | Maximum labeling NATR ratio used for reversals labeling HPO. |
+| freqai.feature_parameters.label_frequency_candles | `auto` | int >= 2 \| `auto` | Reversals labeling frequency. `auto` = max(2, 2 \* number of whitelisted pairs). |
+| freqai.feature_parameters.label_metric | `euclidean` | string (supported: `euclidean`,`minkowski`,`cityblock`,`chebyshev`,`mahalanobis`,`seuclidean`,`jensenshannon`,`sqeuclidean`,...) | Metric used in distance calculations to ideal point. |
+| freqai.feature_parameters.label_weights | [1/6,1/6,1/6,1/6,1/6,1/6] | list[float] | Per-objective weights used in distance calculations to ideal point. Objectives: (1) number of detected reversals, (2) median swing amplitude, (3) median swing amplitude / median volatility-threshold ratio, (4) median swing volume, (5) median swing speed, (6) median swing efficiency ratio. |
+| freqai.feature_parameters.label_p_order | `None` | float \| None | p-order used by `minkowski` / `power_mean` (optional). |
+| freqai.feature_parameters.label_medoid_metric | `euclidean` | string | Metric used with `medoid`. |
+| freqai.feature_parameters.label_kmeans_metric | `euclidean` | string | Metric used for k-means clustering. |
+| freqai.feature_parameters.label_kmeans_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best kmeans cluster. |
+| freqai.feature_parameters.label_kmedoids_metric | `euclidean` | string | Metric used for k-medoids clustering. |
+| freqai.feature_parameters.label_kmedoids_selection | `min` | enum {`min`,`medoid`} | Strategy to select trial in the best k-medoids cluster. |
+| freqai.feature_parameters.label_knn_metric | `minkowski` | string | Distance metric for KNN. |
+| freqai.feature_parameters.label_knn_p_order | `None` | float \| None | Tunable for KNN neighbor distances aggregation methods: p-order (`knn_power_mean`, default: 1.0) or quantile (`knn_quantile`, default: 0.5). (optional) |
+| freqai.feature_parameters.label_knn_n_neighbors | 5 | int >= 1 | Number of neighbors for KNN. |
+| _Predictions extrema_ | | | |
+| freqai.predictions_extrema.selection_method | `rank` | enum {`rank`,`values`,`partition`} | Extrema selection method. `values` uses reversal values, `rank` uses ranked extrema values, `partition` uses sign-based partitioning. |
+| freqai.predictions_extrema.thresholds_smoothing | `mean` | enum {`mean`,`isodata`,`li`,`minimum`,`otsu`,`triangle`,`yen`,`median`,`soft_extremum`} | Thresholding method for prediction thresholds smoothing. |
+| freqai.predictions_extrema.thresholds_alpha | 12.0 | float > 0 | Alpha for `soft_extremum`. |
+| freqai.predictions_extrema.threshold_outlier | 0.999 | float (0,1) | Quantile threshold for predictions outlier filtering. |
+| freqai.predictions_extrema.extrema_fraction | 1.0 | float (0,1] | Fraction of extrema used for thresholds. `1.0` uses all, lower values keep only most significant. Applies to `rank` and `values`; ignored for `partition`. |
+| _Optuna / HPO_ | | | |
+| freqai.optuna_hyperopt.enabled | true | bool | Enables HPO. |
+| freqai.optuna_hyperopt.sampler | `tpe` | enum {`tpe`,`auto`} | HPO sampler algorithm. `tpe` uses [TPESampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.TPESampler.html) with multivariate and group, `auto` uses [AutoSampler](https://hub.optuna.org/samplers/auto_sampler). |
+| freqai.optuna_hyperopt.storage | `file` | enum {`file`,`sqlite`} | HPO storage backend. |
+| freqai.optuna_hyperopt.continuous | true | bool | Continuous HPO. |
+| freqai.optuna_hyperopt.warm_start | true | bool | Warm start HPO with previous best value(s). |
+| freqai.optuna_hyperopt.n_startup_trials | 15 | int >= 0 | HPO startup trials. |
+| freqai.optuna_hyperopt.n_trials | 50 | int >= 1 | Maximum HPO trials. |
+| freqai.optuna_hyperopt.n_jobs | CPU threads / 4 | int >= 1 | Parallel HPO workers. |
+| freqai.optuna_hyperopt.timeout | 7200 | int >= 0 | HPO wall-clock timeout in seconds. |
+| freqai.optuna_hyperopt.label_candles_step | 1 | int >= 1 | Step for Zigzag NATR horizon search space. |
+| freqai.optuna_hyperopt.train_candles_step | 10 | int >= 1 | Step for training sets size search space. |
+| freqai.optuna_hyperopt.space_reduction | false | bool | Enable/disable HPO search space reduction based on previous best parameters. |
+| freqai.optuna_hyperopt.expansion_ratio | 0.4 | float [0,1] | HPO search space expansion ratio. |
+| freqai.optuna_hyperopt.min_resource | 3 | int >= 1 | Minimum resource per Hyperband pruner rung. |
+| freqai.optuna_hyperopt.seed | 1 | int >= 0 | HPO RNG seed. |
## ReforceXY
https://github.com/sponsors/robcaulk
"""
- version = "3.7.128"
+ version = "3.7.129"
_SQRT_2: Final[float] = np.sqrt(2.0)
for pair in self.pairs:
self._optuna_hp_value[pair] = -1
self._optuna_train_value[pair] = -1
- self._optuna_label_values[pair] = [-1, -1, -1, -1]
+ self._optuna_label_values[pair] = [-1, -1, -1, -1, -1, -1]
self._optuna_hp_params[pair] = (
self.optuna_load_best_params(
pair, QuickAdapterRegressorV3._OPTUNA_NAMESPACES[0]
optuna.study.StudyDirection.MAXIMIZE,
optuna.study.StudyDirection.MAXIMIZE,
optuna.study.StudyDirection.MAXIMIZE,
+ optuna.study.StudyDirection.MAXIMIZE,
+ optuna.study.StudyDirection.MAXIMIZE,
],
),
)
max_label_period_candles: int = 24,
min_label_natr_ratio: float = 9.0,
max_label_natr_ratio: float = 12.0,
-) -> tuple[int, float, float, float]:
+) -> tuple[int, float, float, float, float, float]:
min_label_period_candles, max_label_period_candles, candles_step = (
get_min_max_label_period_candles(
fit_live_predictions_candles,
]
if df.empty:
- return 0, 0.0, 0.0, 0.0
+ return 0, 0.0, 0.0, 0.0, 0.0, 0.0
(
_,
pivots_amplitudes,
pivots_amplitude_threshold_ratios,
pivots_volumes,
+ _,
+ pivots_speeds,
+ pivots_efficiency_ratios,
) = zigzag(
df,
natr_period=label_period_candles,
median_amplitude = np.nanmedian(np.asarray(pivots_amplitudes, dtype=float))
if not np.isfinite(median_amplitude):
median_amplitude = 0.0
+
median_amplitude_threshold_ratio = np.nanmedian(
np.asarray(pivots_amplitude_threshold_ratios, dtype=float)
)
if not np.isfinite(median_amplitude_threshold_ratio):
median_amplitude_threshold_ratio = 0.0
+
median_volume = np.nanmedian(np.asarray(pivots_volumes, dtype=float))
if not np.isfinite(median_volume):
median_volume = 0.0
+ median_speed = np.nanmedian(np.asarray(pivots_speeds, dtype=float))
+ if not np.isfinite(median_speed):
+ median_speed = 0.0
+
+ median_efficiency_ratio = np.nanmedian(
+ np.asarray(pivots_efficiency_ratios, dtype=float)
+ )
+ if not np.isfinite(median_efficiency_ratio):
+ median_efficiency_ratio = 0.0
+
return (
len(pivots_values),
median_amplitude,
median_amplitude_threshold_ratio,
median_volume,
+ median_speed,
+ median_efficiency_ratio,
)
"amplitude",
"amplitude_threshold_ratio",
"volume",
+ "speed",
+ "efficiency_ratio",
]
WEIGHT_STRATEGIES: Final[tuple[WeightStrategy, ...]] = (
"none",
"amplitude",
"amplitude_threshold_ratio",
"volume",
+ "speed",
+ "efficiency_ratio",
)
EXTREMA_COLUMN: Final = "&s-extrema"
extrema: Extrema series
indices: Indices of extrema points
weights: Raw weights for each extremum
- strategy: Weight strategy ("none", "amplitude", "amplitude_threshold_ratio", "volume")
+ strategy: Weight strategy ("none", "amplitude", "amplitude_threshold_ratio", "volume", "speed", "efficiency_ratio")
standardization: Standardization method
robust_quantiles: Quantiles for robust standardization
mmad_scaling_factor: Scaling factor for MMAD standardization
): # "none"
return extrema, default_weights
- if strategy in {
- WEIGHT_STRATEGIES[1],
- WEIGHT_STRATEGIES[2],
- WEIGHT_STRATEGIES[3],
- }: # "amplitude" / "amplitude_threshold_ratio" / "volume"
+ if (
+ strategy
+ in {
+ WEIGHT_STRATEGIES[1],
+ WEIGHT_STRATEGIES[2],
+ WEIGHT_STRATEGIES[3],
+ WEIGHT_STRATEGIES[4],
+ WEIGHT_STRATEGIES[5],
+ }
+ ): # "amplitude" / "amplitude_threshold_ratio" / "volume" / "speed" / "efficiency_ratio"
extrema_weights = calculate_extrema_weights(
series=extrema,
indices=indices,
list[float],
list[float],
list[float],
+ list[float],
+ list[float],
+ list[float],
]:
n = len(df)
if df.empty or n < natr_period:
[],
[],
[],
+ [],
+ [],
+ [],
)
natr_values = (ta.NATR(df, timeperiod=natr_period).bfill() / 100.0).to_numpy()
pivots_amplitudes: list[float] = []
pivots_amplitude_threshold_ratios: list[float] = []
pivots_volumes: list[float] = []
+ pivots_durations: list[float] = []
+ pivots_speeds: list[float] = []
+ pivots_efficiency_ratios: list[float] = []
last_pivot_pos: int = -1
candidate_pivot_pos: int = -1
start_pos = min(previous_pos, current_pos)
end_pos = max(previous_pos, current_pos) + 1
- volume = np.nansum(volumes[start_pos:end_pos])
- return volume
+ return np.nansum(volumes[start_pos:end_pos])
+
+ def calculate_pivot_duration(
+ *,
+ previous_pos: int,
+ current_pos: int,
+ ) -> float:
+ if previous_pos < 0 or current_pos < 0:
+ return np.nan
+ if previous_pos >= n or current_pos >= n:
+ return np.nan
+
+ return abs(current_pos - previous_pos)
+
+ def calculate_pivot_efficiency_ratio(
+ *,
+ previous_pos: int,
+ current_pos: int,
+ ) -> float:
+ if previous_pos < 0 or current_pos < 0:
+ return np.nan
+ if previous_pos >= n or current_pos >= n:
+ return np.nan
+
+ start_pos = min(previous_pos, current_pos)
+ end_pos = max(previous_pos, current_pos) + 1
+ if (end_pos - start_pos) < 2:
+ return np.nan
+
+ closes_slice = closes[start_pos:end_pos]
+ close_diffs = np.diff(closes_slice)
+ path_length = float(np.nansum(np.abs(close_diffs)))
+ net_move = float(abs(closes_slice[-1] - closes_slice[0]))
+
+ if not (np.isfinite(path_length) and np.isfinite(net_move)):
+ return np.nan
+ if np.isclose(path_length, 0.0):
+ return np.nan
+
+ return net_move / path_length
def add_pivot(pos: int, value: float, direction: TrendDirection):
nonlocal last_pivot_pos
previous_pos=last_pivot_pos,
current_pos=pos,
)
+ duration = calculate_pivot_duration(
+ previous_pos=last_pivot_pos,
+ current_pos=pos,
+ )
+ if np.isfinite(amplitude) and np.isfinite(duration) and duration > 0.0:
+ speed = amplitude / duration
+ else:
+ speed = np.nan
+ efficiency_ratio = calculate_pivot_efficiency_ratio(
+ previous_pos=last_pivot_pos,
+ current_pos=pos,
+ )
else:
amplitude = np.nan
amplitude_threshold_ratio = np.nan
volume = np.nan
+ duration = np.nan
+ speed = np.nan
+ efficiency_ratio = np.nan
pivots_amplitudes.append(amplitude)
pivots_amplitude_threshold_ratios.append(amplitude_threshold_ratio)
pivots_volumes.append(volume)
+ pivots_durations.append(duration)
+ pivots_speeds.append(speed)
+ pivots_efficiency_ratios.append(efficiency_ratio)
last_pivot_pos = pos
reset_candidate_pivot()
[],
[],
[],
+ [],
+ [],
+ [],
)
for i in range(last_pivot_pos + 1, n):
pivots_amplitudes,
pivots_amplitude_threshold_ratios,
pivots_volumes,
+ pivots_durations,
+ pivots_speeds,
+ pivots_efficiency_ratios,
)