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 can I create an indicator and ignore div by 0 error in data?



  • I am trying to create an indicator and have some div by 0 error. Can you replace the div by 0 with 0 in the indicator?
    For some minute data, the high and low is the same. I will get a div by 0 for these minute bars.

    Also How could I do a Moving average of 15 minutes of f1 divided by the 15 total of price*volume?
    I am wondering how could I do this in a way like lambda

    Thanks!

    import backtrader as bt
    import backtrader.feeds as btfeed
    
    
    class customCSV(btfeed.GenericCSVData):
        params = (
            ('dtformat', '%Y-%m-%d %H:%M:%S'),
            ('datetime', 0),
            ('open', 1),
            ('high', 2),
            ('low', 3),
            ('close', 4),
            ('volume', 5),
            ('openinterest', -1)
        )
    
    
    class SmaCross(bt.SignalStrategy):
        params = (('pfast', 10), ('pslow', 30),)
    
        def __init__(self):
    
            self.data.f1=(self.data.close-self.data.open)/(self.data.high-self.data.low) * self.data.volume*(self.data.high+self.data.low) /2 
    
    
    cerebro = bt.Cerebro()
    
    data = customCSV(dataname='C:\\Test\\SPY.csv')
    
    cerebro.adddata(data)
    cerebro.addstrategy(SmaCross)
    cerebro.run()
    cerebro.plot()
    


  • Your question has two parts.
    Part 1: Try this out.

    self.data.f1 = bt.If(
    (self.data.high-self.data.low)!=0, 
    (self.data.close-self.data.open)/(self.data.high-self.data.low) * self.data.volume*(self.data.high+self.data.low) /2 
    , 
    0)
    

    Part 2:
    Have a look at this page and see if this helps.



  • thanks, run-out!
    I did try your code for part 1. But I still get the same error. Can you try ur code on this csv?

    http://www.sharecsv.com/dl/83a4571ad89d5e20bc01f9a84c686784/SPY.csv

    Here is the error:

    Traceback (most recent call last):
      File "C:/Users/XXX/PycharmProjects/TD/Test.py", line 41, in <module>
        cerebro.run()
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\cerebro.py", line 1127, in run
        runstrat = self.runstrategies(iterstrat)
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\cerebro.py", line 1293, in runstrategies
        self._runonce(runstrats)
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\cerebro.py", line 1652, in _runonce
        strat._once()
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\lineiterator.py", line 297, in _once
        indicator._once()
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\linebuffer.py", line 631, in _once
        self.once(self._minperiod, self.buflen())
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\linebuffer.py", line 755, in once
        self._once_op(start, end)
      File "C:\Users\XXX\AppData\Local\Programs\Python\Python38-32\lib\site-packages\backtrader\linebuffer.py", line 772, in _once_op
        dst[i] = op(srca[i], srcb[i])
    ZeroDivisionError: float division by zero
    


  • Please take a look at the following post. Quoting some code from there:

    class BollingerBandsPct(BollingerBands):
        '''
        Extends the Bollinger Bands with a Percentage line
        '''
        lines = ('pctb',)
        params = (('safediv', False), ('safezero', 0.0))
        plotlines = dict(pctb=dict(_name='%B'))  # display the line as %B on chart
    
        def __init__(self):
            super(BollingerBandsPct, self).__init__()
            if not self.p.safediv:
                self.l.pctb = (self.data - self.l.bot) / (self.l.top - self.l.bot)
            else:
                self.l.pctb = DivByZero(self.data - self.l.bot, self.l.top - self.l.bot, self.p.safezero)
    
    class BollingerBandsPct_SafeDiv(BollingerBandsPct):
        params = (('safediv', True),)
    

    Also the following doc may be relevant: https://www.backtrader.com/blog/2019-07-08-canonical-or-not/canonical-or-not/



  • @vladisld Thanks for your reply!
    I tried the MFI code here https://www.backtrader.com/blog/2019-07-17-mfi-generic/mfi-generic/ and the indicator is calculated and displayed.

    After I make minor changes, the indicator is not displaying anymore. But the code did run and plot is fine except no indicator. This is really weird. I have not tried the moving average yet.

    class MoneyFlowIndex(bt.Indicator):
        lines = ('mfi',)
        params = (
            ('period', 14),
        )
        def init(self):
            money_flow_raw = (self.data.high - self.data.low)
            money_flow_net = (self.data.close - self.data.open)
            mfiratio = bt.ind.DivByZero(money_flow_net, money_flow_raw, zero=0.5)*50+50
            self.l.mfi =  mfiratio
    cerebro = bt.Cerebro()
    
    data = customCSV(dataname='E:\\SPY.csv')
    
    cerebro.adddata(data)
    myind = MoneyFlowIndex(data)
    myind.plotinfo.subplot = True
    cerebro.add_signal(bt.SIGNAL_LONGSHORT, MoneyFlowIndex)
    cerebro.run()
    cerebro.plot()
    


  • I find out that I forget to use init method to initialize. Sorry


Log in to reply
 

});