创建 ZeroLagLSMA 指标时出现问题

问题描述 投票:0回答:2

有人可以看看我的以下 pinescript 指标的实现吗:

// 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)

我尝试用Python编写它,如下所示:

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

看起来当我运行它并使用 ZLSMA 类时 - 它在线工作正常(或者可能不......): self.lsma = LinReg(源=self.data.close, 长度=self.p.length) ...但是当它前进到线路时: self.lsma2 = LinReg(源=self.lsma.line, 长度=self.p.length) ...看来 self.lsma 是空的,我无法在 LinReg 中使用它并且程序崩溃...

python pine-script backtrader
2个回答
1
投票

这是我的版本:

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

0
投票

您可以使用

zlma
库中的
pandas_ta

import pandas_ta as pd_ta

# Assuming you have a DataFrame 'df' with a 'close' column
df['zlma'] = pd_ta.zlma(df['close'], length=32, mamode='simple')

mamode:此参数确定

zlma
计算内部使用的移动平均线类型。通过将其设置为“简单”,您将指定应使用简单移动平均线 (SMA)。如果您喜欢使用指数移动平均线,您可以将其设置为
EMA

您可以使用 pip 安装

pandas_ta

pip install pandas_ta
© www.soinside.com 2019 - 2024. All rights reserved.