[英]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)
我會重命名你的Year
和Month
變量。 兩者都是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.