R语言编写函数实现指数加权移动方差(EWMV)计算
R实现指数加权移动方差(EWMV)的同步计算方案
问题背景
需要编写R函数实现指数加权移动方差(exponentially weighted moving variance, EWMV)计算,目前公开R包仅提供简单移动方差的计算能力,典型包括:
TTR包的runSD函数roll包的roll_SD函数
维基百科移动平均条目给出了EWMV的计算公式及参考文献,但落地实现存在两个障碍:
- 公式原理到可运行代码的转化逻辑不清晰
- 不明确条目提及的「EWMV可与指数移动平均同步便捷计算」的具体实现方式
已有适配滑动窗口的指数移动平均(EMA)自定义函数如下:
EMA <- function (price,n){ ema <- c() ema[1:(n-1)] <- NA ema[n]<- mean(price[1:n]) alpha <- 2/(n+1) for (i in (n+1):length(price)){ ema[i]<-alpha* price[i] + (1-alpha) * ema[i-1] } ema <- reclass(ema,price) return(ema) }
目标是将EWMV计算逻辑集成到上述EMA计算流程中,得到可运行的同步计算实现。
最终实现代码
经过公式核对与滑动场景适配,最终实现无第三方依赖的EWMV计算函数EMVar,内置同步EMA计算逻辑:
EMVar <- function(x, n){ alpha <- 2/(n+1) # 计算指数移动平均 ema <- c() ema[1:(n-1)] <- NA ema[n]<- mean(x[1:n]) for (i in (n+1):length(x)){ ema[i]<-alpha* x[i] + (1-alpha) * ema[i-1] } # 计算指数加权移动方差 delta <- x - lag(ema) emvar <- c() emvar[1:(n-1)] <- NA emvar[n] <- ifelse(n==1,0,var(x[1:n])) for(i in (n+1):length(x)){ emvar[i] <- (1-alpha) * (emvar[i-1] + alpha * delta[i]^2) } return(emvar) }
核心调整逻辑
- 复用计算中间值减少冗余运算:迭代式
EMA[i] = EMA[i-1] + alpha * delta与EMA标准计算公式alpha * x[i] + (1-alpha) * EMA[i-1]完全等价,EMA迭代过程中生成的差值delta可直接用于EWMV计算,无需重复遍历序列计算EMA。如果项目中已经加载TTR包,也可以直接调用包内置的EMA函数替换自实现的EMA逻辑,上述代码内置了完整EMA计算流程,无额外依赖。 - 适配自定义滑动窗口的初始化规则:维基百科给出的默认迭代逻辑从序列首个观测值
x[1]开始,对应初始值为EMA[1] = x[1]、EMVar[1] = 0,无法满足指定窗口长度(如n=20)的滑动计算需求。针对自定义窗口场景,采用和行业通用EMA计算一致的初始化方案:以窗口内样本的简单均值作为EMA初始值(即EMA[n] = mean(x[1:n])),对应以窗口内样本的简单方差作为EWMV初始值(即EMVar[n] = var(x[1:n])),计算结果和常规滑动指标的输出逻辑对齐。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

