Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    How to solve this analyzers problem?

    Indicators/Strategies/Analyzers
    3
    4
    192
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Matheus Pires
      Matheus Pires last edited by

      Hello Guys,

      I was trying to figure out what's gone wrong when I tried to make this kind of resample:

      # Create a Data Feed
      data = btfeeds.BacktraderCSVData(dataname=datapath, timeframe = bt.TimeFrame.Days)
      
      # Add the Data Feed to Cerebro
      cerebro.adddata(data)
      
      cerebro.resampledata(data,timeframe = bt.TimeFrame.Weeks, compression = 1)    
      

      And added this analyzer:

      cerebro.addanalyzer(bt.analyzers.PositionsValue, _name = 'Positions')
      

      But got this kind of error (Array index out of range).

      IndexError                                Traceback (most recent call last)
      <ipython-input-6-cfa4078d6642> in <module>
           30 
           31 # Run over everything
      ---> 32 strats = cerebro.run(runonce = False)
           33 
           34 # Print out the final result
      
      /usr/local/lib/python3.7/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/lib/python3.7/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/lib/python3.7/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/lib/python3.7/site-packages/backtrader/strategy.py in _next(self)
          348 
          349         minperstatus = self._getminperstatus()
      --> 350         self._next_analyzers(minperstatus)
          351         self._next_observers(minperstatus)
          352 
      
      /usr/local/lib/python3.7/site-packages/backtrader/strategy.py in _next_analyzers(self, minperstatus, once)
          386                 analyzer._nextstart()  # only called for the 1st value
          387             else:
      --> 388                 analyzer._prenext()
          389 
          390     def _settz(self, tz):
      
      /usr/local/lib/python3.7/site-packages/backtrader/analyzer.py in _prenext(self)
          150             child._prenext()
          151 
      --> 152         self.prenext()
          153 
          154     def _notify_cashvalue(self, cash, value):
      
      /usr/local/lib/python3.7/site-packages/backtrader/analyzer.py in prenext(self)
          227         The default behavior for an analyzer is to invoke ``next``
          228         '''
      --> 229         self.next()
          230 
          231     def nextstart(self):
      
      /usr/local/lib/python3.7/site-packages/backtrader/analyzers/positions.py in next(self)
           76 
           77     def next(self):
      ---> 78         pvals = [self.strategy.broker.get_value([d]) for d in self.datas]
           79         if self.p.cash:
           80             pvals.append(self.strategy.broker.get_cash())
      
      /usr/local/lib/python3.7/site-packages/backtrader/analyzers/positions.py in <listcomp>(.0)
           76 
           77     def next(self):
      ---> 78         pvals = [self.strategy.broker.get_value([d]) for d in self.datas]
           79         if self.p.cash:
           80             pvals.append(self.strategy.broker.get_cash())
      
      /usr/local/lib/python3.7/site-packages/backtrader/brokers/bbroker.py in get_value(self, datas, mkt, lever)
          420             return self._value if not lever else self._valuelever
          421 
      --> 422         return self._get_value(datas=datas, lever=lever)
          423 
          424     getvalue = get_value
      
      /usr/local/lib/python3.7/site-packages/backtrader/brokers/bbroker.py in _get_value(self, datas, lever)
          444                 dvalue = comminfo.getvalue(position, data.close[0])
          445             else:
      --> 446                 dvalue = comminfo.getvaluesize(position.size, data.close[0])
          447 
          448             dunrealized = comminfo.profitandloss(position.size, position.price,
      
      /usr/local/lib/python3.7/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
      
      

      Does anyone have any idea of what's going on??

      Thanks

      1 Reply Last reply Reply Quote 0
      • Matheus Pires
        Matheus Pires last edited by

        Since giving the whole code may be useful for debugging, here below you can find it... I'm using a sample dataframe I got from "datas" folder...

        Strategy (the same you've seen from quickstart guide)

        # Create a Stratey
        class TestStrategy(bt.Strategy):
        
            def log(self, txt, dt=None):
                ''' Logging function fot this strategy'''
                dt = dt or self.datas[0].datetime.date(0)
                print('%s, %s' % (dt.isoformat(), txt))
        
            def __init__(self):
                # Keep a reference to the "close" line in the data[0] dataseries
                self.dataclose = self.datas[0].close
        
                # To keep track of pending orders
                self.order = None
        
            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, %.2f' % order.executed.price)
                    elif order.issell():
                        self.log('SELL EXECUTED, %.2f' % order.executed.price)
        
                    self.bar_executed = len(self)
        
                elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                    self.log('Order Canceled/Margin/Rejected')
        
                # Write down: no pending order
                self.order = None
        
            def next(self):
                # Simply log the closing price of the series from the reference
                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.dataclose[0] < self.dataclose[-1]:
                            # current close less than previous close
        
                            if self.dataclose[-1] < self.dataclose[-2]:
                                # previous close less than the previous close
        
                                # BUY, BUY, BUY!!! (with 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:
        
                    # Already in the market ... we might sell
                    if len(self) >= (self.bar_executed + 5):
                        # 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()
        
        # Create a cerebro entity
        cerebro = bt.Cerebro(stdstats = False)
        
        # Add a strategy
        cerebro.addstrategy(TestStrategy)
        
        # Datas are in a subfolder of the samples.
        
        datapath = 'datas/2006-day-001.txt'
        
        # Create a Data Feed
        data = btfeeds.BacktraderCSVData(dataname=datapath, timeframe = bt.TimeFrame.Days)
        
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
        
        cerebro.resampledata(data,timeframe = bt.TimeFrame.Weeks, compression = 1)    
        
        ## Resample data
        
        cerebro.addanalyzer(bt.analyzers.PositionsValue, _name = 'Positions') ##If one comments this line, the code works 
        
        cerebro.addobserver(bt.observers.DrawDown,plot=True)
        
        # Set our desired cash start
        cerebro.broker.setcash(100000.0)
        
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        
        # Run over everything
        strats = cerebro.run(runonce = False)
        
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
        
        # Plot the result
        cerebro.plot(style = 'candlestick', volume = False)
        

        Thanks in advance!

        hghhgghdf dfdf 1 Reply Last reply Reply Quote 0
        • Frank L
          Frank L last edited by

          Matheus Pires ,
          I got the same problem , besides bt.analyzers.PositionsValue , bt.analyzers.PyFolio have the same issue.
          regards

          1 Reply Last reply Reply Quote 0
          • hghhgghdf dfdf
            hghhgghdf dfdf @Matheus Pires last edited by

            @Matheus-Pires @Frank-L Use this:

            class adjPositionsValue(bt.analyzers.PositionsValue):
                def prenext(self):
                    pvals = [0 for d in self.datas]
            
                    if self.p.cash:
                        pvals.append(self.strategy.broker.get_cash())
            
                    if self._usedate:
                        self.rets[self.strategy.datetime.date()] = pvals
                    else:
                        self.rets[self.strategy.datetime.datetime()] = pvals
            
            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
            $(document).ready(function () { app.coldLoad(); }); }