簡體   English   中英

如何計算列時間序列下Excel VBA的月波動率

[英]How to Calculate the Monthly Volatility in Excel VBA Under Column Time Series

'H'列是年份數據列,'I'列是月份數據列,'D'列是我們想要計算每月波動率的10年期債券收益率。 這是這個問題的另一個改進代碼,請幫幫我。 返回仍然是#NAME。 感謝@Comintern的回答。 根據@ Comintern的建議,我修改了代碼。 在名稱管理器中,'Yr'表示年份的列(H3:H3696),'M'表示月份的列(I3:I3696),'C_10'表示中國10年的原始收益率數據國債。

現在,我想獲得收益率的月度波動率。

Function Volatility(n As Variant) As Variant
'this function uses to calculate volatility of a bond yield
'"n" is the number of data/date we need to calculate
'please manage the data name in the name manager of formulas
Dim i As Integer, dnum As Integer, mnum As Integer, vectornum As Integer
'dnum count day number, mnum count month number
Dim Result(), TempSave() As Variant
Dim Yr, M As Range
vectornum = Int(n / 20) + 1
ReDim Result(vectornum) As Variant

Yr = ActiveWorkbook.Names("Yr").Value
M = ActiveWorkbook.Names("M").Value
Bond = ActiveWorkbook.Names("C_10").Value

For i = 1 To n
    If Yr(i) = Yr(i + 1) And M(i) = M(i + 1) Then
        dnum = dnum + 1
        ReDim Preserve TempSave(1 To dnum)
        TempSave(dnum) = Bond(i)
        'this is the temporary data container for the same month bond yield
    Else
        TempSave(dnum + 1) = Bond(i)
        'because there is a gap between two month, so, we add the last 'same month bond yield' back
        dnum = 0
        mnum = mnum + 1
        Result(mnum) = Application.WorksheetFunction.StDev_S(TempSave)
    End If
Next i

Volatility = Result
End Function

此代碼有多個問題。 至於#NAME錯誤,您可能只需要將該功能移動到模塊中。 我還建議明確公開:

Public Function Volatility(n As Variant) As Variant

我還會刪除Option Base 0 - 它是默認基礎。 您正在使用的唯一數組是由Excel(因此它們將始終為基數1)和TempSave ,您在此處明確聲明其下限為1:

ReDim Preserve TempSave(1 To dnum)

我會重命名你的YearMonth變量。 兩者都是VBA函數的名稱,並且您的局部變量正在隱藏它們。

這段代碼......

dnum = 0
mnum = 0

...什么都不做 - 變量總是初始化為默認值。 雖然在這種情況下,默認值為Empty (將隱式轉換為0),因為您(可能意外地)將它們聲明為Variant

Dim i, j, dnum, mnum, vectornum As Integer

如果他們都應該是Integer ,你需要明確聲明:

Dim i As Integer, j As Integer, dnum As Integer, mnum As Integer, vectornum As Integer

你可以從循環計數中刪除Step 1 - 它是默認值,但它也需要從1開始,而不是0 (再次,Excel的數組是基數1):

For i = 0 To n Step 1

這條線......

If Year(i) = Year(i + 1) And Month(i) = Month(i + 1) Then

...將給出“下標超出范圍”錯誤,因為如果Range.Value引用多個單元格,您將獲得一個二維數組。 這意味着您需要提供兩個索引。 我假設這些都在同一列中,所以它應該是:

If Year(I, 1) = Year(i + 1, 1) And Month(I, 1) = Month(i + 1, 1) Then

你有相反的問題:

    ReDim Preserve TempSave(1 To dnum)
    TempSave(i, 1) = Bond(i)

您將TempSave聲明為一維數組,但嘗試使用2維對其進行索引。 請注意,您只能ReDim Preserve最高維度,因此如果需要創建具有動態邊界的列,則需要從源陣列計算長度或轉置它。 Bond也將是一個二維數組(假設ActiveWorkbook.Names("C_10")不止一個單元格)。

如果您的任何范圍 1個單元格,這些分配將為您提供類型不匹配:

Year = ActiveWorkbook.Names("Year").Value
Month = ActiveWorkbook.Names("Month").Value
Bond = ActiveWorkbook.Names("C_10").Value

最后, Volatility = Result可能沒有返回它應該返回的內容,因為你將它聲明為:

ReDim Result(vectornum, 1) As Variant

當您從UDF返回Variant數組時,您將只獲得數組中的第一個值 - 在本例中為Result(1, 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM