我想写一个矢量化的代码版本,使用NumPy(或Pandas)计算Arnaud Legoux移动平均线(阿尔马)。你能帮我吗?谢谢。
非矢量化版本如下所示(见下文)。
def NPALMA(pnp_array, **kwargs) :
'''
ALMA - Arnaud Legoux Moving Average,
http://www.financial-hacker.com/trend-delusion-or-reality/
https://github.com/darwinsys/Trading_Strategies/blob/master/ML/Features.py
'''
length = kwargs['length']
# just some number (6.0 is useful)
sigma = kwargs['sigma']
# sensisitivity (close to 1) or smoothness (close to 0)
offset = kwargs['offset']
asize = length - 1
m = offset * asize
s = length / sigma
dss = 2 * s * s
alma = np.zeros(pnp_array.shape)
wtd_sum = np.zeros(pnp_array.shape)
for l in range(len(pnp_array)):
if l >= asize:
for i in range(length):
im = i - m
wtd = np.exp( -(im * im) / dss)
alma[l] += pnp_array[l - length + i] * wtd
wtd_sum[l] += wtd
alma[l] = alma[l] / wtd_sum[l]
return alma
2条答案
按热度按时间odopli941#
起始方式
我们可以沿着第一个轴创建滑动窗口,然后使用Tensor乘法与
wtd
值的范围进行求和约简。实现看起来像这样-
获取滑动窗口的函数:
strided_axis0
来自here
。使用
1D
卷积增强这些与
wtds
值的乘法,然后它们的求和约简基本上是沿着第一个轴的卷积。因此,我们可以沿着axis=0
使用scipy.ndimage.convolve1d
。考虑到内存效率,这将快得多,因为我们不会创建巨大的滑动窗口。实施将是-
因此,作为非零行的
out[length-1:]
将与avgs[:-length+1]
相同。如果我们使用
wtds
中非常小的内核数,可能会有一些精度差异。所以,如果使用这个convolution
方法,请记住这一点。运行时测试
方法-
时间-
g6ll5ycj2#
Divakar之前的答案中没有一个与TradingView的阿尔马v26.0产生的数字完全匹配。数字与参考匹配是至关重要的。考虑到这个目标,X1 m0n1x的Pine Script v5实现可以作为参考,即使它没有矢量化。
下面是一个NumPy版本,它产生与TradingView相同的输出:
以下是使用上述NumPy版本的Pandas版本:
对2023-04-14的$SPY的5分钟数据进行交叉检查,匹配到小数点后第五位。