Экспоненциально взвешенное скользящее стандартное отклонение (EWMSD) в q / kdb + - PullRequest
0 голосов
/ 06 июня 2018

Так как он лучше прогнозирует волатильность, чем простое стандартное отклонение, я попытался написать экспоненциально взвешенное скользящее стандартное отклонение на языке q, используя это инкрементное определение .

Меня вдохновила инкрементная реализация функции ema в q/k.

q) ema
k){(*y)(1f-x)\x*y}

Интересная часть выше - то, что {x y\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     

Используемая базовая формула рекурсии (в соответствии с указанным выше документом):

enter image description here

Предполагая, что это правильно,кто-нибудь придумал более эффективную реализацию?

1 Ответ

0 голосов
/ 08 июня 2018

Я попытался реализовать его так, чтобы он сканировал входной вектор только один раз, используя формулу приращения, и возвращал следующие 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} намного быстрее, чем та же функция, что и лямбда, хотя я не уверен в реализации оптимизации под капотом.

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

Хотя в вашем методе используются два сканирования, обаимеют форму {x y\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 (они рассчитываются для каждого цикла по мере необходимости).

Я буду продолжать искать улучшения в обоих методах, и мне было бы интересно узнать, сможет ли кто-нибудь превзойти ваш метод в терминахКПД

...