애들센스


Augmented Dickey-Fuller Unit Root Test (1) VBA버전 금융공학

Augmented unit root test 관련하여 다운받은 자료가 여럿 있다보니, 사실 하나 하나 뜯어 보질 못하고 이넘 저넘 보다보니 내가 원하는 형태로 개조를 할 수 없었다.

그중에 가장 만만한 (즉, 간단해 보이는 ) 넘을 잡아 코드를 주석처리하고 바꾸고 하여 만든 것이 있다.

기존의 것이 AR(1)프로세스를 만들고 이를 가지고 테스트하는 형태인데, AR(1)프로세스를 만드는 건 일단 필요없으니 버리고 테스트하는 부분을 함수(adfTest)로 만들어 정리한 것이다. 그래야 pairs trading에 써먹을 테니...

첨부 파일을 올려두었는데, 지저분한 코드를 정리하였지만 행렬연산 부분은 그대로 두었다. 그것마저 고치는 건 쓸데없는 짓 같기도 하고 사용한 행렬연산 모듈도 은근 맘에 드는 구석이 있다. 나중에 이 행렬연산은 엑셀의 워크시트 함수에 없는 것이 있어 유용할 듯하다.

다음은 Augmented unit root test을 수행하는 adfTest()를 사용한 예이다. 시계열과 lag order(생략하면 샘플크기에 따라 계산)를 주면 , 통계량과 p-Value 그리고 사용한 lag order를 돌려준다. 시계열을 배열의 형태로 함수에 전달하면 편리하겠는데, 행렬연산 때문에 벡터의 형태로 만들어 전달해야 한다(즉 n by 1 의 행렬) 그래서 시계열를 담는 변수를 x(1 To n, 1 To 1)와 같은 형태로 만들어 넘겨 주어야 한다.

리턴값은 배열의 형태로 전달되는데, 0번 항목이 통계량, 1번이 p-Value 그리고 2번이 lag order이다.
Sub demoadfTest()
Dim s As Worksheet
Dim rngSeries As Range, rng As Range
Dim x
Dim i As Long

Set s = Sheet1

Set rngSeries = s.Range(s.Range("begin"), s.Range("begin").End(xlDown))

ReDim x(1 To rngSeries.Cells.Count, 1 To 1)

i = 1
For Each rng In rngSeries
x(i, 1) = rng.Value
i = i + 1
Next

Dim ut, lag_order As Long

If Len(s.Range("Lag_order")) = 0 Then
lag_order = 0
Else
lag_order = s.Range("Lag_order")
End If

ut = adfTest(x, lag_order)

s.Range("Dickey_Fuller_Test_Statistic") = ut(0)
s.Range("p_value") = ut(1)
s.Range("Lag_order") = ut(2)

Debug.Print "Dickey Fuller Test Statistic :", ut(0)
Debug.Print "p-Value :", ut(1)
Debug.Print "Lag order :", ut(2)

End Sub
검증을 위해 똑같은 시계열자료를 가지고 lag order=3 과 lag order=0으로 R에서 adf.test()함수로 수행해보았다. 결과가 아래와 같은데 얘랑 같은 면 되는 거지 뭐~

사실 이건 감격적인 일이다. 왜냐하면 2005년 5월 30일 윌멋포럼에 adf 수행하는 VBA코드를 문의 한 적이 있다. 거의 7년만에 드뎌 손에 넣은 것이다. 뭐 그사이에 잊고 살았지만....그런데 눈물은 안나고 어깨만 아프네...

[DOWNLOAD]adftest_by_timebird.xls

덧글

댓글 입력 영역