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

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?


    from __future__ import (absolute_import, division, print_function,
    import backtrader as bt
    from datetime import datetime
    from backtrader.indicators import EMA
    from backtrader.indicators import StdDev
    import backtrader.indicators as btind
    class RVI(bt.Indicator):
        lines = ('dummyline',)
        params = (('value', 5),)
        def __init__(self):
            stDevHi = StdDev(, period=10)
            stDevLo = StdDev(, period=10)
            avgStDevHiUp = bt.If(  >,EMA(stDevHi, period = 14), 0)
            avgStDevHiDown= bt.If(  <,EMA(stDevHi, period = 14), 0)
            avgStDevLoUp = bt.If(  >,EMA(stDevLo, period = 14), 0)
            avgStDevLoDown = bt.If(  <,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.sma = btind.EMA(, period = 20)
        def next(self):
            if not self.position:
                if (self.sma < and self.rsi_small > self.rsi_small[-1]):
                if (self.sma > and self.rsi_small < self.rsi_small[-1]):
                if self.rsi_small < self.rsi_small[-1] and < self.sma and self.position.size > 0:
                if self.rsi_small > self.rsi_small[-1] and > self.sma and self.position.size < 0:
    #Variable for our starting cash
    startcash = 10000
    #Create an instance of cerebro
    cerebro = bt.Cerebro()
    #Add our strategy
    #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(
        fromdate = datetime(2000,1,1),
        todate = datetime(2020,1,1),
        timeframe = bt.TimeFrame.Days,
        buffered= True
    #Add the data to Cerebro
    # Set our desired cash start
    # Run over everything
    #Get final portfolio Value
    portvalue =
    pnl = portvalue - startcash
    #Print out the final result
    print('Final Portfolio Value: ${}'.format(portvalue))
    print('P/L: ${}'.format(pnl))
    #Finally plot the end results

    Thanks for any help

  • Have a look here. bt.DivByZero

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

Log in to reply