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

Problem occurring when I change 'cerebro.adddata(data, name = i)' to 'cerebro.resampledata(data , timeframe = bt.TimeFrame.Minutes, compression=15,name = i)' Error: return self.array[self.idx + ago] IndexError: array index out of range



  • I can't thank the developers enough for this platform. But here I am again with another post trying to figure out what I am doing wrong. I know the mistake might be something really basic.
    Important portions of the code are mentioned below.
    init function

        def __init__(self):
            '''
            Create an dictionary of indicators so that we can dynamically add the
            indicators to the strategy using a loop. This mean the strategy will
            work with any numner of data feeds. 
            '''
            self.inds = dict()
            self.order = {}
            for i, d in enumerate(self.datas):
                self.order[d._name] = None
                self.inds[d] = dict()
                self.inds[d]['atr14'] = bt.indicators.AverageTrueRange(d, period = self.params.atrperiod)
                self.inds[d]['macd'] = bt.indicators.MACD(d,
                                           period_me1=self.p.macd1,
                                           period_me2=self.p.macd2,
                                           period_signal=self.p.macdsig)
                self.inds[d]['mcross'] = bt.indicators.CrossUp(self.inds[d]['macd'].macd, self.inds[d]['macd'].signal)
    
    
    

    Main logic in next():

        def next(self):
    
    #         self.logdata()
            for i, d in enumerate(self.datas):
                dt, dn = self.datetime.date(), d._name
                pos = self.getposition(d).size
                self.logdata()
                print(d._name)
    #ERROR OCCURSE BELOW THIS LINE
                 if self.inds[d]['atr14'][0] * self.params.atrmultiplier < (d.high[0]-d.low[0]) and d.close[0]<d.close[-1]:  # This is where the error occurs
    #                  self.buy(data=d, size=1)
                        if self.order[d._name]:
                            self.log('We already have a buy order for %s in place' % d._name)
                            return
                        self.log(' BUYING.  ||| symbol: %s , atr14 : %.2f , high-low :  %.2f, close[0]: %.2f, close[-1] %.2f ' % (d._name,self.inds[d]['atr14'][0],(d.high[0]-d.low[0]),d.close[0],d.close[-1]))
                        self.order[d._name] = self.order_target_value(data=d, target = 30000)
    
    
    
    

    Code for data insertion for multiple stocks written below. This code gives error.

    for i in stocks_5:
        stock_ohlc = data_csv[data_csv['Symbol'] == i][['open','high','low','close','volume']] 
        data = bt.feeds.PandasData(dataname=stock_ohlc, sessionstart = datetime.time(9,15), sessionend=datetime.time(15,15))
        cerebro.resampledata(data , timeframe = bt.TimeFrame.Minutes, compression=15,name = i)
    
    

    Keeping everything same but using this code works and I get a proper output.

    for i in stocks_5:
        stock_ohlc = data_csv[data_csv['Symbol'] == i][['open','high','low','close','volume']] 
        data = bt.feeds.PandasData(dataname=stock_ohlc, timeframe = bt.TimeFrame.Minutes, compression=15, sessionstart = datetime.time(9,15), sessionend=datetime.time(15,15))
        cerebro.adddata(data, name = i)
    
    
    

    The only reason I need to use resample data instead of addatla is because as far as I know there is a necessity to use resample data for 15 minute bars when paper trading I interactive brokers.
    I can't post output here of the code that is working since it is really long.
    Also 1 important thing to consider which I have deduced is the error occurs when there is no data for that stock. For example out of 5 stocks data of 4 stocks are starting on 21st January but the 5th is starting on 24th, this is where the error occurs.

    Here is the output when I have the error:

    1,2018-12-21T09:15:00,O: 43.85,H: 43.85,L: 43.10,C: 43.30,V: 222.00
    20MICRONS
    1,2018-12-21T09:15:00,O: 43.85,H: 43.85,L: 43.10,C: 43.30,V: 222.00
    21STCENMG
    1,2018-12-21T09:15:00,O: 43.85,H: 43.85,L: 43.10,C: 43.30,V: 222.00
    3IINFOTEC
    1,2018-12-21T09:15:00,O: 43.85,H: 43.85,L: 43.10,C: 43.30,V: 222.00
    3MINDIA
    1,2018-12-21T09:15:00,O: 43.85,H: 43.85,L: 43.10,C: 43.30,V: 222.00
    3PLAND
    ---------------------------------------------------------------------------
    IndexError                                Traceback (most recent call last)
    <ipython-input-43-a3e55db0bf8e> in <module>
        291 # Run over everything
        292 # cerebro.broker.set_coc(True)
    --> 293 cerebro.run()
        294 
        295 #Get final portfolio Value
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/cerebro.py in run(self, **kwargs)
       1125             # let's skip process "spawning"
       1126             for iterstrat in iterstrats:
    -> 1127                 runstrat = self.runstrategies(iterstrat)
       1128                 self.runstrats.append(runstrat)
       1129                 if self._dooptimize:
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/cerebro.py in runstrategies(self, iterstrat, predata)
       1296                     self._runnext_old(runstrats)
       1297                 else:
    -> 1298                     self._runnext(runstrats)
       1299 
       1300             for strat in runstrats:
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/cerebro.py in _runnext(self, runstrats)
       1628                 self._check_timers(runstrats, dt0, cheat=False)
       1629                 for strat in runstrats:
    -> 1630                     strat._next()
       1631                     if self._event_stop:  # stop if requested
       1632                         return
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/strategy.py in _next(self)
        345 
        346     def _next(self):
    --> 347         super(Strategy, self)._next()
        348 
        349         minperstatus = self._getminperstatus()
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/lineiterator.py in _next(self)
        273                 self.nextstart()  # only called for the 1st value
        274             else:
    --> 275                 self.prenext()
        276         else:
        277             # assume indicators and others operate on same length datas
    
    <ipython-input-43-a3e55db0bf8e> in prenext(self)
        115                     d.plotinfo.plotmaster = self.datas[0]
        116     def prenext(self):
    --> 117         self.next()
        118 
        119     def next(self):
    
    <ipython-input-43-a3e55db0bf8e> in next(self)
        126             print(d._name)
        127             if not pos and self.p.typeofentry == 1:  # no market / no orders
    --> 128                 if self.inds[d]['atr14'][0] * self.params.atrmultiplier < (d.high[0]-d.low[0]) and d.close[0]<d.close[-1]:
        129 #                     self.buy(data=d, size=1)
        130                     if self.order[d._name]:
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/lineseries.py in __getitem__(self, key)
        465 
        466     def __getitem__(self, key):
    --> 467         return self.lines[0][key]
        468 
        469     def __setitem__(self, key, value):
    
    /usr/local/Cellar/python35/3.5.7_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/backtrader/linebuffer.py in __getitem__(self, ago)
        161 
        162     def __getitem__(self, ago):
    --> 163         return self.array[self.idx + ago]
        164 
        165     def get(self, ago=0, size=1):
    
    IndexError: array index out of range
    

    Also I really don't mind implementing this exact code with add data but I have some issue when live paper trading it in interactive brokers thus I have to use resample data. I think there is a need I show the prenext() function to get further insight so here it is:

        def prenext(self):
            self.next()
            
    

    Again I might be wrong in many things I am considering. Please feel free to correct me. Any help would be appreciated. Thanks in advance.



  • As a guess - When you simply add data you define data feed time frame and compression. However, when you use resampling, than your original data feed time frame and compression is not defined. Only data feed and compression of the resultant data feed.

    Maybe this causes the error.



  • Thank you for the reply. I tried defining the original data feed time frame and compression and then using resampling on it.
    Note: I don't really need to do this for backtesting but I am doing this as I need to resample the data for interactive brokers live paper trading.
    But I still got the same error at the same place.

    for i in stocks_5:
        stock_ohlc = data_csv[data_csv['Symbol'] == i][['open','high','low','close','volume']] 
        data = bt.feeds.PandasData(dataname=stock_ohlc, timeframe = bt.TimeFrame.Minutes, compression=15, sessionstart = datetime.time(9,15), sessionend=datetime.time(15,15))
        cerebro.resampledata(data, timeframe = bt.TimeFrame.Minutes, compression=15, name = i)
    
    
    


  • So here is an update for the same. I had added

    def prenext(self):
            self.next()
    

    so that my backtest runs the entire timeframe i.e. if I have 100 stocks the earliest possible date is taken into consideration since some stocks have IPO's later. When I removed the prenext the code worked with resample and replay data but again I am getting output for a lower timeframe i.e. if the entire timeframe is 100 days but 1 of the stocks is only 30 days I am getting the backtest of only that particular timeframe.
    Is there a way to achieve both i.e. get the backtest for the entire timeframe as well as me not getting an error. I am sure I have made some silly mistake in understanding the docs but I am helpless regarding this.



  • You are trying to access the prices which don't yet exist during prenext(). Therefore bt returns you an error. You need to put additional check in the script to avoid it.


Log in to reply
 

});