我正在重新訪問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」 –