kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
https://kernc.github.io/backtesting.py/
GNU Affero General Public License v3.0
5.55k stars 1.07k forks source link

resample_apply data shift? #970

Closed jmlacasa closed 1 year ago

jmlacasa commented 1 year ago

Hi! Love the library. It is very simple to use I have a question about the use of resample_apply. I am currently trying to calculate ATR indicator in a 5m time frame with 1m time frame input.

Expected Behavior

I would have expected that the ATR value for a 5m timestamp would be replicated to the next 5 1m timestamps. like this:

ATR 5m 2023-04-21 02:55:00 0.059889 2023-04-21 03:00:00 0.059727 2023-04-21 03:05:00 0.059586

ATR5m in 1m candles (resample_apply output) 2023-04-21 03:00:00 0.059727 2023-04-21 03:01:00 0.059727 2023-04-21 03:02:00 0.059727 2023-04-21 03:03:00 0.059727 2023-04-21 03:04:00 0.059727 2023-04-21 03:05:00 0.059586 2023-04-21 03:06:00 0.059586 2023-04-21 03:07:00 0.059586 2023-04-21 03:08:00 0.059586 2023-04-21 03:09:00 0.059586

Actual Behavior

Instead what happens is the candle data is shifted one 5m candle forward. i.e. what I see between 03:00:00 and 03:04:00 is old data from 02:55:00 instead of 03:00:00 Is there something I am assuming incorrectly? Thank you for any help!

Steps to Reproduce

# self.data contains 1m candles

self.atr = resample_apply('5T'
                          , talib.ATR
                          , series=self.data.High
                          , low=self.data.Low.s.resample('5T').agg('min').to_numpy()
                          , close=self.data.Close.s.resample('5T').agg('last').to_numpy()
                          , timeperiod=200)

Timestamp
2023-04-21 02:59:00    0.060037
2023-04-21 03:00:00    0.059889
2023-04-21 03:01:00    0.059889
2023-04-21 03:02:00    0.059889
2023-04-21 03:03:00    0.059889
2023-04-21 03:04:00    0.059889
2023-04-21 03:05:00    0.059727
2023-04-21 03:06:00    0.059727
2023-04-21 03:07:00    0.059727
2023-04-21 03:08:00    0.059727
2023-04-21 03:09:00    0.059727
2023-04-21 03:10:00    0.059586

Freq: T, Name: ATR(H[5T],200), dtype: float64

talib.ATR(candles_1m['High'].resample('5T').agg('max')
          , candles_1m['Low'].resample('5T').agg('min')
          , candles_1m['Close'].resample('5T').agg('last')
          , timeperiod=200).tail(4)

Timestamp
2023-04-21 02:55:00    0.059889
2023-04-21 03:00:00    0.059727
2023-04-21 03:05:00    0.059586
2023-04-21 03:10:00    0.059331
Freq: 5T, dtype: float64

Additional info

kernc commented 1 year ago

Try as the example in the docs indicates:

self.atr = resample_apply('5T'
  , talib.ATR
  , series=self.data.High
  , low=self.data.Low
  , close=self.data.Close
  , timeperiod=200)

The resampling/aggregation is already done in resample_apply() internally.