Backtest is feeding in data from a future date
-
I'm doing some testing on how prices are being loaded in. I have two stocks, one which starts 1/2/2004 and another starts 1/9/2004. Once I load them in to Backtrader, when I step through the code I see that the first time prenext is being called is on date 1/2/2004, which is fine. For the first stock the closing price is self.datas is correct. However for the 2nd stock, which starts 1/9/2004, the closing price which is being shown is the last price in the pricing file, which is from 5/25/2004. Shouldn't it show as NaN?
-
@walt It would be great if you could share the code, logs and a sample of the data that shows the problem.
-
Sure here's the code
import backtrader as bt import datetime as dt import os class OptionData(bt.feeds.GenericCSVData): lines = ('delta',) params = ( ('open',-1), ('high',-1), ('low',-1), ('volume',-1), ('openinterest',-1), ('close',1), ('delta',2), ('dtformat',('%m/%d/%Y')), ) # Create a Strategy class Screener(bt.Strategy): def __init__(self): print('Starting Portfolio Value: %.2f' % self.broker.getvalue()) def prenext(self): # Need to run strategy here since not all datas will have data at the beginning # ! Be mindful that options which have no data will have prices filled in from the future px1 = self.datas[0].close[0] # Value is 695.8 which is wr px2 = self.datas[1].close[0] # Value is 712.04 which is wrong, correct price is 716.6 # 712.04 is the price from 5/25/04 data_folder = r'C:\Users\walte\OneDrive - K Squared Capital\K Squared Capital\Trading Models\Code\Backtrader\Data/' all_files = os.listdir(data_folder) # Create a cerebro entity cerebro = bt.Cerebro() data = OptionData(dataname = data_folder + 'SPX_C_400_20041218.csv') cerebro.adddata(data, name = 'SPX_C_400_20041218.csv') data = OptionData(dataname = data_folder + 'SPX_C_400_20040619.csv') cerebro.adddata(data, name = 'SPX_C_400_20040619.csv',) # Add a strategy cerebro.addstrategy(Screener) # Run over everything results = cerebro.run()
Data for SPX_C_400_20041218.csv looks like this:
And for SPX_C_400_20040619.csv:
-
@walt This behavior is by design although I would agree is somewhat unexpected.
During first few
prenext
calls only the first datadatas[0]
is actually iterated ( since the second datadatas[1]
is still not started). Getting the 'current' value of thedatas[1]
doesn't make sense at this point - however the current implementation ofGenericCSVData
will just return the latest loaded bar value. Other data feed classes may just throw exception for example.To be on the safe side I'd suggest to just test that the data was actually iterated before trying to access the current bar:
if len(self.datas[1]): px2 = self.datas[1].close[0]
the
len(self.datas[1])
will be zero unless the first bar of the data will be iterated.