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?
-
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
-
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!
-
Matheus Pires ,
I got the same problem , besides bt.analyzers.PositionsValue , bt.analyzers.PyFolio have the same issue.
regards -
@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