我正在重新访问Excel VBA中的一些旧代码并尝试将其转换为Access VBA。调整Excel VBA函数以访问VBA
此代码需要一系列数字(“零”)并计算“Lambda”权重的简单加权平均值。此计算和此代码工作正常,并已验证为正确。
Excel代码如下。
Option Explicit
Function EWMA(Zeros As Range, Lambda As Double, MarkDate As Date, MaturityDate As Date) As Double
Dim vZeros() As Variant
Dim Price1 As Double, Price2 As Double
Dim SumWtdRtn As Double
Dim I As Long
Dim m As Double
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
vZeros = Zeros
m = Month(MaturityDate) - Month(MarkDate)
For I = 2 To UBound(vZeros, 1)
Price1 = 1/((1 + vZeros(I - 1, 1))^(m/12))
Price2 = 1/((1 + vZeros(I, 1))^(m/12))
LogRtn = Log(Price1/Price2)
RtnSQ = LogRtn^2
WT = (1 - Lambda) * Lambda^(I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn^(1/2)
End Function
现在我试图在Access VBA中重现这个相同的功能。此代码引用一个表格(“HolderTable”),它由与上述Excel代码中的“零”范围完全相同的数字组成。在Access中,这些被标记为“InterpRate”。然后,它应用与Excel代码中完全相同的计算,但适用于Access语法。
接入码如下:
Function EWMA(Lambda As Double) As Double
Dim Price1 As Double, Price2 As Double
Dim vInterpRate() As Variant
Dim SumWtdRtn As Double
Dim I As Long
Dim m As Double
Dim rec As Recordset
Dim LogRtn As Double, RtnSQ As Double, WT As Double, WtdRtn As Double
m = 3
Dim x As Integer
Set rec = CurrentDb.OpenRecordset("SELECT InterpRate FROM HolderTable")
x = 1
Do While rec.EOF = False
ReDim Preserve vInterpRate(x + 1)
vInterpRate(x) = rec("InterpRate")
x = x + 1
rec.MoveNext
Loop
For I = 1 To x
Price1 = 1/((1 + vInterpRate(I - 1))^(m/12))
Price2 = 1/((1 + vInterpRate(I))^(m/12))
LogRtn = Log(Price2/Price1)
RtnSQ = LogRtn^2
WT = (1 - Lambda) * Lambda^(I - 2)
WtdRtn = WT * RtnSQ
SumWtdRtn = SumWtdRtn + WtdRtn
Next I
EWMA = SumWtdRtn^(1/2)
End Function
理想的情况下,这些应该产生完全相同的数字。 “零”范围和“interpRate”数字是相同的。我怀疑问题出在我如何在Access中定义我的数组,但我似乎无法修复它。两个守则之间是否有不一致?
作为参考,我附上了Excel电子表格,附有VBA代码。 http://www.filedropper.com/soewma_1
难道只是x在您的访问版本中增加了1倍太多? –
我认为这可能是可能的,我怎么能改变它来解决这个问题? – beeba
最简单的方法是在你的Do ... While循环中添加“x = x - 1” –