计算指数加权移动平均线

时间:2015-10-20 14:34:08

标签: excel vba excel-vba

我正在尝试一个相当简单的函数来计算Excel VBA中following的指数加权移动平均波动率。但是,我认为我的功能中存在一些我无法查明的错误,因为我没有得到正确的解决方案。

 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计算)为here

我做错了什么?

更新:使用Ron Rosenfeld的解决方案:

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

1 个答案:

答案 0 :(得分:1)

这里采用VBA功能的方式有点不同。输入是一个价格数组,假设你显示的是降序,还有Lambda。希望变量的名称可以让你看到逻辑:

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

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

修改

如果您想输入3M CAD Zero Rates作为范围输入而不是定价,那么您可以修改上述内容以根据退货数据计算两个相关价格。在这种情况下,它将是:

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