2016-10-25 2 views
1

'H' Column is the year data column, 'I' Column is the month data column, 'D' Column is the 10-year bond yield we want to calculate the monthly volatility. Dies ist ein weiterer verbesserter Code für diese Frage, bitte helfen Sie mir. Die Rückkehr ist immer noch #NAME. Danke der Antwort von @Comintern. Laut dem Rat von @Comintern habe ich den Code überarbeitet. Im Namensmanager bezieht sich "Yr" auf die Spalte des Jahres (H3: H3696), "M" bezieht sich auf die Spalte des Monats (I3: I3696), "C_10" bezieht sich auf die ursprünglichen Ertragsdaten von China 10 Year Schatzobligation.So berechnen Sie die monatliche Volatilität in Excel VBA unter Spalte Zeitreihe

Gerade jetzt möchte ich die monatliche Volatilität der Rendite erhalten.

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 
+0

Was ist Ihre Frage genau? Fragen Sie, warum es in #Name aufgelöst wird? –

+0

Ja, ich möchte das Problem in den Codes kennen. Ich habe das "Jahr" verwendet, um das Jahr der Anleiherenditen zu referenzieren, und "Monat", um den Monat der Anleiherenditen zu referenzieren, "C_10" sind die ursprünglichen Daten der Anleiherenditen. –

Antwort

0

Dieser Code hat mehrere Probleme. Wie für den #NAME Fehler müssen Sie wahrscheinlich nur die Funktion in ein Modul verschieben. Ich würde auch vorschlagen, es ausdrücklich öffentlich zu machen:

Public Function Volatility(n As Variant) As Variant 

ich auch Option Base 0 entfernen würde - es ist die Standardbasis. Die einzigen Arrays Sie verwenden werden von Excel erstellt (so werden sie immer Basis 1) und TempSave, die Sie explizit mit einem niedrigeren Betrag aus 1 hier gebunden erklären:

ReDim Preserve TempSave(1 To dnum) 

ich umbenennen würde Ihre Year und Month Variablen. Beide sind die Namen von VBA-Funktionen und Ihre lokalen Variablen verbergen sie.

Dieser Code ...

dnum = 0 
mnum = 0 

... nicht alles tun - Variablen werden auf ihre Standardwerte immer initialisiert. Obwohl in diesem Fall ist der Standard Empty (was implizit auf 0 gegossen wird), da Sie (wahrscheinlich versehentlich) erklären sie als Variant hier:

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

Wenn sie alle angeblich sind Integer zu sein, müssen Sie erklären, dass ausdrücklich:

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

Sie Step 1 aus dem Schleifenzählung entfernen - es ist der Standard, aber es muss auch mit 1, nicht 0 hier (wieder, die Excel-Arrays sind Basis 1) starten:

For i = 0 To n Step 1 

Diese Linie ...

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

... ein „Index außerhalb des zulässigen Bereichs“ Fehler geben, denn wenn Range.Value auf mehr als eine Zelle bezeichnet, erhalten Sie einen zweidimensionalen Array. Das bedeutet, dass Sie beide Indizes bereitstellen müssen. Ich gehe davon aus, dass diese alle in der gleichen Spalte sind, so soll es sein:

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

Sie haben das entgegengesetzte Problem hier:

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

Sie TempSave als eindimensionales Array deklarieren, aber Versuch um es mit 2 Dimensionen zu indizieren.Beachten Sie, dass Sie nur die höchste Dimension ReDim Preserve haben. Wenn Sie also eine Spalte mit einer dynamischen Grenze erstellen müssen, müssen Sie entweder die Länge aus den Quell-Arrays berechnen oder sie transponieren. Bond wird auch ein zweidimensionales Array sein (unter der Annahme ist mehr als eine Zelle).

Wenn alle Ihre Bereiche 1 Zelle sind, werden diese Zuweisungen geben Ihnen einen Typenkonflikt:

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

Schließlich Volatility = Result wahrscheinlich Rückkehr ist nicht das, was es sein sollte, weil Sie es haben erklärt, wie:

ReDim Result(vectornum, 1) As Variant 

Wenn Sie ein Array von Variant von einem UDF zurückkehren, werden Sie nur den ersten Wert im Array erhalten - in diesem Fall Result(1, 1).

+0

Nach Ihrem Vorschlag habe ich den Code überarbeitet. Im Namensmanager bezieht sich "Yr" auf die Spalte des Jahres (H3: H3696), "M" bezieht sich auf die Spalte des Monats (I3: I3696), "C_10" bezieht sich auf die ursprünglichen Ertragsdaten von China 10 Year Schatzobligation. Gerade jetzt möchte ich die monatliche Volatilität der Rendite bekommen. –