| 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`. |
+| freqai.label_prediction.keep_fraction | 0.005 | 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
self.assertEqual(DEFAULTS_LABEL_PIPELINE, before)
def test_a_flat_config_dict_is_read_as_the_default_block(self):
- # The regressor hands over whatever get_label_pipeline_config produced, which may carry
- # pipeline keys at the top level instead of under "default".
+ # Direct LabelTransformer callers may pass a flat pipeline configuration.
+ # The regressor instead passes the normalized "default"/"columns" mapping.
#
# A round trip alone is satisfied by ANY invertible pipeline, including one that
# ignores the flat dict entirely and falls back to `DEFAULTS_LABEL_PIPELINE`
import pandas as pd
import scipy as sp
from freqtrade.freqai.freqai_interface import IFreqaiModel
+from LabelTransformer import DEFAULTS_LABEL_PREDICTION
from qa_support import PAIR, QaTestCase
from Utils import _OPTUNA_NAMESPACES, DEFAULTS_LABEL_PIPELINE
model = regressor(
_fit_live_predictions_candles=candles if budget is None else budget,
label_prediction={
- "default": {
- "method": "thresholding",
- "selection_method": "rank_extrema",
- "threshold_method": "mean",
- "outlier_quantile": 0.999,
- "soft_extremum_alpha": 12.0,
- "keep_fraction": 0.0075,
- },
+ "default": dict(DEFAULTS_LABEL_PREDICTION),
"columns": {},
},
min_max_pred=lambda *args, **kwargs: (-0.4, 0.6),
# size 0 is the one case that may legitimately keep nothing, and keep_fraction
# does not force a candidate out of a set that does not exist.
self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(0, 1.0), 0)
- self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(0, 0.0075), 0)
+ self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(0, 0.005), 0)
def test_a_non_empty_extremum_set_always_keeps_at_least_one(self):
- for keep_fraction in (0.0, 0.0075, 0.5, 1.0):
+ for keep_fraction in (0.0, 0.005, 0.5, 1.0):
with self.subTest(keep_fraction=keep_fraction):
self.assertGreaterEqual(
QuickAdapterRegressorV3._calculate_n_kept_extrema(10, keep_fraction), 1
def test_the_kept_count_uses_banker_rounding_not_ceiling(self):
# round() is round-half-to-even: 133 * 0.5 == 66.5 keeps 66, not 67, and a
- # keep_fraction of 0.0075 over 133 extrema still keeps only the floor of one.
+ # keep_fraction of 0.005 over 133 extrema still keeps only the floor of one.
self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(133, 0.5), 66)
self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(3, 0.5), 2)
- self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(133, 0.0075), 1)
+ self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(133, 0.005), 1)
self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(10, 0.5), 5)
self.assertEqual(QuickAdapterRegressorV3._calculate_n_kept_extrema(10, 1.0), 10)
"label_prediction": {
"method": "thresholding",
"threshold_method": "isodata",
- "keep_fraction": 0.0075
+ "keep_fraction": 0.005
// Alternative per-label format: remove the sibling keys above, then uncomment:
// "default": {
// "method": "thresholding",
"""Chronological train/test split using sklearn's TimeSeriesSplit final fold.
``n_splits`` controls train/test proportions (higher = larger train).
- ``gap`` excludes samples between train and test; when 0, auto-derived
- from ``label_period_candles``. ``max_train_size`` enables sliding
- window mode. ``weights`` is sliced positionally via ``train_idx`` /
- ``test_idx``.
+ ``gap`` excludes samples between train and test. When 0, it uses the label
+ horizon in causal mode, otherwise ``label_period_candles``.
+ ``max_train_size`` enables sliding windows. ``weights`` is sliced
+ positionally via ``train_idx`` / ``test_idx``.
"""
feat_dict = self.ft_params
causal_mode = self._causal_mode
"threshold_method": SKIMAGE_THRESHOLD_METHODS[0], # "mean"
"outlier_quantile": 0.999,
"soft_extremum_alpha": 12.0,
- "keep_fraction": 0.0075,
+ "keep_fraction": 0.005,
}