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

Need some helps on issue: "IndexError: array index out of range"



  • Hey guys. while I tried to write a double ma crossing strategy, the result shows "IndexError: array index out of range." The data I used is CSV file which I downloaded from internet. Is this issue happened because of my data? I'm new on python and Backtrader, any suggestion or helps will much appreciate! Thank you in advance!

    Regards,
    Leo

    Code shows below:

    import pandas as pd
    import numpy as np
    import datetime
    import backtrader as bt
    
    cerebro = bt.Cerebro()
    cerebro.broker.set_cash(1111111111.1) 
    
    
    data = bt.feeds.YahooFinanceCSVData(
            dataname='test data 1.csv',
            # Do not pass values before this date
            fromdate=datetime.datetime(1999, 1, 1),
            # Do not pass values after this date
            todate=datetime.datetime(2013, 12, 31),
            reverse=False)
    
    cerebro.adddata(data)
    
    class double_ma(bt.Strategy):
        fast_window = 5
        slow_window = 10
    
        def log(self, txt, dt=None):
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):
            self.dataclose = self.datas[0].close
            self.order = None
            self.buyprice = None
            self.buycomm = None
    
            self.slow_sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.slow_window)
            self.fast_sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.fast_window)
    
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                return
    
            # Check if an order has been completed
            # Attention: broker could reject order if not enough cash
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm))
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.executed.price,
                              order.executed.value,
                              order.executed.comm))
    
                self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
    
            self.order = None
    
        def notify_trade(self, trade):
            if not trade.isclosed:
                return
    
            self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                     (trade.pnl, trade.pnlcomm))
    
        def next(self):
            self.log('Close, %.2f' % self.dataclose[0])
    
            # Check if an order is pending ... if yes, we cannot send a 2nd one
            if self.order:
                return
    
            # Check if we are in the market
            if not self.position:
    
                # Not yet ... we MIGHT BUY if ...
                if self.slow_sma[1] > self.fast_sma[1] and self.fast_sma[0] >= self.slow_sma[0]:
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.2f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.buy()
    
            else:
    
                if self.slow_sma[1] < self.fast_sma[1] and self.fast_sma[0] <= self.slow_sma[0]:
                    # SELL, SELL, SELL!!! (with all possible default parameters)
                    self.log('SELL CREATE, %.2f' % self.dataclose[0])
    
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.sell()
    
    
    cerebro.addstrategy(double_ma)
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
    cerebro.run()
    
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
    

    Result shows below:

    2013-12-13, Close, 30.88
    2013-12-16, Close, 31.17
    2013-12-17, Close, 31.25
    2013-12-18, Close, 32.16
    2013-12-19, Close, 34.01
    2013-12-19, SELL CREATE, 34.01
    2013-12-20, SELL EXECUTED, Price: 34.06, Cost: 32.48, Comm 0.00
    2013-12-20, OPERATION PROFIT, GROSS 1.58, NET 1.58
    2013-12-20, Close, 33.80
    2013-12-23, Close, 34.32
    2013-12-24, Close, 34.68
    2013-12-26, Close, 35.03
    2013-12-27, Close, 35.30
    2013-12-30, Close, 35.31
    Traceback (most recent call last):
      File "C:/Users/Leo/Desktop/Backtrader/Backtrader1.py", line 114, in <module>
        cerebro.run()
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\cerebro.py", line 1127, in run
        runstrat = self.runstrategies(iterstrat)
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\cerebro.py", line 1293, in runstrategies
        self._runonce(runstrats)
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\cerebro.py", line 1695, in _runonce
        strat._oncepost(dt0)
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\strategy.py", line 309, in _oncepost
        self.next()
      File "C:/Users/Leo/Desktop/Backtrader/Backtrader1.py", line 94, in next
        if self.slow_sma[1] > self.fast_sma[1] and self.fast_sma[0] >= self.slow_sma[0]:
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\lineseries.py", line 467, in __getitem__
        return self.lines[0][key]
      File "C:\Users\Leo\Desktop\Backtrader\venv\lib\site-packages\backtrader\linebuffer.py", line 163, in __getitem__
        return self.array[self.idx + ago]
    IndexError: array index out of range
    
    


  • Seems you get to the end of the data feed and try to get future values of self.slow_sma[1] and self.fast_sma[1] which doesn't' exist.



  • @ab_trader
    Got it . thank you!


Log in to reply
 

});