For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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


  • administrators

    @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 inside self.data1. No.

    See here for what self.data1 means: Docs - Platform Concepts

    What 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 like for i in range(0, len(self.datas), 2), where self.datas[i]will have the5-minfeed andself.datas[i + 1]will have the1-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)
    

Log in to reply
 

});