Unit Root Testing
Purpose
Unit root testing for a series which reverts to a constant or has a linear trend.
Taking the data of PFC and RECLTD for a series
> y1 <- (security.db1[, "PFC"]) > x1 <- (security.db1[, "RECLTD"]) > fit <- lm(y1 ~ x1 + 0) > error <- residuals(fit) > temp <- data.frame(x = dates, y = error) |
> library(ggplot2) > ggplot(temp, aes(x = as.Date(x), y = error)) + geom_line(colour = "blue", + lwd = 1.3) + xlab("Date") + ylab("Spread") + opts(title = "PFC-RECLTD") |
- Obviously you can see that the spread has a linear trend. You got to test this series in the presence of linear trend Regress for a linear trend. The detrended spread is shown below
> temp$time <- 1:dim(temp)[1] > fit <- lm(error ~ time, temp) > summary(fit) Call: lm(formula = error ~ time, data = temp) Residuals: Min 1Q Median 3Q Max -32.3399 -5.9418 -0.2506 6.0012 25.8646 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 48.916538 1.137506 43.00 <2e-16 *** time -0.265581 0.006465 -41.08 <2e-16 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 9.892 on 302 degrees of freedom Multiple R-squared: 0.8482, Adjusted R-squared: 0.8477 F-statistic: 1688 on 1 and 302 DF, p-value: < 2.2e-16 > temp$residual <- resid(fit) |
- Detrended Spread looks like this
> ggplot(temp, aes(x = as.Date(x), y = residual)) + geom_line(colour = "blue", + lwd = 1.3) + xlab("Date") + ylab("Spread") + opts(title = "PFC-RECLTD") |
- So obviously the spread need to be tested accordingly. .Dickey fuller test for the presence of unit root
> adfTest(temp$y, type = "nc")@test$p.value 0.06330866 > adfTest(temp$y, type = "c")@test$p.value 0.4436295 > adfTest(temp$y, type = "ct")@test$p.value 0.01 |
MacKinnon test for the presence of unit root
> unitrootTest(temp$y, lags = 1, type = "nc")@test$p.value[1] t 0.05976044 > unitrootTest(temp$y, lags = 1, type = "c")@test$p.value[1] t 0.4570682 > unitrootTest(temp$y, lags = 1, type = "ct")@test$p.value[1] t 0.002161845 |
adf table for no constant
> adfTable(trend = "nc")$z 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -2.66 -2.26 -1.95 -1.60 0.92 1.33 1.70 2.16 50 -2.62 -2.25 -1.95 -1.61 0.91 1.31 1.66 2.08 100 -2.60 -2.24 -1.95 -1.61 0.90 1.29 1.64 2.03 250 -2.58 -2.23 -1.95 -1.62 0.89 1.29 1.63 2.01 500 -2.58 -2.23 -1.95 -1.62 0.89 1.28 1.62 2.00 Inf -2.58 -2.23 -1.95 -1.62 0.89 1.28 1.62 2.00 |
adf table for constant
> adfTable(trend = "c")$z 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -3.75 -3.33 -3.00 -2.63 -0.37 0.00 0.34 0.72 50 -3.58 -3.22 -2.93 -2.60 -0.40 -0.03 0.29 0.66 100 -3.51 -3.17 -2.89 -2.58 -0.42 -0.05 0.26 0.63 250 -3.46 -3.14 -2.88 -2.57 -0.42 -0.06 0.24 0.62 500 -3.44 -3.13 -2.87 -2.57 -0.43 -0.07 0.24 0.61 Inf -3.43 -3.12 -2.86 -2.57 -0.44 -0.07 0.23 0.60 |
adf table for constant and trend
> adfTable(trend = "ct")$z 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -4.38 -3.95 -3.60 -3.24 -1.14 -0.80 -0.50 -0.15 50 -4.15 -3.80 -3.50 -3.18 -1.19 -0.87 -0.58 -0.24 100 -4.04 -3.73 -3.45 -3.15 -1.22 -0.90 -0.62 -0.28 250 -3.99 -3.69 -3.43 -3.13 -1.23 -0.92 -0.64 -0.31 500 -3.98 -3.68 -3.42 -3.13 -1.24 -0.93 -0.65 -0.32 Inf -3.96 -3.66 -3.41 -3.12 -1.25 -0.94 -0.66 -0.33 |
MacKinnon table for no constant
> unitrootTable(trend = "nc") 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -2.661 -2.272 -1.955 -1.609 0.925 1.337 1.701 2.139 50 -2.612 -2.249 -1.948 -1.613 0.906 1.309 1.660 2.073 100 -2.588 -2.238 -1.944 -1.615 0.897 1.296 1.641 2.043 250 -2.574 -2.232 -1.942 -1.616 0.891 1.288 1.630 2.026 500 -2.570 -2.229 -1.941 -1.616 0.890 1.286 1.627 2.021 Inf -2.565 -2.227 -1.941 -1.617 0.888 1.284 1.624 2.015 attr(,"control") table trend statistic "unitroot" "nc" "t" |
MacKinnon table for constant
> unitrootTable(trend = "c") 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -3.724 -3.314 -2.986 -2.633 -0.370 0.000 0.327 0.714 50 -3.568 -3.213 -2.921 -2.599 -0.406 -0.040 0.281 0.658 100 -3.497 -3.166 -2.891 -2.582 -0.423 -0.059 0.259 0.632 250 -3.456 -3.139 -2.873 -2.573 -0.433 -0.071 0.247 0.617 500 -3.443 -3.131 -2.867 -2.570 -0.437 -0.075 0.242 0.612 Inf -3.430 -3.122 -2.861 -2.567 -0.440 -0.078 0.238 0.607 attr(,"control") table trend statistic "unitroot" "c" "t" |
MacKinnon table for constant and trend
> unitrootTable(trend = "ct") 0.010 0.025 0.050 0.100 0.900 0.950 0.975 0.990 25 -4.374 -3.945 -3.603 -3.238 -1.146 -0.820 -0.525 -0.173 50 -4.153 -3.795 -3.502 -3.181 -1.198 -0.882 -0.594 -0.251 100 -4.052 -3.727 -3.455 -3.153 -1.223 -0.911 -0.627 -0.289 250 -3.995 -3.687 -3.428 -3.137 -1.237 -0.929 -0.647 -0.311 500 -3.976 -3.673 -3.419 -3.132 -1.242 -0.935 -0.653 -0.318 Inf -3.958 -3.660 -3.410 -3.127 -1.246 -0.940 -0.660 -0.326 attr(,"control") table trend statistic "unitroot" "ct" "t" |
See Chris Brooks Page 331 Stationarity tests have stationarity under the null hypothesis, thus reversing the null and alternatives under the Dickey Fuller approach. Thus, under stationarity tests, the data will appear stationary by default if there is little information in the sample. One such stationarity test is the KPSS test. The results of these tests can be compared with the ADF/PP procedure to see if the same conclusion is obtained. The null and alternative hypotheses under each testing approach are as follows:
The most important criticism that has been levelled at unit root tests is that their power is low if the process is stationary but with a root close to the non-stationary boundary. So, for example, consider an AR(1) data generating process with coefficient 0.95. If the true data generating process is yt = phi y(t-1) + et the null hypothesis of a unit root should be rejected. It has been thus argued that the tests are poor at deciding, for example, whether phi = 1 or phi = 0.95, especially with small sample sizes. The source of this problem is that, under the classical hypothesis-testing framework, the null hypothesis is never accepted, it is simply stated that it is either rejected or not rejected. This means that a failure to reject the null hypothesis could occur either because the null was correct, or because there is insufficient information in the sample to enable rejection. One way to get around this problem is to use a stationarity test as well as a unit root test
KPSS test is basically a 2nd order brownian bridge
> kpss.test(temp$y, "Trend")$statistic KPSS Trend 0.3985639 > urkpssTest(temp$y, type = "tau", lags = "short") Title: KPSS Unit Root Test Test Results: Test is of type: tau with 5 lags. Value of test-statistic is: 0.3461 Critical value for a significance level of: 10pct 5pct 2.5pct 1pct critical values 0.119 0.146 0.176 0.216 Description: Fri Apr 09 13:29:32 2010 by user: Radha |
Thus stationarity test and unit root test confirm that the spread is a stationary spread.
- I would like to also check whether there has been a structural break
> summary(ur.za(temp$y, model = "both")) ################################ # Zivot-Andrews Unit Root Test # ################################ |
Takeaway :
- Use stationarity and unit root tests to be doubly sure that the series is a stationary series
- Use both the tests
- Once you see that the series is stationary then do some stuff based on the engle granger
- Use CRDW for testing the unit root for cointegrating residuals
- Engle Granger Test used CRDF , CRDW