]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor: extract ensure_datetime_series helper for date dtype workaround
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 30 Apr 2026 22:51:29 +0000 (00:51 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 30 Apr 2026 22:51:29 +0000 (00:51 +0200)
Centralizes the int64 epoch-ms vs datetime detection logic into a shared
helper. Handles both formats correctly: unit='ms' for int64, passthrough
for existing datetime columns.

Ref: https://github.com/freqtrade/freqtrade/issues/13107

ReforceXY/user_data/strategies/RLAgentStrategy.py
quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 815e5a14609436ffcdce2c396c1c65872f6f661c..d47f7555ac8b5a921cf87081ab34617ecaf62f99 100644 (file)
@@ -5,6 +5,7 @@ from typing import Any, Final, Literal, Optional
 
 import numpy as np
 import pandas as pd
+
 # import talib.abstract as ta
 from freqtrade.persistence import Trade
 from freqtrade.strategy import IStrategy
@@ -18,6 +19,12 @@ logger = logging.getLogger(__name__)
 ACTION_COLUMN: Final = "&-action"
 
 
+def _ensure_datetime_series(series: pd.Series) -> pd.Series:
+    if pd.api.types.is_integer_dtype(series):
+        return pd.to_datetime(series, unit="ms", utc=True)
+    return pd.to_datetime(series, utc=True)
+
+
 class RLAgentStrategy(IStrategy):
     """
     RLAgentStrategy
@@ -55,7 +62,7 @@ class RLAgentStrategy(IStrategy):
     def feature_engineering_standard(
         self, dataframe: DataFrame, metadata: dict[str, Any], **kwargs
     ) -> DataFrame:
-        dates = pd.to_datetime(dataframe["date"], utc=True)
+        dates = _ensure_datetime_series(dataframe["date"])
         dataframe["%-day_of_week"] = (dates.dt.dayofweek + 1) / 7
         dataframe["%-hour_of_day"] = (dates.dt.hour + 1) / 25
 
index 04d125ea4e134071ae07cc95e6e5b349d85523dc..70747ab49a8d71aaa536cd5a0586f774e3cddd4e 100644 (file)
@@ -51,6 +51,7 @@ from Utils import (
     LABEL_COLUMNS,
     REGRESSORS,
     Regressor,
+    ensure_datetime_series,
     eval_set_and_weights,
     fit_regressor,
     format_dict,
@@ -1376,12 +1377,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 training_filter=True,
             )
 
-            start_date = pd.to_datetime(
-                unfiltered_df["date"].iloc[0], utc=True
-            ).strftime("%Y-%m-%d")
-            end_date = pd.to_datetime(
-                unfiltered_df["date"].iloc[-1], utc=True
-            ).strftime("%Y-%m-%d")
+            dates = ensure_datetime_series(unfiltered_df["date"])
+            start_date = dates.iloc[0].strftime("%Y-%m-%d")
+            end_date = dates.iloc[-1].strftime("%Y-%m-%d")
             logger.info(
                 f"-------------------- Training on data from {start_date} to "
                 f"{end_date} --------------------"
index 2e5108dd14fccd665b67971237c25d8724a679b9..b5d9ca8b35662d52babbb05342193cf2ac7fbd33 100644 (file)
@@ -16,7 +16,6 @@ from typing import (
 )
 
 import numpy as np
-import pandas as pd
 import pandas_ta as pta
 import talib.abstract as ta
 from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
@@ -40,6 +39,7 @@ from Utils import (
     apply_label_weighting,
     bottom_log_return,
     calculate_quantile,
+    ensure_datetime_series,
     ewo,
     format_dict,
     format_number,
@@ -724,7 +724,7 @@ class QuickAdapterV3(IStrategy):
     def feature_engineering_standard(
         self, dataframe: DataFrame, metadata: dict[str, Any], **kwargs
     ) -> DataFrame:
-        dates = pd.to_datetime(dataframe["date"], utc=True)
+        dates = ensure_datetime_series(dataframe["date"])
 
         dataframe["%-day_of_week"] = (dates.dt.dayofweek + 1) / 7
         dataframe["%-hour_of_day"] = (dates.dt.hour + 1) / 25
index 49e706dffc2cecbd7ded9d0226db4bc350ab927f..54870ed79b9c4ddbb0a21a3e51412f06d90e816e 100644 (file)
@@ -644,6 +644,12 @@ def get_label_prediction_config(
     )
 
 
+def ensure_datetime_series(series: pd.Series) -> pd.Series:
+    if pd.api.types.is_integer_dtype(series):
+        return pd.to_datetime(series, unit="ms", utc=True)
+    return pd.to_datetime(series, utc=True)
+
+
 def get_distance(p1: T, p2: T) -> T:
     return abs(p1 - p2)