有人可以看看我的以下 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 中使用它并且程序崩溃...
这是我的版本:
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
您可以使用
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