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

# Custom Indicator RVI; float division by zero

• So I am trying to build the relative volatility index indicator in backtrader. However, I get an error:

``````dst[i] = op(srca[i], srcb[i])                                                                                       ZeroDivisionError: float division by zero
``````

I understand that there are multiple points in my indicator logic where a division by zero could occur, such as rviHi declaration. However, I can't seem to find a way to fix this. Can anyone with knowledge of the relative volatility index check if my math/formula is right? Or is this a logic/programming error I committed?

Code:

``````from __future__ import (absolute_import, division, print_function,
unicode_literals)
from datetime import datetime

class RVI(bt.Indicator):
lines = ('dummyline',)

params = (('value', 5),)

def __init__(self):
stDevHi = StdDev(self.data.high, period=10)
stDevLo = StdDev(self.data.low, period=10)
avgStDevHiUp = bt.If(self.data.high  > self.data.high(-1),EMA(stDevHi, period = 14), 0)

avgStDevHiDown= bt.If(self.data.high  < self.data.high(-1),EMA(stDevHi, period = 14), 0)

avgStDevLoUp = bt.If(self.data.low  > self.data.low(-1),EMA(stDevLo, period = 14), 0)

avgStDevLoDown = bt.If(self.data.low  < self.data.low(-1),EMA(stDevLo, period = 14), 0)

rviHi = bt.If((avgStDevHiDown + avgStDevHiUp) == 0, 50, (100* avgStDevHiUp) / (avgStDevHiUp + avgStDevHiDown))

rviLo = bt.If((avgStDevLoUp + avgStDevLoDown) == 0,50, (100* avgStDevLoUp) / (avgStDevLoUp + avgStDevLoDown))

self.lines.dummyline = (rviHi + rviLo) / 2
class firstStrategy(bt.Strategy):

def __init__(self):
self.rsi_small = RVI(self.data)
self.sma = btind.EMA(self.data, period = 20)

def next(self):
if not self.position:
if (self.sma < self.data.close and self.rsi_small > self.rsi_small[-1]):
#print(self.datetime.date())
if (self.sma > self.data.close and self.rsi_small < self.rsi_small[-1]):
self.sell(size=10)
#print('{},SELL,{}'.format(self.datetime.datetime(), self.data.close[0]))
#print(self.datetime.date())
else:
if self.rsi_small < self.rsi_small[-1] and self.data.close < self.sma and self.position.size > 0:
self.close(size=10)
if self.rsi_small > self.rsi_small[-1] and self.data.close > self.sma and self.position.size < 0:
self.close(size=10)

#Variable for our starting cash
startcash = 10000

#Create an instance of cerebro
cerebro = bt.Cerebro()

#Get Apple data from Yahoo Finance.
#data = bt.feeds.Quandl(
#    dataname='AAPL',
#    fromdate = datetime(2016,1,1),
#    todate = datetime(2017,1,1),
#    buffered= True
#    )
data = bt.feeds.YahooFinanceData(
dataname='AAPL',
fromdate = datetime(2000,1,1),
todate = datetime(2020,1,1),
timeframe = bt.TimeFrame.Days,
buffered= True
)

# Set our desired cash start
cerebro.broker.setcash(startcash)

# Run over everything
cerebro.run()

#Get final portfolio Value
portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash

#Print out the final result
print('Final Portfolio Value: \${}'.format(portvalue))
print('P/L: \${}'.format(pnl))

#Finally plot the end results
cerebro.plot(style='candlestick')
``````

Thanks for any help

• Have a look here. bt.DivByZero

• Thank you, thats exactly what I needed. Didn't realize backtrader had this function.

});