From a8bb5b90c704445cb7ec370f75e989bb9d69a8a2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 21 Sep 2025 12:09:35 +0200 Subject: [PATCH] fix: ensure std on samples apply Bessel correction MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- ReforceXY/user_data/freqaimodels/ReforceXY.py | 63 +++++++++++++++---- .../freqaimodels/QuickAdapterRegressorV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 2 +- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/ReforceXY/user_data/freqaimodels/ReforceXY.py b/ReforceXY/user_data/freqaimodels/ReforceXY.py index 67e6fca..dedd96d 100644 --- a/ReforceXY/user_data/freqaimodels/ReforceXY.py +++ b/ReforceXY/user_data/freqaimodels/ReforceXY.py @@ -1971,11 +1971,10 @@ class InfoMetricsCallback(TensorboardCallback): for k, values in numeric_acc.items(): if not values: continue - mean = np.mean(values) - aggregated_info[k] = mean + aggregated_info[k] = np.mean(values) if len(values) > 1: try: - aggregated_info[f"{k}_std"] = np.std(values) + aggregated_info[f"{k}_std"] = np.std(values, ddof=1) except Exception: pass @@ -2011,7 +2010,12 @@ class InfoMetricsCallback(TensorboardCallback): try: self.logger.record("info/n_envs", int(len(infos_list))) except Exception: - pass + try: + self.logger.record( + "info/n_envs", int(len(infos_list)), exclude=("tensorboard",) + ) + except Exception: + pass if filtered_values > 0: try: @@ -2127,18 +2131,18 @@ class InfoMetricsCallback(TensorboardCallback): category, {} ).get(metric) if isinstance(value, (int, float)) and count and count > 0: - mean = float(value) / float(count) - self.logger.record(f"{category}/{metric}_mean", mean) + self.logger.record( + f"{category}/{metric}_mean", float(value) / float(count) + ) except Exception: try: count = aggregated_tensorboard_metric_counts.get( category, {} ).get(metric) if isinstance(value, (int, float)) and count and count > 0: - mean = float(value) / float(count) self.logger.record( f"{category}/{metric}_mean", - mean, + float(value) / float(count), exclude=("tensorboard",), ) except Exception: @@ -2152,8 +2156,23 @@ class InfoMetricsCallback(TensorboardCallback): else: progress_done = 0.0 progress_remaining = 1.0 - progress_done - self.logger.record("train/progress_done", progress_done) - self.logger.record("train/progress_remaining", progress_remaining) + try: + self.logger.record("train/progress_done", progress_done) + self.logger.record("train/progress_remaining", progress_remaining) + except Exception: + try: + self.logger.record( + "train/progress_done", + progress_done, + exclude=("tensorboard",), + ) + self.logger.record( + "train/progress_remaining", + progress_remaining, + exclude=("tensorboard",), + ) + except Exception: + pass except Exception: progress_remaining = 1.0 @@ -2162,7 +2181,17 @@ class InfoMetricsCallback(TensorboardCallback): if callable(lr): lr = lr(progress_remaining) if isinstance(lr, (int, float)) and np.isfinite(lr): - self.logger.record("train/learning_rate", float(lr)) + try: + self.logger.record("train/learning_rate", float(lr)) + except Exception: + try: + self.logger.record( + "train/learning_rate", + float(lr), + exclude=("tensorboard",), + ) + except Exception: + pass except Exception: pass @@ -2172,7 +2201,17 @@ class InfoMetricsCallback(TensorboardCallback): if callable(cr): cr = cr(progress_remaining) if isinstance(cr, (int, float)) and np.isfinite(cr): - self.logger.record("train/clip_range", float(cr)) + try: + self.logger.record("train/clip_range", float(cr)) + except Exception: + try: + self.logger.record( + "train/clip_range", + float(cr), + exclude=("tensorboard",), + ) + except Exception: + pass except Exception: pass diff --git a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py index 96a249f..79cc03a 100644 --- a/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py +++ b/quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py @@ -503,7 +503,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel): ) dk.data["DI_value_mean"] = di_values.mean() - dk.data["DI_value_std"] = di_values.std() + dk.data["DI_value_std"] = di_values.std(ddof=1) dk.data["extra_returns_per_train"]["DI_value_param1"] = f[0] dk.data["extra_returns_per_train"]["DI_value_param2"] = f[1] dk.data["extra_returns_per_train"]["DI_value_param3"] = f[2] diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index ddade7f..f50bc3e 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -222,7 +222,7 @@ def vwapb( dataframe: pd.DataFrame, window: int = 20, std_factor: float = 1.0 ) -> tuple[pd.Series, pd.Series, pd.Series]: vwap = qtpylib.rolling_vwap(dataframe, window=window) - rolling_std = vwap.rolling(window=window, min_periods=window).std() + rolling_std = vwap.rolling(window=window, min_periods=window).std(ddof=1) vwap_low = vwap - (rolling_std * std_factor) vwap_high = vwap + (rolling_std * std_factor) return vwap_low, vwap, vwap_high -- 2.43.0