From a7432c9adcac1fe33fa21994bd6707c3b5779b42 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 1 May 2026 19:20:24 +0200 Subject: [PATCH] fix: ensure_datetime_series raises ValueError on None instead of silent corruption --- ReforceXY/user_data/strategies/RLAgentStrategy.py | 9 +++++++-- quickadapter/user_data/strategies/QuickAdapterV3.py | 2 +- quickadapter/user_data/strategies/Utils.py | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ReforceXY/user_data/strategies/RLAgentStrategy.py b/ReforceXY/user_data/strategies/RLAgentStrategy.py index 7cbe108..aa2efa9 100644 --- a/ReforceXY/user_data/strategies/RLAgentStrategy.py +++ b/ReforceXY/user_data/strategies/RLAgentStrategy.py @@ -23,8 +23,13 @@ _EPOCH_MS_MIN = 1_262_304_000_000 # 2010-01-01T00:00:00Z _EPOCH_MS_MAX = 2_051_222_400_000 # 2035-01-01T00:00:00Z -def _ensure_datetime_series(series: pd.Series) -> pd.Series: +def _ensure_datetime_series(series: pd.Series | None) -> pd.Series: """Ensure a date series is datetime64[ms, UTC], following freqtrade's data handler pattern.""" + if series is None: + raise ValueError( + "Expected a date Series but received None. " + "The 'date' column is missing from the dataframe." + ) if pd.api.types.is_integer_dtype(series): sample = series.dropna() if sample.empty: @@ -77,7 +82,7 @@ class RLAgentStrategy(IStrategy): def feature_engineering_standard( self, dataframe: DataFrame, metadata: dict[str, Any], **kwargs ) -> DataFrame: - dates = _ensure_datetime_series(dataframe["date"]) + dates = _ensure_datetime_series(dataframe.get("date")) dataframe["%-day_of_week"] = (dates.dt.dayofweek + 1) / 7 dataframe["%-hour_of_day"] = (dates.dt.hour + 1) / 25 diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 2d00ba2..87871e2 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -724,7 +724,7 @@ class QuickAdapterV3(IStrategy): def feature_engineering_standard( self, dataframe: DataFrame, metadata: dict[str, Any], **kwargs ) -> DataFrame: - dates = ensure_datetime_series(dataframe["date"]) + dates = ensure_datetime_series(dataframe.get("date")) dataframe["%-day_of_week"] = (dates.dt.dayofweek + 1) / 7 dataframe["%-hour_of_day"] = (dates.dt.hour + 1) / 25 diff --git a/quickadapter/user_data/strategies/Utils.py b/quickadapter/user_data/strategies/Utils.py index e794082..c5f8e74 100644 --- a/quickadapter/user_data/strategies/Utils.py +++ b/quickadapter/user_data/strategies/Utils.py @@ -649,8 +649,13 @@ _EPOCH_MS_MIN = 1_262_304_000_000 # 2010-01-01T00:00:00Z _EPOCH_MS_MAX = 2_051_222_400_000 # 2035-01-01T00:00:00Z -def ensure_datetime_series(series: pd.Series) -> pd.Series: +def ensure_datetime_series(series: pd.Series | None) -> pd.Series: """Ensure a date series is datetime64[ms, UTC], following freqtrade's data handler pattern.""" + if series is None: + raise ValueError( + "Expected a date Series but received None. " + "The 'date' column is missing from the dataframe." + ) if pd.api.types.is_integer_dtype(series): sample = series.dropna() if sample.empty: -- 2.53.0