diff --git a/freqtrade/data/converter/converter.py b/freqtrade/data/converter/converter.py index 7e68439df..adce2c065 100644 --- a/freqtrade/data/converter/converter.py +++ b/freqtrade/data/converter/converter.py @@ -39,7 +39,11 @@ def ohlcv_to_dataframe( df = DataFrame(ohlcv, columns=cols) # Floor date to seconds to account for exchange imprecisions - df["date"] = to_datetime(df["date"], unit="ms", utc=True).dt.floor("s") + from freqtrade.exchange import timeframe_to_floor_freq + + resample_interval = timeframe_to_floor_freq(timeframe) + + df["date"] = to_datetime(df["date"], unit="ms", utc=True).dt.floor(resample_interval) # Some exchanges return int values for Volume and even for OHLC. # Convert them since TA-LIB indicators used in the strategy assume floats diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 075906e11..709738efc 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -30,6 +30,7 @@ from freqtrade.exchange.exchange_utils import ( validate_exchange, ) from freqtrade.exchange.exchange_utils_timeframe import ( + timeframe_to_floor_freq, timeframe_to_minutes, timeframe_to_msecs, timeframe_to_next_date, diff --git a/freqtrade/exchange/exchange_utils_timeframe.py b/freqtrade/exchange/exchange_utils_timeframe.py index 1897edf3b..ead8e0e18 100644 --- a/freqtrade/exchange/exchange_utils_timeframe.py +++ b/freqtrade/exchange/exchange_utils_timeframe.py @@ -29,6 +29,21 @@ def timeframe_to_msecs(timeframe: str) -> int: return ccxt.Exchange.parse_timeframe(timeframe) * 1000 +def timeframe_to_floor_freq(timeframe: str) -> str: + """ + Translates the timeframe interval value written in the human readable + form ('1m', '5m', '1h', '1d', '1w', etc.) to the desired floor frequency used by pandas + ("1m", "5m", "1h", "1d", "1w", etc.). + Will use minute for most higher timeframes. + """ + timeframe_seconds = timeframe_to_seconds(timeframe) + timeframe_minutes = timeframe_seconds // 60 + if timeframe_minutes <= 1: + return "1s" + else: + return "1min" + + def timeframe_to_resample_freq(timeframe: str) -> str: """ Translates the timeframe interval value written in the human readable