From: Jérôme Benoit Date: Mon, 25 May 2026 00:45:18 +0000 (+0200) Subject: fix(weights): guard DI_values None and read label_frequency_candles from freqai_info X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=b4950444cd9484a5191713e09160a8c238bb5d0e;p=freqai-strategies.git fix(weights): guard DI_values None and read label_frequency_candles from freqai_info - fit_live_predictions: pred_df.get('DI_values') returns None when feature_parameters.DI_threshold is 0 or absent (the default), causing AttributeError on the subsequent .mean()/.std() calls. Fall back to zeros instead. - _label_frequency_candles: read from self.freqai_info['feature_parameters'] (matching every other access in the file) instead of self.config, which is the top-level config dict and never contains feature_parameters directly. The previous code silently ignored user-provided values and always fell back to the default 'max(2, 2 * len(self.pairs))'. --- diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index c1a74a9..51488c9 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -872,9 +872,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): def _label_frequency_candles(self) -> int: default_label_frequency_candles = max(2, 2 * len(self.pairs)) - label_frequency_candles = self.config.get("feature_parameters", {}).get( - "label_frequency_candles" - ) + label_frequency_candles = self.ft_params.get("label_frequency_candles") if label_frequency_candles is None: label_frequency_candles = default_label_frequency_candles @@ -1431,7 +1429,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): Per-row sample weights are sliced positionally and propagate to both train and test sets. """ - feat_dict = self.freqai_info.get("feature_parameters", {}) + feat_dict = self.ft_params dsp = dict(self.data_split_parameters) dsp.setdefault("shuffle", False) dsp.setdefault("test_size", QuickAdapterRegressorV3._TEST_SIZE) @@ -1552,7 +1550,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): f"diverged from freqtrade's runtime label list" ) n_rows = len(features_filtered) - feat_dict = self.freqai_info.get("feature_parameters", {}) + feat_dict = self.ft_params weight_factor = feat_dict.get("weight_factor", 0) if ( not isinstance(weight_factor, bool) @@ -1738,7 +1736,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): :param dk: FreqaiDataKitchen instance for data building :return: data_dictionary with train/test features/labels/weights """ - feat_dict = self.freqai_info.get("feature_parameters", {}) + feat_dict = self.ft_params if feat_dict.get("shuffle_after_split", False): raise ValueError( "feature_parameters.shuffle_after_split=True is incompatible " @@ -2026,8 +2024,12 @@ class QuickAdapterRegressorV3(BaseRegressionModel): ) di_values = pred_df.get("DI_values") - dk.data["DI_value_mean"] = di_values.mean() - dk.data["DI_value_std"] = di_values.std(ddof=1) + if di_values is not None: + dk.data["DI_value_mean"] = di_values.mean() + dk.data["DI_value_std"] = di_values.std(ddof=1) + else: + dk.data["DI_value_mean"] = 0.0 + dk.data["DI_value_std"] = 0.0 label_prediction = self.label_prediction for label_col in dk.label_list: