计算指数加权移动平均线

我正在尝试一个相当简单的函数来计算Excel VBA中的指数加权移动平均波动率。 但是,我觉得我的function有些错误,我不能确定,因为我没有得到正确的解决scheme。

Function EWMA(numbers As Range, Lambda As Single) As Double Dim mean As Double Dim x As Double Dim c As Range Dim n As Integer mean = WorksheetFunction.Average(numbers) n = WorksheetFunction.Count(numbers) For Each c In numbers x = x + (Lambda ^ (n - c.Count)) * ((c.Value - mean) ^ 2) Next c EWMA = (1 - Lambda) * x End Function 

我正在使用的价值和目标波动率(使用电子表格EWMA计算)在这里 。

我究竟做错了什么?

更新:使用Ron Rosenfeld的解决scheme:

 Option Explicit Function EWMA(Zero As Range, Lambda As Double) As Double Dim vZero As Variant Dim SumWtdRtn As Double Dim I As Long Dim vPrices As Variant Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double vZero = Zero For I = 2 To UBound(vZero, 1) vPrices = 1 / ((1 + vZero(I, 1)) ^ (3 / 12)) LogRtn = Log(vPrices(I - 1, 1) / vPrices(I, 1)) RtnSQ = LogRtn ^ 2 WT = (1 - Lambda) * Lambda ^ (I - 2) WtdRtn = WT * RtnSQ SumWtdRtn = SumWtdRtn + WtdRtn Next I EWMA = SumWtdRtn ^ (1 / 2) End Function 

这里有一个与VBA函数不同的方法。 input是一个价格数组,假定您按照降序显示,Lambda。 希望variables的名字能让你看到逻辑:

 Option Explicit Function EWMA2(Prices As Range, Lambda As Double) As Double Dim vPrices As Variant Dim dSumWtdRtn As Double Dim I As Long Dim dLogRtn As Double, dRtnSQ As Double, dWT As Double, dWtdRtn As Double vPrices = Prices For I = 2 To UBound(vPrices, 1) dLogRtn = Log(vPrices(I - 1, 1) / vPrices(I, 1)) dRtnSQ = dLogRtn ^ 2 dWT = (1 - Lambda) * Lambda ^ (I - 2) dWtdRtn = dWT * dRtnSQ dSumWtdRtn = dSumWtdRtn + dWtdRtn Next I EWMA2 = dSumWtdRtn ^ (1 / 2) End Function 

使用您的数据,它会得到与电子表格计算相同的结果(在数据types的精度范围内)

编辑

如果您想要input3M CAD Zero Rates作为范围input,而不是定价,那么您可以修改上述内容,以根据收益数据计算两个相关的价格。 在这种情况下,这将是:

 Option Explicit Function EWMAV(Zeros As Range, Lambda As Double) As Double Dim vZeros() As Variant Dim dPrice1 As Double, dPrice2 As Double Dim dSumWtdRtn As Double Dim I As Long Dim dLogRtn As Double, dRtnSQ As Double, dWT As Double, dWtdRtn As Double vZeros = Zeros For I = 2 To UBound(vZeros, 1) dPrice1 = 1 / ((1 + vZeros(I - 1, 1)) ^ (3 / 12)) dPrice2 = 1 / ((1 + vZeros(I, 1)) ^ (3 / 12)) dLogRtn = Log(dPrice1 / dPrice2) dRtnSQ = dLogRtn ^ 2 dWT = (1 - Lambda) * Lambda ^ (I - 2) dWtdRtn = dWT * dRtnSQ dSumWtdRtn = dSumWtdRtn + dWtdRtn Next I EWMAV = dSumWtdRtn ^ (1 / 2) End Function