How to calculate indicator line using prior period values?
-
I'm attempting to write an indicator based off a projected moving average formula (CP2) which also has Lamberts Marker Direction Formula (MDI) in there as well.
My issue is that I need to use prior period values of CP2 to calculate the MDI formula but I'm not sure of the best approach as I understand that most of the calculations should be done in the init() function.
Here is what I have so far and as you can see I have attempted to use an array to store the CP2 values which is probably not best practice but getting the 'IndexError: list index out of range' error because it can't access the values. I guess I mostly need help in how to write this in the best practice format.
from __future__ import (absolute_import, division, print_function, unicode_literals) # Import the backtrader platform import backtrader as bt import math from decimal import * class ProjectedMovingAverageIndicator(bt.Indicator): lines = ('CP2','MDI',) params = (('periodSlow', 100),('periodFast', 25),('movav', bt.indicators.MovAv.Simple),) plotinfo = dict(subplot=True) plotlines = dict( CP2=dict(_samecolor=False), MDI=dict(_samecolor=False), ) def __init__(self): self.addminperiod(self.params.periodSlow) # Calculate moving averages self.movavSlow = self.p.movav(self.data.close, period=self.p.periodSlow) self.movavFast = self.p.movav(self.data.close, period=self.p.periodFast) self.CP2 = [] def next(self): # Perry Kaufman project moving average self.CP2.append(self.p.periodSlow * ((self.movavSlow[0] - self.data.close[-1]) / self.p.periodSlow) - ((self.movavFast[0] - self.data.close[-1]) / self.p.periodFast)) # Market Direction Indicator MDI = 100 * (self.CP2[-2] - self.CP2[-1]) / ((self.data.close[-1] + self.data.close[-1]) / 2) # Create lines self.l.CP2[0] = self.CP2[-1] self.l.MDI[0] = MDI print("CP2: ", CP2[-1], " MDI: ", MDI)
Thanks
-
IMHO the better way is to define the CP2 line using delaying indexing. See Delayed Indexing Concept.
Probably something like:
def __init__(self): self.addminperiod(self.params.periodSlow) # Calculate moving averages self.movavSlow = self.p.movav(self.data.close, period=self.p.periodSlow) self.movavFast = self.p.movav(self.data.close, period=self.p.periodFast) # Perry Kaufman project moving average self.CP2 = self.p.periodSlow * ((self.movavSlow(0) - self.data.close(-1)) / self.p.periodSlow) - ((self.movavFast(0) - self.data.close(-1)) / self.p.periodFast) def next(self): # Market Direction Indicator MDI = 100 * (self.CP2[-2] - self.CP2[-1]) / ((self.data.close[-1] + self.data.close[-1]) / 2) # Create lines self.l.CP2[0] = self.CP2[-1] self.l.MDI[0] = MDI print("CP2: ", self.CP2[-1], " MDI: ", MDI)
-
@vladisld said in How to calculate indicator line using prior period values?:
Market Direction Indicator
MDI = 100 * (self.CP2[-2] - self.CP2[-1]) / ((self.data.close[-1] + self.data.close[-1]) / 2) # Create lines self.l.CP2[0] = self.CP2[-1] self.l.MDI[0] = MDI print("CP2: ", self.CP2[-1], " MDI: ", MDI)
Amazing, thanks @vladisld!