Friday, 26 March 2021

Backtrader problems in resampling to daily

Using backtrader, I would like to retrieve quotes at a five minute scale and resample at a daily scale.

I am able to resample five minutes to sixty minutes, but can't do daily. Here is the code:

from __future__ import absolute_import, division, print_function, unicode_literals
import backtrader as bt
import backtrader.stores.ibstore as ibstore
import datetime
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

_CLIENTID = 100

class St(bt.Strategy):
    def __init__(self):
        self.sma = bt.indicators.SMA(self.data)

    def logdata(self):
        txt = []
        txt.append('{}'.format(len(self)))
        txt.append('{}'.format(self.data.datetime.datetime(0).isoformat()))
        txt.append('{:.2f}'.format(self.data.open[0]))
        txt.append('{:.2f}'.format(self.data.high[0]))
        txt.append('{:.2f}'.format(self.data.low[0]))
        txt.append('{:.2f}'.format(self.data.close[0]))
        txt.append('{:.2f}'.format(self.data.volume[0]))
        logger.debug(','.join(txt))

    data_live = False

    def notify_data(self, data, status, *args, **kwargs):
        print('*' * 5, 'DATA Notification:', data._getstatusname(status), *args)
        if status == data.LIVE:
            self.data_live = True

    def next(self):
        self.logdata()
        if not self.data_live:
            return

_TICKER = "TSLA-STK-SMART-USD"
_FROMDATE = datetime.datetime(2021,1,4)
_TODATE = datetime.datetime(2021,1,29)
_HAS_STATS = False

def run(args=None):
    cerebro = bt.Cerebro(stdstats=_HAS_STATS)

    store = ibstore.IBStore(host="127.0.0.1", port=7497, clientId= _CLIENTID )
    cerebro.broker = store.getbroker()
    stockkwargs = dict(
        timeframe=bt.TimeFrame.Minutes,
        compression=10,
        rtbar=False,
        historical=True,
        qcheck=0.5,
        fromdate=_FROMDATE,
        todate=_TODATE,
        latethrough=False,
        tradename=None
    )

    data0 = store.getdata(dataname=_TICKER, **stockkwargs)
    # cerebro.resampledata(data0, timeframe=bt.TimeFrame.Minutes, compression=60)
    cerebro.resampledata(data0, timeframe=bt.TimeFrame.Days, compression=1)

    cerebro.run()

if __name__ == "__main__":
    run()

I get a connection, but no days. Here is the output (with no bars printed):

Server Version: 76
TWS Time at connection:20210303 09:39:17 EST
***** DATA Notification: DELAYED
***** DATA Notification: DISCONNECTED

However, if I go on a 60-minute resample, all is well. The code

cerebro.resampledata(data0, timeframe=bt.TimeFrame.Minutes, compression=60)
# cerebro.resampledata(data0, timeframe=bt.TimeFrame.Days, compression=1)

results in

Server Version: 76
TWS Time at connection:20210303 09:36:27 EST
***** DATA Notification: DELAYED
DEBUG:__main__:30,2021-01-05T17:00:00,749.65,754.40,735.11,753.21,6011.00
DEBUG:__main__:31,2021-01-05T18:00:00,753.39,754.18,751.60,753.34,1126.00
DEBUG:__main__:32,2021-01-05T19:00:00,753.32,753.32,750.49,752.90,1179.00
DEBUG:__main__:33,2021-01-06T04:00:00,748.00,752.55,746.66,751.88,331.00
DEBUG:__main__:34,2021-01-06T05:00:00,751.60,753.00,749.26,750.50,137.00
(omitted)
DEBUG:__main__:286,2021-01-28T17:00:00,833.00,833.25,831.36,831.61,116.00
DEBUG:__main__:287,2021-01-28T18:00:00,831.60,833.96,830.11,831.00,175.00
DEBUG:__main__:288,2021-01-28T19:00:00,830.51,832.00,829.45,829.45,358.00
***** DATA Notification: DISCONNECTED

I am using these versions:

Python 3.7.4
ib                   0.8.0
IbPy2                0.8.0
numpy                1.19.2
pandas               1.1.3

TL;DR I did several other experiments.

getData timeframe getData compression resample timeframe resample compression outcome
Minutes 5 Minutes 60 can see hourly, as expected
Minutes 5 Days 1 (empty)
(blank) (blank) Days 1 (empty)
Days 1 Days 1 (empty)
Days 1 (commented out) (commented out) (empty)


from Backtrader problems in resampling to daily

No comments:

Post a Comment