[PJ01-01] 정상성 검정과 인과관계 검정 with R
동아리에서 열심히 겨울 프로젝트를 진행중이다.
우리 조가 선택한 주제는 'VAR 모델을 이용한 포트폴리오의 수익률 예측과 Value at Risk 측정'이다.
이를 위해 우리 조가 이번주 2월 3일까지 해야할 일은 포트폴리오에 추가할 종목과 종목에 영향을 줄 것이라고 생각하는 변수에 대한 시계열 데이터를 수집하는 것이다.
여기서 말하는 변수라 함은 선택한 종목의 수익률에 영향을 줄만한 변수를 의미한다.
예를 들어 금융 관련 주를 선택했을 경우 금리, 본원통화, 코스피, 신용 스프레드 등이 변수가 될 수 있다.
스포를 방지하기 위해 내가 선택한 종목을 A, 해당 종목에 영향을 줄 것으로 예상되는 변수를 변수1~변수9라고 부르겠다.
이번 포스트에서는 현재 나의 프로젝트 진행상황을 간단히 요약하려고한다.
주로 코드만 작성할 것이고 자세한 이론은 이후 'FinancialTimeSeries' 카테고리에서 포스팅할 예정...
모든 코드는 R을 이용해 쓰여진다.
#정상성검정
우선 다음과 같이 작업 공간을 설정해주고 필요한 라이브러리들을 불러온다.
> setwd("C:\\Users\\songh\\OneDrive\\BITAMIN\\WinterProject") > library(readxl) > library(lmtest) > library(urca) > library(forecast) > library(vars) > library(tseries) |
다음 수익률 데이터를 불러오고 시계열 객체로 저장한다.
> #월별수익률 ts객체 설정 > return <- read_xlsx('A_월간수익률.xlsx', sheet=1) > return <- ts(return[[2]], start = c(2013,1), frequency = 12) > return Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2013 5.62 -0.17 -5.57 -6.64 1.19 -9.43 -0.22 -2.92 4.79 0.00 -4.44 -2.65 2014 -0.91 -8.86 -1.39 2.34 4.32 7.92 10.61 4.10 -11.00 8.39 6.93 -9.82 2015 6.85 1.81 9.01 25.24 -9.74 -6.51 -3.66 -14.07 -2.88 6.27 -8.39 -5.65 2016 -11.32 3.86 2.30 -4.14 -9.52 -0.84 7.23 -7.28 -2.67 -0.14 -8.43 -1.71 2017 5.37 2.63 1.51 1.76 16.04 3.12 -1.82 -9.86 -5.86 3.04 3.41 -0.68 2018 18.99 -8.01 -0.63 -5.72 -0.54 -7.46 -6.47 -0.46 0.46 -18.07 18.22 6.42 2019 6.19 3.59 -3.90 7.06 -0.84 12.68 -6.39 -4.72 0.14 -4.95 5.87 6.93 2020 -8.68 -8.94 -11.33 8.27 -7.14 -5.72 9.87 4.15 -0.49 4.90 22.90 2.53 2021 -7.25 -9.53 7.93 9.78 11.25 -3.13 -1.56 11.75 -3.52 0.32 -6.34 1.24 2022 -19.52 5.75 -0.95 -5.36 -0.13 -15.21 3.09 -3.14 -9.56 3.25 10.00 -10.53 |
우리의 목표는 변수1~변수9 중 종목 A와 인과관계가 있는 변수를 찾고, 해당 변수와 종목 A의 Vector Autoregressive(VAR) 모델을 만들어 종목 A에 대한 예측을 수행하는 것이다.
그렇기 위해선 말했듯이 종목 A와 인과관계가 있는 변수를 찾는 것이 우선이다.
인과관계를 찾기 위한 방법은 대표적으로 그랜저-인과관계 검정이 있다.
그랜저-인과관계 검정의 귀무가설은 인과관계가 없다는 것이고, 대립가설은 인과관계가 있다는 것이다.
즉 검정 결과 $p-value$가 주어진 유의수준보다 작게 나올 경우 인과관계가 있다고 받아들인다.
그랜저-인과관계 검정을 위해선 검정을 시행하고 싶은 두 변수에 대해 VAR 모델을 만들어주어야 한다.
또한 그러기 위해선 각 변수들이 모두 정상성을 만족해야 한다.
우선 종목 A와 변수1의 VAR 모델을 만들어 주기 전에 변수 1에 대한 정상성 검정을 다음과 같이 실행한다.
(수익률 데이터는 대부분 정상성을 만족하기에..)
> adf.test(data[[2]]) Augmented Dickey-Fuller Test data: data[[2]] Dickey-Fuller = -2.7831, Lag order = 4, p-value = 0.2512 alternative hypothesis: stationary > pp.test(data[[2]]) Phillips-Perron Unit Root Test data: data[[2]] Dickey-Fuller Z(alpha) = -15.644, Truncation lag parameter = 4, p-value = 0.2116 alternative hypothesis: stationary |
위 결과를 해석하기 전에 정상성 검정하는 방법에 대해 살짝 짚고 넘어가자.
시계열 데이터의 정상성을 검정하는 가장 대표적인 방법으로 Augmented Dicky-Fuleer(ADF) 검정과 Phillips-Perron(PP) 검정이 있다.
두 검정 모두 귀무가설은 정상성을 갖지 못한다이고 대립가설은 정상성을 가진다이다.
즉 두 검정 결과 $p-value$가 주어진 유의수준보다 낮으면 데이터가 정상성을 가진다고 판단할 수 있다.
하지만 각 검정 방법은 특정한 조건을 가정한 검정이기 때문에 항상 정확하다고 보기엔 어려울 수 있다.
그렇기 때문에 우리는 두 검정 결과 모두 귀무가설이 기각되는 경우의 변수만 사용할 것이다.
이제 위의 결과를 해석해보자.
data[[2]]는 변수1에 대한 데이터를 의미하고, ADF와 PP 검정 결과 $p-value$가 각각 0.2512, 0.2116으로 유의수준을 0.05라고 했을 때 귀무가설을 기각하기 어렵다.
따라서 우리는 '차분'을 도입한다.
해당 시점의 시계열 데이터를 원래 해당 시점의 데이터에서 직전 시점의 데이터를 뺀 데이터로 변경한다.
그러면 아주 신기한 일이 벌어지는데 다음을 보자.
> adf.test(diff(data[[2]])) Augmented Dickey-Fuller Test data: diff(data[[2]]) Dickey-Fuller = -5.16, Lag order = 4, p-value = 0.01 alternative hypothesis: stationary Warning message: In adf.test(diff(data[[2]])) : p-value smaller than printed p-value > pp.test(diff(data[[2]])) Phillips-Perron Unit Root Test data: diff(data[[2]]) Dickey-Fuller Z(alpha) = -49.167, Truncation lag parameter = 4, p-value = 0.01 alternative hypothesis: stationary Warning message: In pp.test(diff(data[[2]])) : p-value smaller than printed p-value |
차분시킨 데이터에 대해 검정한 결과 ADF, PP 검정 모두 $p-value$가 0.01보다 작게 나오게 된다.
즉 차분한 데이터는 정상성을 만족하고, 이를 이용해 VAR 모델링을 진행하면 된다.
우리는 1시점 전의 데이터만을 가지고 차분하였는데 이는 보통 1차 차분이라고 부른다.
실제로 진행해본 결과 변수5까지 1차 차분만 하면 정상성을 만족하는 것을 볼 수 있었다.
이번엔 변수6에 대한 검정 결과를 살펴보자.
> adf.test(data[[7]]) Augmented Dickey-Fuller Test data: data[[7]] Dickey-Fuller = -3.806, Lag order = 4, p-value = 0.02102 alternative hypothesis: stationary > pp.test(data[[7]]) Phillips-Perron Unit Root Test data: data[[7]] Dickey-Fuller Z(alpha) = -8.2591, Truncation lag parameter = 4, p-value = 0.6387 alternative hypothesis: stationary > adf.test(diff(data[[7]])) Augmented Dickey-Fuller Test data: diff(data[[7]]) Dickey-Fuller = -2.8695, Lag order = 4, p-value = 0.2154 alternative hypothesis: stationary > pp.test(diff(data[[7]])) Phillips-Perron Unit Root Test data: diff(data[[7]]) Dickey-Fuller Z(alpha) = -27.479, Truncation lag parameter = 4, p-value = 0.01024 alternative hypothesis: stationary |
차분하지 않은 본래 데이터도, 1차 차분한 데이터도 모두 정상성을 만족하지 않는다.
그러면 한번 더 차분해볼까..?
> adf.test(diff(diff(data[[7]]))) Augmented Dickey-Fuller Test data: diff(diff(data[[7]])) Dickey-Fuller = -6.0214, Lag order = 4, p-value = 0.01 alternative hypothesis: stationary Warning message: In adf.test(diff(diff(data[[7]]))) : p-value smaller than printed p-value > adf.test(diff(diff(data[[7]]))) Augmented Dickey-Fuller Test data: diff(diff(data[[7]])) Dickey-Fuller = -6.0214, Lag order = 4, p-value = 0.01 alternative hypothesis: stationary Warning message: In adf.test(diff(diff(data[[7]]))) : p-value smaller than printed p-value |
차분의 차분, 즉 2차 차분한 결과 정상성을 만족한다는 결과를 얻을 수 있다.
모든 변수에 대한 정상성 검정을 실시한 결과 변수1~5,8,9는 1차 차분으로 정상성을 만족했고, 변수6~7은 2차 차분으로 정상성을 만족했다.
정상성을 갖는 데이터로 만든는 방법은 차분뿐만 아니라 자연로그를 씌우거나, 자연로그를 씌운 데이터를 다시 차분하는 방법 등 다양하다.
#그랜저인과관계검정
자 이제 정상성을 만족하는 데이터를 모두 만들었으므로 본격적인 그랜저-인과관계 검정을 시행해보자.
> var1 <- ts(diff(data[[2]])[3:length(diff(data[[2]]))], start = c(2013,1), frequency = 12) > v1 <- cbind(return, var1) > head(v1) return var1 Jan 2013 5.62 -1.3 Feb 2013 -0.17 -2.4 Mar 2013 -5.57 -1.5 Apr 2013 -6.64 0.1 May 2013 1.19 1.3 Jun 2013 -9.43 0.2 |
var1에 차분한 변수1 데이터를 입력해주고, cbind()를 이용해 수익률 데이터와 var1 데이터를 묶어주면 위와 같은 출력을 볼 수 있다.
다음 본격적인 검정을 수행하기 전에 한가지 중요하게 신경써야 할 점이 있다.
바로 'lag'라는 것인데, 이는 어느 시점 전까지의 데이터를 이용할 것인지를 결정하는 것이다.
lag를 선택하는 방법은 AIC, BIC, HQIC 등이 있지만 비교적 적은 데이터에 적합한 BIC를 이용할 것이다.
아래와 같이 VARselect를 이용해 lag를 선택할 수 있다.
> VARselect(v1, lag.max=12, type='const') $\$$selection AIC(n) HQ(n) SC(n) FPE(n) 3 2 1 3 $\$$criteria 1 2 3 4 5 6 7 AIC(n) 5.388415 5.328312 5.305041 5.347553 5.412320 5.468357 5.463841 HQ(n) 5.448832 5.429007 5.446014 5.528804 5.633849 5.730164 5.765926 SC(n) 5.537423 5.576657 5.652724 5.794575 5.958680 6.114055 6.208877 FPE(n) 218.862580 206.117094 201.422469 210.256374 224.468932 237.627136 236.856621 8 9 10 11 12 AIC(n) 5.464896 5.470115 5.493434 5.492461 5.492551 HQ(n) 5.807259 5.852757 5.916353 5.955659 5.996026 SC(n) 6.309270 6.413828 6.536485 6.634851 6.734278 FPE(n) 237.501654 239.250992 245.541251 246.091080 247.062641 |
파라미터인 lag.max는 월별 데이터이기 때문에 12로 설정했다.
출력값의 $\$$selection에 있는 SC 값이 우리가 이용할 BIC 값이다.
우리가 구한 BIC 값인 1을 이용해 다음과 같이 그랜저-인과관계 검정을 진행한다.
> grangertest(return~var1, order=1) Granger causality test Model 1: return ~ Lags(return, 1:1) + Lags(var1, 1:1) Model 2: return ~ Lags(return, 1:1) Res.Df Df F Pr(>F) 1 116 2 117 -1 0.0343 0.8534 |
grangertest(y~x, order=?)에서 y가 결과, x가 원인임을 검정하는 것이고 order에는 BIC 값을 넣으면 된다.
그러면 $p-value$가 0.8534로 인과관계가 없다는 귀무가설을 기각하지 못한다.
따라서 변수1은 수익률의 원인이 될 수 없다.
이번에는 변수2에 대해 살펴보자.
> var2 <- ts(diff(data[[3]])[3:length(diff(data[[3]]))], start = c(2013,1), frequency = 12) > v2 <- cbind(return, var2) > VARselect(v2, lag.max=12, type='const') $\$$selection AIC(n) HQ(n) SC(n) FPE(n) 2 2 2 2 $\$$criteria 1 2 3 4 5 6 7 AIC(n) 5.258846 5.024656 5.067947 5.064975 5.090903 5.076120 5.084484 HQ(n) 5.319263 5.125351 5.208921 5.246226 5.312432 5.337927 5.386569 SC(n) 5.407853 5.273002 5.415631 5.511997 5.637263 5.721818 5.829521 FPE(n) 192.264965 152.138130 158.905768 158.499188 162.767087 160.527627 162.081346 8 9 10 11 12 AIC(n) 5.124820 5.150656 5.143510 5.168960 5.207107 HQ(n) 5.467183 5.533297 5.566430 5.632157 5.710583 SC(n) 5.969195 6.094368 6.186561 6.311349 6.448835 FPE(n) 169.033853 173.825737 173.043191 178.074196 185.712241 > grangertest(return~var2, order=2) Granger causality test Model 1: return ~ Lags(return, 1:2) + Lags(var2, 1:2) Model 2: return ~ Lags(return, 1:2) Res.Df Df F Pr(>F) 1 113 2 115 -2 2.3529 0.09974 . --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 |
유의수준을 0.1이라고 했을 때 $p-value$가 0.09974로 인과관계가 없다는 귀무가설을 기각하고 인과관계가 있다는 대립가설을 채택한다.
이와 같은 검정을 계속 시행한 결과 변수 2,6,9가 수익률의 원인이 되는 변수임을 확인할 수 있었다.
.
오늘은 변수의 정상성에 대한 검정과 해당 변수가 수익률의 원인이 되는지 알아보는 그랜저-인과관계 검정에 대해 알아보았다.
다음 포스팅에서는 인과관계가 밝혀진 변수들을 통해 수익률 데이터와 새로운 VAR 모델을 만들고,
해당 VAR 모델을 이용하여 수익률에 대한 예측을 실시할 예정이다.
오늘은 여기까지.