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.