backtrader2 / backtrader

Python Backtesting library for trading strategies
https://www.backtrader.com
GNU General Public License v3.0
227 stars 54 forks source link

Resampling 1 Minute to 20 Minutes produces bars at absurd intervals #85

Closed sohamsjain closed 2 years ago

sohamsjain commented 2 years ago

I'm trying to resample 1 minute bars to 20 minutes. But the resampled bars are produced at absurd intervals.

Source of datafeed: Interactive Brokers API Market hours: 09:15 hrs to 15:30 hrs Backfill duration: 10 days

Note: Data provided by IB API is left-edge labeled (forward looking) by default. BackwardLookingFilter is a simple workaround that handles rightedge-ing minute bars. The problem persists with or without it.


import backtrader as bt

fromdate = datetime.now().date() - timedelta(days=10)
sessionstart = datetime.now().time().replace(hour=9, minute=15, second=0, microsecond=0)
sessionend = datetime.now().time().replace(hour=15, minute=30, second=0, microsecond=0)

class BackwardLookingFilter(object):

    def __init__(self, data):
        pass

    def __call__(self, data):
        data.datetime[0] = data.date2num(data.datetime.datetime(0) + timedelta(minutes=1))
        return False

class Test(bt.Strategy)

    def next(self):

        print("Minutes 1 ", self.data0.datetime.datetime(0))
        print("Minutes 20 ", self.data1.datetime.datetime(0))
        print("_"*50)

cerebro = bt.Cerebro()
cerebro.addstrategy(Test)

store = bt.stores.IBStore(port=7497, _debug=False)
cerebro.setbroker(store.getbroker())

minutedata = store.getdata(dataname="NIFTY50_IND_NSE", fromdate=fromdate, rtbar=True, sessionstart=sessionstart,
                           historical=True, sessionend=sessionend, timeframe=bt.TimeFrame.Minutes,
                           compression=1)

cerebro.adddata(minutedata)

minutedata.addfilter(BackwardLookingFilter)

cerebro.resampledata(minutedata,
                     timeframe=bt.TimeFrame.Minutes,
                     compression=20,
                     bar2edge=False,
                     boundoff=5)

cerebro.run()

Output:

Server Version: 76
TWS Time at connection:20220226 19:12:01 India Standard Time
Minutes 1  2022-02-16 09:35:00
Minutes 20 2022-02-16 09:35:00
__________________________________________________
Minutes 1  2022-02-16 09:36:00
Minutes 20 2022-02-16 09:35:00
__________________________________________________
Minutes 1  2022-02-16 09:37:00
Minutes 20 2022-02-16 09:35:00
__________________________________________________
Minutes 1  2022-02-16 09:38:00
Minutes 20 2022-02-16 09:37:00
__________________________________________________
Minutes 1  2022-02-16 09:39:00
Minutes 20 2022-02-16 09:37:00
__________________________________________________
Minutes 1  2022-02-16 09:40:00
Minutes 20 2022-02-16 09:37:00
__________________________________________________

Ideally after 09:35:00 the next 20 Minute bar should be produced at 09:55:00.

Unexpected behavior: The 20 Minute datafeed produces a bar at time: 09:37:00. (4th row in output)