0

can someone look on my implementation of bellow pinescript indicator:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © veryfid

//@version=4

study(title = "ZLSMA - Zero Lag LSMA", shorttitle="ZLSMA", overlay=true, resolution="")
length = input(title="Length", type=input.integer, defval=32)
offset = input(title="Offset", type=input.integer, defval=0)
src = input(close, title="Source")
lsma = linreg(src, length, offset)
lsma2 = linreg(lsma, length, offset)
eq= lsma-lsma2
zlsma = lsma+eq

plot(zlsma, color=color.yellow, linewidth=3)

I trying to code it in python like this:

class BarIndex_ind(bt.Indicator):
    lines = ('index', )

    def __init__(self):
        pass

    def next(self):
        self.lines.index[0] = len(self.data)+1

class LinReg(bt.Indicator):
    lines = ('line',)
    params = (
        ('length', 32),
        ('source', None),
        ('offset', 0), #not using now
    )

    def __init__(self):
        #self.addminperiod(self.p.length)
        self.barindex = BarIndex_ind()
        self.x_ = bt.ind.SMA(self.barindex, period=self.p.length)
        self.y_ = bt.ind.SMA(self.p.source, period=self.p.length)
        self.mx = bt.ind.StdDev(self.barindex, period=self.p.length)
        self.my = bt.ind.StdDev(self.p.source, period=self.p.length)
    
    def next(self):
        c = correlate(self.barindex.get(size=self.p.length), self.p.source.get(size=self.p.length), self.p.length)
        slope = c[1] * (self.my[0]/self.mx[0])
        inter = self.y_[0] - slope * self.x_[0]
        linreg = self.barindex[0] * slope + inter
        self.l.line[0] = linreg

class ZLSMA(bt.Indicator):
    lines = ('line',)
    params = (
        ('length', 32),
        ('offset', 0),
    )

    def __init__(self):
        #self.addminperiod(2*self.p.length)
        self.lsma = LinReg(source=self.data.close, length=self.p.length)
        self.lsma2 = LinReg(source=self.lsma.line, length=self.p.length)
    
    def next(self):
        eq = self.lsma[0] - self.lsma2[0]
        self.l.line[0] = self.lsma[0] + eq

It looks like when I run it and use ZLSMA class - it works fine in line (or maybe not...): self.lsma = LinReg(source=self.data.close, length=self.p.length) ...but when it go forward to line: self.lsma2 = LinReg(source=self.lsma.line, length=self.p.length) ...it seems that self.lsma is empty and I cannot use it in LinReg and program crashes...

Papay
  • 1

1 Answers1

0

Here is my version :

def lsma(data, period=14, regression=True):
    size = len(data)
    out = np.full(size, np.nan)
    w = np.arange(1, period + 1, dtype=np.float64)
    if regression:
        for i in range(period - 1, size):
            e = i + 1
            s = e - period
            intercept, slope = np.dot(np.linalg.pinv(np.vstack((np.ones(period), w)).T), data[s:e])
            out[i] = slope * period + intercept
    else:
        for i in range(period - 1, size):
            e = i + 1
            s = e - period
            out[i] = np.dot(data[s:e], w) / np.sum(w)
    return out


def zlsma(data, period=14, regression=True):
    size = len(data)
    sum_w = np.sum(np.arange(1, period + 1, dtype=np.float64))
    lsma_v = lsma(data, period, regression)
    out = np.full(size, np.nan)
    w = sum_w / (2 * np.sum(np.arange(1, period)))
    for i in range(period - 1, size):
        out[i] = lsma_v[i] + (data[i] - lsma_v[i]) * w
    return out
Rom
  • 192
  • 1
  • 5