指数加权移动平均(EWMA或EWA)是量化交易中一种简单而强大的工具,特别适用于日内交易。它允许交易者快速轻松地跟踪指定时间段内证券的平均价格,并可用于识别趋势并进行交易决策。
通常来说EWMA的数学公式可以表示为如下:
EWMAt=αxt+(1−α)EWMAt−1
所以其关键在于α的计算,在pandas所提供的api中,提供了alpha
,halflife
,span
,com
这四个表示不同但是相互等价的参数,通常使用的多为alpha
和span
。
其中com
即为质心(Center of Mass),他的计算,可以认为是针对于每个时间点的权重的加权平均,所找到的位置,即:
CoM=t=0∑∞(1−α)tαt=α(1−α)t=0∑∞t(1−α)t−1=α(1−α)t=0∑∞[−(1−α)t]′=α(1−α)[−t=0∑∞(1−α)t]′=α(1−α)[−α1]′=α1−α
化简上式,我们可以得到:
α=1/(1+CoM)
半衰期(Half-life)即为权重衰减到一半所需要的时间,所以我们可以得到:
(1−α)H=0.5⇒α=1−exp(−Hlog2)
以上均为时间间隔等长的情况,当面对不同间隔的时间序列的时候,我们可以使用index
参数来指定时间序列的时间间隔,这样可以使得计算的结果更加准确。假设两个时间戳的间隔为dt
,那么我们可以使用如下的公式来计算alpha
:
α′=1−exp(−αdt)≈1−(1−αdt)=αdt
当时间间隔总是为1的时候,实际上和最开始的公式基本等价。
考虑一个情形,依次有三个时间戳,分别为t0
,t1
,t2
,那么dt1
和dt2
分别为t1 - t0
和t2 - t1
,那么我们可以使用如下的公式来计算alpha
:
EWMA2=α2x2+(1−α2)EWMA1=α2x2+(1−α2)(α1x1+(1−α1)EWMA0)=α2x2+α1(1−α2)x1+(1−α1)(1−α2)EWMA0
其中t0
时刻的权重为:
(1−α1)(1−α2)=exp(−αdt1−αdt2)=exp(−α(t2−t0))
这样即使当中有多个时间戳到达,对于同样间隔的数据点,其权重仍然一致。对应的python代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| from typing import Optional
import numpy as np
class EWMA(object): def __init__( self, com: Optional[float] = None, span: Optional[float] = None, halflife: Optional[float] = None, alpha: Optional[float] = None, ) -> None: assert ( (com is None) + (span is None) + (halflife is None) + (alpha is None) ) == 3, "only one of com, span, halflife, alpha should be not None" if com is not None: self.alpha = 1 / (1 + com) elif span is not None: self.alpha = 2 / (span + 1) elif halflife is not None: self.alpha = 1 - np.exp(np.log(0.5) / halflife) elif alpha is not None: self.alpha = alpha
def __call__(self, x: np.ndarray, index: Optional[np.ndarray] = None) -> np.ndarray: if index is not None: alpha = 1 - np.exp(-np.diff(index, prepend=0) * self.alpha) else: alpha = np.ones_like(x) * self.alpha
ewma = np.zeros_like(x) ewma[0] = x[0] for i in range(1, len(x)): ewma[i] = alpha[i] * x[i] + (1 - alpha[i]) * ewma[i - 1] return ewma
|