指数加权移动标准差(EWMSD),单位为q/kdb+;

指数加权移动标准差(EWMSD),单位为q/kdb+;,kdb,Kdb,因为它比简单的标准差更好地预测波动性,所以我尝试用q语言编写指数加权移动标准差函数 我受到了q/k中ema函数增量实现的启发 q) ema k){(*y)(1f-x)\x*y} 上面有趣的部分是{xy\z}是{{z+y*x}\[x;y;z]}的缩写 这是我的刺,但是它扫描(\)输入向量y两次: q) .q.emdev:{sqrt 0f (1f-x)\0f^(1f-x)*x*d*d:y-prev ema[x;y]} q) (1%3) emdev 1,10#0 0 0.4714045 0.4969

因为它比简单的标准差更好地预测波动性,所以我尝试用
q
语言编写指数加权移动标准差函数

我受到了
q/k
ema
函数增量实现的启发

q) ema
k){(*y)(1f-x)\x*y}
上面有趣的部分是
{xy\z}
{{z+y*x}\[x;y;z]}
的缩写

这是我的刺,但是它扫描(
\
)输入向量
y
两次:

q) .q.emdev:{sqrt 0f (1f-x)\0f^(1f-x)*x*d*d:y-prev ema[x;y]}
q) (1%3) emdev 1,10#0
0 0.4714045 0.496904 0.4566233 0.3981362 0.3381504 0.2829914 0.2347385 0.1936388 0.1591718 0.1305404     
使用的核心递归公式(根据上述参考文件):


假设这是正确的,是否有人提出了更有效的实现方法?

我尝试实现它,以便它只使用增量公式扫描输入向量一次,并仅使用每个循环的上一个值返回每个循环中的下一个EMA和EMVAR,并获得与您相同的结果

myemdev:{sqrt (flip {((1f-x)*y[0]+x*d*d;y[1]+x*d:z-y[1])}[x]\[(0;first y);y]) 0}
q)myemdev[(1%3);1,10#0]
0 0.4714045 0.496904 0.4566233 0.3981362 0.3381504 0.2829914 0.2347385 0.1936388 0.1591718 0.1305404
但是,尽管它只在输入上循环一次,但这种方法比您的方法花费的时间要长得多

q)\t {sqrt 0f (1f-x)\0f^(1f-x)*x*d*d:y-prev ema[x;y]}[1%3;1,100000#0]
4
q)\t {sqrt (flip {((1f-x)*y[0]+x*d*d;y[1]+x*d:z-y[1])}[x]\[(0;first y);y]) 0}[1%3;1,100000#0]
189
q)\t ema[1%3;100000#0]
1
q)\t {{z+(1f-x)*y}[x]\[first y;y*x]}[1%3;1,100000#0]
57
从给出相同结果的这两个函数来看,很明显,
{x y\z}
形式的方法比以lambda形式写出的相同函数要快得多,尽管我不确定是否在引擎盖下实现优化

q)\t {(1)(1+x)\(x*y)}[0.005;1,1000000#0]
15
q)\t {{z+x*(1+y)}\[1;x;(x*y)]}[0.005;1,1000000#0]
711
虽然您的方法使用了两次扫描,但都是
{xy\z}
的形式,因此从我的角度来看,这两次扫描非常有效。使用纯增量方法仅对输入进行一次扫描的好处被无法将其转换为更有效的形式所抵消,正如这里重新排列的方法中的
(1f-x;1f)*y
{sqrt(flip{(1f-x;1f)*y+x*(d,1f)*d:z-y[1]}[x]\[(0;first y);y])0}
无法预先计算,因为我们没有所有可用的EMA值(根据需要计算每个循环)


我将继续寻找这两种方法的改进,我想看看是否有人能在效率方面击败你的方法

谢谢你,事实上,阅读listbox论坛,早在2013年,他们就决定将
{z+y*x}\
作为一个内置的C级函数,因为这是一个常见的标量问题