Multiple Timeframes with Multiple Datafeeds
-
When I use a single time frame I have no trouble resampling my data and implementing it into init exactly the way its shown in the BT documantation:
def __init__(self): self.atr = bt.indicators.ATR(self.data, period=self.params.atr_per) self.stoch = bt.indicators.Stochastic(self.data, period=self.params.stoch_per, period_dslow=self.params.dslow_per) self.daily_atr = bt.indicators.ATR(self.data1, period=self.params.datr_per)
When I work with multiple data feed I use following code to add it to cerebro:
for i in range(len(symbols)): dataframe = pandas.read_csv(symbols[i][0], index_col=0, parse_dates=True, dayfirst=True ) data = PandasData(dataname=dataframe, timeframe=bt.TimeFrame.Minutes, compression=5) cerebro.adddata(data, name=symbols[i][1])
and then following code to implement it into init:
def __init__(self): self.inds = dict() for i, d in enumerate(self.datas): self.inds[d] = dict() self.inds[d]['atr'] = bt.indicators.ATR(d, period=self.params.atr_per) self.inds[d]['stoch'] = bt.indicators.Stochastic(d, period=self.params.stoch_per, period_dslow=self.params.dslow_per)
The code above works perfectly witha single timeframe.
For a single datafeed and multiple timeframe, I have self.data for my intraday data and self.data1 for my daily data which I can pass to the indicators I want and from there on my strategy works as expected.
For multiple datafeeds however, looks like backtrader includes both the 5 min and daily timeframes in same set of feeds (self.datas) and from here on I cannot pass the data I want to the relevant indicators. Not only this but the daily data also messes around with my intraday indicators.
I tried to replicate the above code during init:
self.daily_inds = dict() for i, d1 in enumerate(self.data1): self.daily_inds[d1] = dict() self.daily_inds[d1]['d_atr'] = bt.indicators.ATR(d1, period=5)
but it simply wouldnt work.
Is there a way to prevent daily data messing around with my intraday indicators and use it only for the calculation of the daily indicators?
Daily ATR is important to me as it presents the average daily range for the past few days.
thanks,
Rum -
@Rumen-Nenov said in Multiple Timeframes with Multiple Datafeeds:
For multiple datafeeds however, looks like backtrader includes both the 5 min and daily timeframes in same set of feeds (self.datas)
For a single data feed too. Each and every data feed is present in the
self.datas
iterable, exactly in the order in which they were introduced in the system.@Rumen-Nenov said in Multiple Timeframes with Multiple Datafeeds:
and from here on I cannot pass the data I want to the relevant indicators
And why not? They are data feeds, they can be passed to any indicator.
@Rumen-Nenov said in Multiple Timeframes with Multiple Datafeeds:
Not only this but the daily data also messes around with my intraday indicators.
Exactly how? This would be the first time.
@Rumen-Nenov said in Multiple Timeframes with Multiple Datafeeds:
for i, d1 in enumerate(self.data1):
Sorry but
self.data1
is a data feed and not and array of data feeds. This is for sure not in the documentation. It seems you assume that daily data feeds get magically all packed insideself.data1
. No.See here for what
self.data1
means: Docs - Platform ConceptsWhat you need is to have a convention for the addition order of the data feeds to cerebro. If you add a
5-min
/1-day
data feeds per instrument, you can use something likefor i in range(0, len(self.datas), 2)
, where self.datas[i]will have the
5-minfeed and
self.datas[i + 1]will have the
1-day` feed. -
Great! thanks very much!
I simply created 2 new lists inside init
self.m5_data = self.datas[::2] self.d1_data = self.datas[1::2] self.inds = dict() for i, d in enumerate(self.m5_data): self.inds[d] = dict() self.inds[d]['atr'] = bt.indicators.ATR(d, period=self.params.atr_per) self.inds[d]['stoch'] = bt.indicators.Stochastic(d, period=self.params.stoch_per, period_dslow=self.params.dslow_per) self.daily_inds = dict() for i, d in enumerate(self.d1_data): self.daily_inds[d] = dict() self.daily_inds[d]['d_atr'] = bt.indicators.ATR(d, period=self.params.d_atr_per)
Now however I've got trouble using it during next. For single time frame following code does the trick:
def next(self): for i, d in enumerate(self.datas): dt, dn = self.datetime.datetime(), d._name pos = self.getposition(d).size if pos==0: # And then follows the logic of the strategy
but for multiple time frame i couldn't enumerate both lists simultaneously. I tried following
for i, d in enumerate(zip(self.m5_data, self.d1_data)): dt, dn = self.datetime.datetime(), d._name pos = self.getposition(d).size # and also for i, d in enumerate(self.m5_data + self.d1_data): dt, dn = self.datetime.datetime(), d._name pos = self.getposition(d).size
neither of them worked. Further ahead in the process I believe that time frames are matched by d._name and self.datetime.datetime, and they should not necessarily be enumerated simultaneously. What would be the solution here?
-
Solved!
def next(self): for i, (d, d1) in enumerate(zip(self.m5_data, self.d1_data)): dt, (dn, d1n) = self.datetime.datetime(), (d._name, d1._name)
-
Hello @Rumen-Nenov,
I have a common problem. Here is my code:
import backtrader as bt import backtrader.feeds as btfeeds #import backtrader.indicators as btind import pandas as pd import math #gutes Forum Problem 2 Timeframes und mehrere datenfeeds (aktien) # https://community.backtrader.com/topic/2285/multiple-timeframes-with-multiple-datafeeds class simpleStrategy1307(bt.Strategy): params = ( ('Risk_perTrade', 0.01), ) def __init__(self): self.m60_data = self.datas[::2] self.d1_data = self.datas[1::2] self.inds = dict() for i, d in enumerate(self.m60_data): self.inds[d] = dict() self.inds[d]['atr'] = bt.indicators.ATR(d) #self.inds[d]['stoch'] = bt.indicators.Stochastic(d) self.daily_inds = dict() for i, d in enumerate(self.d1_data): self.daily_inds[d] = dict() self.daily_inds[d]['d_atr'] = bt.indicators.ATR(d) print("__init__ durchlaufen :)") def next(self): print("Hallo") # d = 60min & d1 = Daily Data # dn = 60Minuten Sock Name & d1n ist Daily Stock Name for i, (d, d1) in enumerate(zip(self.m60_data, self.d1_data)): dt, (dn, d1n) = self.datetime.datetime(), (d._name, d1._name) if self.inds[d]['atr'] > self.inds[d1]['atr']: self.buy(d) else: self.sell(d) #print(d) #print(dn) #print(d.date) def runstrat(): cerebro = bt.Cerebro() cerebro.addstrategy(simpleStrategy1307) # get all symbols # read symbols from csv and read path of Stock and Index sheet = pd.read_csv("/Users/christianbrendel/Desktop/allgemein/Visual Studio/Grap StockData/Aktiensymbole/SPX_für_Tiingo Kopie.csv") Stock_60min_path = "/Users/christianbrendel/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/" Index_Daily_path = "/Users/christianbrendel/Desktop/allgemein/Visual Studio/Stock Data/Index EOD Data/^GSPC.csv" #erstelle excel w, h = 2, len(sheet.index) symbols = [[0 for x in range(w)] for y in range(h)] for i in range (0,len(sheet.index)): # in erste Spalte path z.B. "/Users/christianbrendel/Desktop/allgemein/Visual Studio/Stock Data/S&P500 Aktien 1H/A" symbols[i][0] = Stock_60min_path + sheet.iloc[i][0] + ".csv" # in der zeiten spalte den Name z.B. "A" einfügen symbols[i][1] = sheet.iloc[i][0] for i in range(len(symbols)): dataframe = pd.read_csv(symbols[i][0], index_col=1, parse_dates=True, dayfirst=True, infer_datetime_format=True, ) #stock_prices = pd.read_csv(path, index_col=1, parse_dates=True, infer_datetime_format=True) m60_data = bt.feeds.PandasData(dataname=dataframe, timeframe=bt.TimeFrame.Minutes, compression=60) cerebro.adddata(m60_data, name=symbols[i][1]) Indexdataframe = pd.read_csv(Index_Daily_path, index_col=0, parse_dates=True, dayfirst=True, infer_datetime_format=True, ) Indexdata = bt.feeds.PandasData(dataname=Indexdataframe, timeframe=bt.TimeFrame.Days) cerebro.adddata(Indexdata, name="SPX") #print('Starting Portfolio Value: {0:8.2f}'.format(cerebro.broker.getvalue())) cerebro.run() if __name__ == "__main__": runstrat() print("data added to Cerebro :)") #print('Starting Portfolio Value: {0:8.2f}'.format(cerebro.broker.getvalue()))
The code starts and than nothing happens..
1. Do you think my way to fill my data feed is correct?
2. Is my init Method right?
3. Can I use my data feed like I have done in the next function?thank you for your help!
best regards
Christian