N

Hi all, I'm coded a backtrader version of the Absolute Strength Histogram (ASH) indicator, wonder if I could get some feedback on "proper/optimized" ways of coding it.
Description and calculation of indicator is from : https://www.mql5.com/en/code/21429
My main issue, is that when coding, I created each line bar by bar, primarily in the "next()" function. And when calculating a weighted average, I couldn't seem to get a BT indicator function to work, so used "numpy" functions.
Another questions, most of the "lines" in my code are for calculations/storing values, is there a recommended way to store these data instead? My understanding is that lines should be mainly for plotting/output.
It seems to work, but clearly not optimal, hope for any suggestions! Thanks!
class ASH(bt.Indicator):
lines = ("SmthBulls", "SmthBears", "Bulls", "Bears", "AvgBulls", "AvgBears", "ash")
params = (("Mode", 0), #RSI = 0, Stoch = 1
("Length", 9),
("Smooth", 1),)
plotinfo = dict(plot=False, subplot=True)
def __init__(self):
self.addminperiod(self.p.Length+self.p.Smooth+5)
self.sma_close = bt.indicators.SMA(self.data, period=1)
self.highest = bt.indicators.Highest(self.data.high, period = self.p.Length)
self.lowest = bt.indicators.Lowest(self.data.low, period = self.p.Length)
def next(self):
if self.p.Mode == 0:
self.l.Bulls[0] = 0.5 * (math.fabs(self.sma_close[0] - self.sma_close[-1]) + (self.sma_close[0] - self.sma_close[-1]))
self.l.Bears[0] = 0.5 * (math.fabs(self.sma_close[0] - self.sma_close[-1]) - (self.sma_close[0] - self.sma_close[-1]))
if self.p.Mode == 1:
self.l.Bulls[0] = self.sma_close[0] - self.lowest[0]
self.l.Bears[0] = self.highest[0] - self.sma_close[0]
if not math.isnan(self.l.Bulls[-1*self.p.Length]) and not math.isnan(self.l.Bears[-1*self.p.Length]):
weights = np.array(range(1, self.p.Length + 1))
avgBullarray = np.array([])
avgBeararray = np.array([])
for i in range(-1 * self.p.Length+1, 1):
avgBullarray = np.append(avgBullarray, self.l.Bulls[i] )
avgBeararray = np.append(avgBeararray, self.l.Bears[i] )
self.l.AvgBulls[0] = np.average(avgBullarray, weights=weights)
self.l.AvgBears[0] = np.average(avgBeararray, weights=weights)
if not math.isnan(self.l.AvgBulls[-1*self.p.Smooth]) and not math.isnan(self.l.AvgBears[-1*self.p.Smooth]):
weights = np.array(range(1, self.p.Smooth + 1))
smthBullarray = np.array([])
smthBeararray = np.array([])
for i in range(-1 * self.p.Smooth+1, 1):
smthBullarray = np.append(smthBullarray, self.l.AvgBulls[i] )
smthBeararray = np.append(smthBeararray, self.l.AvgBears[i] )
self.l.SmthBulls[0] = np.average(smthBullarray, weights=weights)
self.l.SmthBears[0] = np.average(smthBeararray, weights=weights)
self.l.ash[0] = self.l.SmthBulls[0] - self.l.SmthBears[0]