@junajo10 a possible approach to keep it clear is to separate the OLS_Beta in 2 parts

```
class OLS_Slope_Intercept(bt.indicators.PeriodN):
_mindatas = 2 # ensure at least 2 data feeds are passed
lines = ('slope', 'intercept',)
params = (('period', 10),)
def next(self):
p0 = pd.Series(self.data0.get(size=self.p.period))
p1 = pd.Series(self.data1.get(size=self.p.period))
p1 = sm.add_constant(p1, prepend=True)
slope, intercept = sm.OLS(p0, p1).fit().params
self.lines.slope[0] = slope
self.lines.intercept[0] = intercept
class OLS_Transformation(bt.indicators.PeriodN):
_mindatas = 2 # ensure at least 2 data feeds are passed
lines = ('spread', 'spread_mean', 'spread_std', 'zscore',)
params = (('period', 10),)
def __init__(self):
self._slint = OLS_Slope_Intercept(*self.datas)
self.l.spread = self.data0 - (self._slint.slope * self.data1 + self._slint.intercept)
self.l.spread_mean = bt.ind.SMA(self.l.spread, period=self.p.period)
self.l.spread_std = bt.ind.StdDev(self.l.spread, period=self.p.period)
self.l.zscore = (self.l.spread - self.l.spread_mean) / self.l.spread_std
```