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

Problem mixing inheritance and recursive indicator



  • I am having a problem getting the subclassed signal from the Trix example when I generate the signal using the recursive EMA version from the blog.

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import backtrader as bt
    import backtrader.indicators as btind
    
    
    class MyTrix(bt.Indicator):
    
        lines = ('trix',)
        params = (('period', 15),)
    
        def __init__(self):
            ema1 = btind.EMA(self.data, period=self.p.period)
            ema2 = btind.EMA(ema1, period=self.p.period)
            ema3 = btind.EMA(ema2, period=self.p.period)
    
            self.lines.trix = 100.0 * (ema3 - ema3(-1)) / ema3(-1)
    
    
    class MyTrixSignalInherited(MyTrix):
    
        lines = ('signal',)
        params = (('sigperiod', 30),)
    
        def __init__(self):
            super(MyTrixSignalInherited, self).__init__()
            self.lines.signal = MyEMA(self.lines.trix, period=self.p.sigperiod)
    
    
    class MyEMA(bt.indicators.PeriodN):
        params = {'period': 30}  # even if defined, we can redefine the default value
        lines = ('ema',)  # our output line
    
        def __init__(self):
            self.alpha = 2.0 / (1.0 + self.p.period)  # period -> exp smoothing factor
    
        def nextstart(self):  # calculate here the seed value
            self.lines.ema[0] = self.data[-1] / self.p.period
    
        def next(self):
            ema1 = self.lines.ema[-1]  # previous EMA value
            self.lines.ema[0] = ema1 * (1.0 - self.alpha) + self.data[0] * self.alpha
    

    Here is a short snippet of the output and the strategy...

    class NoStrategy(bt.Strategy):
        params = (('trixperiod', 20),
                  ('analyzer', False),)
    
        def __init__(self):
            self.trix = MyTrixSignalInherited(self.data, period=self.p.trixperiod)
    
        def next(self):
            print('Trix: %.2f, Signal: %.2f' % (self.trix.trix[0], self.trix.signal[0]))
    
    Trix: -0.07, Signal: nan
    Trix: -0.23, Signal: nan
    Trix: -0.37, Signal: nan
    Trix: -0.53, Signal: nan
    Trix: -0.69, Signal: nan
    Trix: -0.83, Signal: nan
    Trix: -0.97, Signal: nan
    Trix: -1.07, Signal: nan
    Trix: -1.12, Signal: nan
    Trix: -1.11, Signal: nan
    

    Any suggestions on how to get the signal to get calculated properly?



  • Maybe another hint may help someone help me figure this out. Within the subclass, using the standard EMA indicator works...

    class MyTrixSignalInherited(MyTrix):
    
        lines = ('signal',)
        params = (('sigperiod', 30),)
    
        def __init__(self):
            super().__init__()        
            self.lines.signal = btind.EMA(self.lines.trix, period=self.p.sigperiod)
    

    It is only when using the recursive version that the nan values appear. By debugging, I am seeing that even within nextstart, the item "self.data" is full of nan values.

    Unfortunately, my true use case involves a similarly developed recursive indicator, so I really need to figure out why it seems to be receiving nan values from the lines output of the parent class.



  • Further testing shows that if I remove the "next" method from the recursive indicator (rendering it non-recursive), that the indicator correctly receives the data from the parent class. That makes me start to think that this is actually a bug.