From eaa3fb499546687757cae0da11f4a4fc37ce9442 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 30 May 2025 12:08:28 +0200 Subject: [PATCH] perf(qav3): tune SL/TP targets computation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../freqaimodels/QuickAdapterRegressorV3.py | 17 +++++++++-------- .../user_data/strategies/QuickAdapterV3.py | 6 +++--- quickadapter/user_data/strategies/Utils.py | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index a2bedc7..5e83b5e 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -471,10 +471,11 @@ class QuickAdapterRegressorV3(BaseRegressionModel): ) if np_weights.size != normalized_matrix.shape[1]: raise ValueError("label_weights length must match number of objectives") - label_knn_metric = self.ft_params.get("label_knn_metric", "euclidean") knn_kwargs = {} + label_knn_metric = self.ft_params.get("label_knn_metric", "euclidean") if label_knn_metric == "minkowski" and isinstance(label_p_order, float): knn_kwargs["p"] = label_p_order + ideal_point = np.ones(normalized_matrix.shape[1]) if metric in { @@ -587,22 +588,22 @@ class QuickAdapterRegressorV3(BaseRegressionModel): is_finite_mask = np.isfinite(current_column) - if is_finite_mask.any(): + if np.any(is_finite_mask): finite_col = current_column[is_finite_mask] finite_min_val = np.min(finite_col) finite_max_val = np.max(finite_col) finite_range_val = finite_max_val - finite_min_val if np.isclose(finite_range_val, 0): - if is_pos_inf_mask.any() and is_neg_inf_mask.any(): + if np.any(is_pos_inf_mask) and np.any(is_neg_inf_mask): normalized_matrix[is_finite_mask, i] = 0.5 - elif is_pos_inf_mask.any(): + elif np.any(is_pos_inf_mask): normalized_matrix[is_finite_mask, i] = ( 0.0 if current_direction == optuna.study.StudyDirection.MAXIMIZE else 1.0 ) - elif is_neg_inf_mask.any(): + elif np.any(is_neg_inf_mask): normalized_matrix[is_finite_mask, i] = ( 1.0 if current_direction == optuna.study.StudyDirection.MAXIMIZE @@ -1069,7 +1070,7 @@ def zigzag( natr_ratio: float = 6.0, ) -> tuple[list[int], list[float], list[int]]: min_confirmation_window: int = 2 - max_confirmation_window: int = 5 + max_confirmation_window: int = 6 n = len(df) if df.empty or n < max(natr_period, 2 * max_confirmation_window + 1): return [], [], [] @@ -1446,6 +1447,6 @@ def round_to_nearest_int(value: float, step: int) -> int: :return: The rounded value. :raises ValueError: If step is zero. """ - if step == 0: - raise ValueError("step must be non-zero") + if not isinstance(step, int) or step <= 0: + raise ValueError("step must be a positive integer") return int(round(value / step) * step) diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 7cdde08..fb22704 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -303,7 +303,7 @@ class QuickAdapterV3(IStrategy): dataframe["vwap_lowerband"], dataframe["vwap_middleband"], dataframe["vwap_upperband"], - ) = vwapb(dataframe, 20, 1) + ) = vwapb(dataframe, 20, 1.0) dataframe["%-vwap_width"] = ( dataframe["vwap_upperband"] - dataframe["vwap_lowerband"] ) / dataframe["vwap_middleband"] @@ -375,10 +375,10 @@ class QuickAdapterV3(IStrategy): return self.get_label_natr_ratio(pair) * 0.0125 def get_stoploss_natr_ratio(self, pair: str) -> float: - return self.get_label_natr_ratio(pair) * 0.95 + return self.get_label_natr_ratio(pair) * 0.9 def get_take_profit_natr_ratio(self, pair: str) -> float: - return self.get_label_natr_ratio(pair) * 0.75 + return self.get_label_natr_ratio(pair) * 0.7 def set_freqai_targets(self, dataframe: DataFrame, metadata: dict, **kwargs): pair = str(metadata.get("pair")) diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index 70b163c..31bd0cc 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -116,11 +116,11 @@ def price_retracement_percent(dataframe: pd.DataFrame, period: int) -> pd.Series # VWAP bands -def vwapb(dataframe: pd.DataFrame, window=20, num_of_std=1) -> tuple: +def vwapb(dataframe: pd.DataFrame, window: int = 20, std_factor: float = 1.0) -> tuple: vwap = qtpylib.rolling_vwap(dataframe, window=window) rolling_std = vwap.rolling(window=window, min_periods=window).std() - vwap_low = vwap - (rolling_std * num_of_std) - vwap_high = vwap + (rolling_std * num_of_std) + vwap_low = vwap - (rolling_std * std_factor) + vwap_high = vwap + (rolling_std * std_factor) return vwap_low, vwap, vwap_high @@ -360,7 +360,7 @@ def zigzag( natr_ratio: float = 6.0, ) -> tuple[list[int], list[float], list[int]]: min_confirmation_window: int = 2 - max_confirmation_window: int = 5 + max_confirmation_window: int = 6 n = len(df) if df.empty or n < max(natr_period, 2 * max_confirmation_window + 1): return [], [], [] -- 2.43.0