Futures rollover - data feed produced seems to be empty
-
Dear All,
I'm trying to backtest a VIX futures strategy that requires actual futures contract. It is the first time i'm looking at the rollover feature of backtester. My code is fairly simple and inspired from the rollover sample / code I found on this forum. At a high level, I load each indidivudal futures (only 4 contracts in this example) contract from CSV, then i try to "chain" them using cerebro.rollover (with checkvolume). After that, i'm adding the strategy 'TheStrategy' (same as in sample code) to display the daily bars. Unfortunately, nothing gets displayed. it seems that the datafeed generated by cerebro.rollover is empty. I have tried to investigate this issue but i have not found anything (difficult since there is not even an error message). On thing i did is to replace cerebro.rollover by cerebro.chaindata. In this case, it works well, and i see the 4 futures contracts being displayed one after the others. Code used is shown below.
Any help to resolve/investigate this issue will be extremely welcome!
Thanks in advance and cheers!
Lamp'data from CBOE website, e.g.
VX18 - https://markets.cboe.com/us/futures/market_statistics/historical_data/products/csv/VX/2018-12-19import datetime import time import argparse import bisect import calendar import datetime import backtrader as bt import backtrader.filters as btfilters from backtrader.order import Order class TheStrategy(bt.Strategy): def start(self): header = ['Len', 'Name', 'RollName', 'Datetime', 'Open', 'High', 'Low', 'Close', 'Volume', 'OpenInterest'] print(', '.join(header)) def next(self): txt = list() txt.append('%04d' % len(self.data0)) txt.append('{}'.format(self.data0._dataname)) # Internal knowledge ... current expiration in use is in _d txt.append('{}'.format(self.data0._d._dataname)) txt.append('{}'.format(self.data.datetime.date())) txt.append('{}'.format(self.data.open[0])) txt.append('{}'.format(self.data.high[0])) txt.append('{}'.format(self.data.low[0])) txt.append('{}'.format(self.data.close[0])) txt.append('{}'.format(self.data.volume[0])) txt.append('{}'.format(self.data.openinterest[0])) print(', '.join(txt)) def get_data_feed(data_filename): data = bt.feeds.GenericCSVData( dataname=data_filename, headers=True, dtformat=('%Y-%m-%d'), datetime=0, open=3, high=4, low=5, close=6, volume=8, openinterest=10, timeframe=bt.TimeFrame.Days, compression=1 ) return data def checkvolume(d0, d1): return d0.volume[0] < d1.volume[0] # Switch if volume from d0 < d1 month_codes = ['U18', 'V18', 'X18', 'Z18'] ffeeds = [get_data_feed('./CFE_{0}_VX.csv'.format(x)) for x in month_codes] month_codes = ['U18', 'V18', 'X18', 'Z18'] ffeeds = [get_data_feed('./CFE_{0}_VX.csv'.format(x)) for x in month_codes] cerebro = bt.Cerebro() rollkwargs = dict() rollkwargs['checkcondition'] = checkvolume cerebro.rolloverdata(name='FESX', *ffeeds, **rollkwargs) #cerebro.chaindata(name='FESX', *ffeeds) cerebro.addstrategy(TheStrategy) cerebro.run()
-
Documentation - Docs - Rolling over Futures
- checkcondition (default: None) Note: This will only be called if checkdate has returned True
You have not specified a
checkdate
, which means that yourcheckcondition
is not being called. In any case that should not be the problem, because it will simply be ignored.@lampalork said in Futures rollover - data feed produced seems to be empty:
open=3, high=4, low=5, close=6,
Those indices are offset by
+1
. You want2, 3, 4, 5
.@lampalork said in Futures rollover - data feed produced seems to be empty:
class TheStrategy(bt.Strategy): def start(self): header = ['Len', 'Name', 'RollName', 'Datetime', 'Open', 'High', 'Low', 'Close', 'Volume', 'OpenInterest'] print(', '.join(header))
You say it seems to be empty, but we don't even know if you are seeing the header printed.
I would
- Load one of those single data feeds and see if it loads and is displayed
- Add 2 of them manually to
cerebro.rollover
and see what happens.
-
Hi Backtrader,
Thanks for getting back.
- i have fixed the field indices but obviously this was not the issue
- when i load one feed straight (i.e.
using cerebro.adddata(ffeeds[0])
instead of rollover), i can see the header and the data being displayed - When i load one feed or multiple feeds using rolloverdata (e.g.
cerebro.rolloverdata(ffeeds[0], name='MyRoll', **rollkwargs)
orcerebro.rolloverdata(ffeeds[0],ffeeds[1], name='MyRoll', **rollkwargs)
), i can see the header but not the header - When i load the data with chaindata (e.g.
cerebro.chaindata(name='MyRoll', *ffeeds)
), i can see the header and all the data (i.e. the data of the four futures one after the other)
Hope this clarifies the issue i'm facing. In case it is relevant, i'm running backtrader version 1.9.66.122
Thanks and regards
Lamp' -
Dear backtrader,
Any idea how I could investigate this further ?
thanks in advanceRegards
Lamp' -
Not really. The sample which is in the repository works.
My suggestion is that you use that sample with as little modifications as possible, i.e.: change only
ffeeds = [bt.stores. ...]
and use
ffeeds = [getdata(x) for x in fcodes]
Where
getdata
is the one in where you fetch the data usingGenericCSV
@lampalork said in Futures rollover - data feed produced seems to be empty:
month_codes = ['U18', 'V18', 'X18', 'Z18'] ffeeds = [get_data_feed('./CFE_{0}_VX.csv'.format(x)) for x in month_codes] month_codes = ['U18', 'V18', 'X18', 'Z18'] ffeeds = [get_data_feed('./CFE_{0}_VX.csv'.format(x)) for x in month_codes]
In any case you may also want to remove those duplicates
-
Still sort of stuck on this. I replicated the examples, and it is still not working. Is there a way I can run the example without changes, where do I get the VChart data used in rollover.py; I could not find them on GitHub. Do u need to subscribe to visual chart to be able to download the data and run this example? Thanks
-
Hello all, i finally made some progress on this. at first sight, it seems that upgrading backtrader from version backtrader-1.9.66.122 to backtrader-1.9.70.122 has fixed my issue. this is strange since this feature was added a while back to bt; but anyway, i thought i would post this here in case it can help someone else! happy sunday!