Custom Indicator Help
-
I want to calculate a moving average and rolling standard deviations(Kinda like Bollinger Bands) but I want to calculate this on the spread that I have calculated using the returns of two stocks. I tried using indicators such as bt.SMA and such but I kept getting errors. I eventually just manually calculated the deviation bands and MA but was hoping someone could show me what is the right way to do it, because the manual results doesn't look 100% correct either.
Keep in mind this is part of an indicator class.def next(self): l0_pct_change = ( np.array(self.line0.get(ago=0, size=self.p.period_beta)) / np.array(self.line0.get(ago=-1, size=self.p.period_beta)) - 1 ) self.line1.idx = self.line0.idx l1_pct_change = ( np.array(self.line1.get(ago=0, size=self.p.period_beta)) / np.array(self.line1.get(ago=-1, size=self.p.period_beta)) - 1 ) model = sm.OLS(l0_pct_change, l1_pct_change) self.l.beta[0] = model.fit().params self.l.spread[0] = l0_pct_change[0] - l1_pct_change[0]*self.l.beta[0] #These are the lines of code in question datasum = math.fsum(self.l.spread.get(size=self.p.period_beta)) self.l.spread_sma15[0] = datasum / self.p.period_beta self.l.spread_2sd[0] = ((((datasum-self.lines.spread_sma15)**2)/self.p.period_beta)**0.5)*2 self.l.spread_m2sd[0] = ((((datasum - self.lines.spread_sma15) ** 2) / self.p.period_beta) ** 0.5) * -2
-
@ssbilis I would like to ask a clarifying question if I may. Are you trying to do the following:
- Use two lines.
- Calculate the one (could be more than one) period return for each line.
- Create moving averages for each line and then subtract the lines from each other.
- Calcualate standard deviation bands on the result from three.
Does this reflect what you are trying to do?
-
@run-out Kinda.
I want to create a pairs trading strategy.
Where I calculate the spread using the returns of the two assets. Then I want to calculate the moving average and standard deviation of the spread.
You get what I am saying? -
@ssbilis I think you could do a lot of the calculations in your
__init__
method and then just access them innext()
to simplify things. Something like this (if I'm understanding what you are trying to do). Note, I'm faking the beta calculation since I'm not familiar with thestatsmodel
library.class St(bt.Strategy): def __init__(self): self.amdrets = (self.datas[0].close / self.datas[0].close(-1) - 1) self.intcrets = (self.datas[1].close / self.datas[1].close(-1) - 1) beta = calc_beta(self.amdrets, self.intcrets) self.spread = self.amdrets - self.intcrets * beta self.spread_sma = MovingAverageSimple(self.spread, period=15) self.spread_p2sd = StandardDeviation(self.spread_sma, period=15) * 2 self.spread_m2sd = -self.spread_p2sd def next(self): print(f'amd: {self.amdrets[0]}, intc: {self.intcrets[0]}, spread: {self.spread[0]}, sma: {self.spread_sma[0]}, +2sd: {self.spread_p2sd[0]}, -2sd: {self.spread_m2sd[0]}')
-
@davidavr said in Custom Indicator Help:
self.spread_m2sd = -self.spread_p2sd
This is actually very helpful thank you