Category Archives: python

Backtrader Data Frustruation

I’ve been working on a day-trading algorithm for backtrader using stock data (primarily SPY and QQQ for now). Sometimes it appears that the data doesn’t completely come through and the system doesn’t quite initialize. I now think I know what is going on.

First, the fix…I shortened the maximum parameter for an ATR parameter that I was using. When this was shortened (using 60 minute data, to 300 bars or fewer) the code started working as anticipated.

Why did this work? I believe using some levels of granularity the historical data retrieved is insufficient to allow all of the indicators to fully populate. This was tricky to narrow down because 1 minute data worked and 120 minute data worked but 60 minute data didn’t. I don’t know that the Interactive Brokers API gives you the same amount of data each time, so in some cases it appears less data is retrieved resulting in in my case ATR to not fully populate and leaving me in the “prenext” area of backtrader, not making it to the “next” method.

Backtrader–notes about multiple data timeframes

I attempted to make a system that uses ATR based on a different time frame than the signal I was considering. Bottom line, that wasn’t successful for trading (at least so far) but I did discover some errors and figured out a way to correct some of them.

First of all, to use multiple time frames I had to include some additional inputs into the original data.

I collected the data using a class I wrote that gets data into a pandas dataframe named data frame, so that is the entry point for the following code:

data = bt.feeds.PandasData(dataname=dataframe, name=symbol, ) 

If I wanted to use a different time frame, I had to modify this code to the following:

data = bt.feeds.PandasData(dataname=dataframe, name=symbol, timeframe = bt.TimeFrame.Minutes, compression = _) 

Then to resample the data, I could use the following statements:

cerebro.adddata(data) #data0
cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression = 720, name = '720m') # data1
cerebro.resampledata(data, timeframe=bt.TimeFrame.Days, compression = 1, name = '1d') # data2

This including this resampled data did cause some problems. I had an observer that intermittently caused errors when plotting which I removed to allow plotting to be reliable:

#cerebro.addobserver(bu.AcctValue)

Truth be told I didn’t really need that observer but it was in some code I copied when I was just getting started with backtrader.

I also had trouble with an analyzer, specifically the returns analyzer added with the following code.

cerebro.addanalyzer(bt.analyzers.Returns, _name="ret")

When I used the data feed that included “timeframe = bt.TimeFrame.Minutes” this analyzer would give a nonsensical answer. I don’t know why this subtle difference in the data that shouldn’t really change anything ruins the output of the analyzer but it seems to be the case.