Tutorial
Tutorial
• reduce the set of models using information criteria and residuals analysis;
(a) Load the data into R and construct a data set with observations in the
range 1 January 2011—31 January 2012.
library(forecast)
Now, load the data using the read.delim command with the sep = "," option
as it is comma delimited.
Use Date (first column) in the data set to select the required range, then save
Adj_Close as the yt variable.
1
sel_sample <- mydata$Date >= as.Date("2011-01-01") &
mydata$Date <= as.Date("2012-01-31")
y <- as.matrix(mydata$Adj_Close[sel_sample])
Solution Differencing is easily done with diff command and lagging a series
can be done with indexing operations (although there are also other ways).
Dy <- diff(y)
r <- as.matrix(log(y[2:nrow(y)]) - log(lag(y[1:nrow(y) - 1])))
(c) Draw time series plots of yt , ∆yt and rt ; comment on the stationarity
of the processes that may have generated these observations.
Solution Use the Date variable in the data set to select a subsample for 2011,
then plot each series using the plot command.
2
23 24 25 26 27 28 29 30
Stock Prices of Merck (MRK)
Jan 2011 Apr 2011 Jul 2011 Oct 2011 Jan 2012
Time (2011)
0.5
−0.5
−1.5
Jan 2011 Apr 2011 Jul 2011 Oct 2011 Jan 2012
Time (2011)
3
plot(dates[sel2011], r[sel2011], type = "l", xlab = "Time (2011)",
ylab = colnames(r))
0.02
Log Returns
−0.02
−0.06
Jan 2011 Apr 2011 Jul 2011 Oct 2011 Jan 2012
Time (2011)
The process {yt } is likely not stationary as its mean appears to vary over time.
The process {∆yt } seems to have a zero mean, but its variance may depend on
time. We will cover time-varying variance later in the course.
(d) Compute and plot the sample ACFs and PACFs of yt and ∆yt . Com-
ment on your findings.
4
Stock Prices of Merck (MRK)
1.0
0.8
0.6
ACF
0.4
0.2
0.0
0 5 10 15 20
Lag
0.4
0.2
0.0
5 10 15 20
Lag
5
acf(Dy[sel2011], main = colnames(Dy))
0.4
0.2
0.0
0 5 10 15 20
Lag
For prices (yt ), the SACF decays but the SPACF drops to zero after one lag. Also,
the first PAC is near 1, suggesting an AR(1) model of the form yt = yt + ϵt . You
should be able to see a connection to the implied model for ∆yt .
For price changes (∆yt ), the SPACF drops to zero after one lag but the SACF
oscillates. Also, the first AC is near 1, suggesting an MA(1) model of the form
∆yt = ϵt−1 +ϵt . You should notice the somewhat contradictory conclusions we have
reached with this line of reasoning. Can you think of any possible explanations?
Solution The Arima command from the forecast package makes it easy to
estimate a specified ARMA(p, q). We can put this command inside a nested for
loop to process a lot of ARMA models quickly. For this exercise, we estimate
models with combinations of p = 0, . . . , 4 and q = 0, . . . , 4. For each estimated
model, we extract the estimated AIC and BIC, then save these in a neat matrix,
which we call ic, to be examined ex-post.
6
ic <- matrix( nrow = 25, ncol = 4 )
colnames(ic) <- c("p", "q", "aic", "bic")
for (p in 0:4)
{
for (q in 0:4)
{
fit_p_q <- Arima(Dy, order = c(p, 0, q))
ic[p * 5 + q + 1,] = c(p, q, fit_p_q[["aic"]], fit_p_q[["bic"]])
}
}
(f) Use the AIC and BIC to reduce the set of ARMA(p, q) models.
print(ic)
## p q aic bic
## [1,] 0 0 221.1652 228.3695
## [2,] 0 1 222.9201 233.7265
## [3,] 0 2 221.3797 235.7882
## [4,] 0 3 221.7444 239.7550
## [5,] 0 4 223.3386 244.9513
## [6,] 1 0 222.8619 233.6683
## [7,] 1 1 218.0345 232.4430
## [8,] 1 2 217.6980 235.7086
## [9,] 1 3 219.6798 241.2926
## [10,] 1 4 221.6430 246.8578
## [11,] 2 0 220.8859 235.2944
## [12,] 2 1 217.7698 235.7804
## [13,] 2 2 219.6627 241.2755
## [14,] 2 3 221.5682 246.7830
## [15,] 2 4 223.5379 252.3549
## [16,] 3 0 219.9955 238.0061
## [17,] 3 1 219.6965 241.3092
## [18,] 3 2 221.4811 246.6960
## [19,] 3 3 221.2772 250.0942
## [20,] 3 4 219.9602 252.3793
7
## [21,] 4 0 221.6630 243.2757
## [22,] 4 1 221.6951 246.9099
## [23,] 4 2 223.4237 252.2406
## [24,] 4 3 219.5087 251.9277
## [25,] 4 4 219.5611 255.5823
The AIC and BIC appear to wildly disagree in their rankings of ARMA mod-
els. Unfortunately, there is no systematic approach to resolving this conflicting
information!
We need to proceed in a sensible way, so we look at the top 10 specifications
preferred by the AIC as well as the top 10 preferred by the BIC. This is easy to
do by sorting the matrix ic.
## p q aic bic
## [1,] 1 2 217.6980 235.7086
## [2,] 2 1 217.7698 235.7804
## [3,] 1 1 218.0345 232.4430
## [4,] 4 3 219.5087 251.9277
## [5,] 4 4 219.5611 255.5823
## [6,] 2 2 219.6627 241.2755
## [7,] 1 3 219.6798 241.2926
## [8,] 3 1 219.6965 241.3092
## [9,] 3 4 219.9602 252.3793
## [10,] 3 0 219.9955 238.0061
print(ic_bic)
## p q aic bic
## [1,] 0 0 221.1652 228.3695
## [2,] 1 1 218.0345 232.4430
## [3,] 1 0 222.8619 233.6683
## [4,] 0 1 222.9201 233.7265
## [5,] 2 0 220.8859 235.2944
## [6,] 1 2 217.6980 235.7086
## [7,] 2 1 217.7698 235.7804
## [8,] 0 2 221.3797 235.7882
## [9,] 3 0 219.9955 238.0061
## [10,] 0 3 221.7444 239.7550
8
For our purpose, next, it is sensible to select the models that make the top 10 in
both lists. However, this is not a rule by any means—in other contexts, it is likely
that a different approach will be more sensible.
(g) Draw time series plots of the estimated residuals you obtained for the
ARMA models selected in part (f). Comment on your findings. Run the
Ljung-Box test (at the α = 5% significance level) to test the white noise
hypothesis on estimated residuals obtained from each ARMA in the set
obtain in part (f) and report the test results. Use this information to
identify the adequate set of specified ARMAs.
Solution The forecast package simplifies residuals analysis with the command
checkresiduals. It will plot the estimated residuals series along with the SACF
and a histogram. It also automatically performs the Ljung-Box test using K = 10
by default and the α = 5% significance level.
for (i in 1:length(adq_set))
{
checkresiduals(Arima(Dy[sel2011], order = adq_set[[i]]))
}
9
Residuals from ARIMA(1,0,1) with non−zero mean
1
−1
−2
0 50 100 150 200 250
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
0 5 10 15 20 25 −2 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,1) with non-zero mean
## Q* = 8.0188, df = 8, p-value = 0.4316
##
## Model df: 2. Total lags used: 10
10
Residuals from ARIMA(1,0,2) with non−zero mean
1
−1
−2
0 50 100 150 200 250
0.10 40
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 25 −2 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,2) with non-zero mean
## Q* = 6.42, df = 7, p-value = 0.4917
##
## Model df: 3. Total lags used: 10
11
Residuals from ARIMA(2,0,1) with non−zero mean
1
−1
−2
0 50 100 150 200 250
0.10 40
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 25 −2 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,0,1) with non-zero mean
## Q* = 6.4833, df = 7, p-value = 0.4846
##
## Model df: 3. Total lags used: 10
12
Residuals from ARIMA(3,0,0) with non−zero mean
1
−1
−2
0 50 100 150 200 250
0.15 40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05 10
−0.10
0
0 5 10 15 20 25 −2 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(3,0,0) with non-zero mean
## Q* = 11.424, df = 7, p-value = 0.1212
##
## Model df: 3. Total lags used: 10
Nothing clearly stands out to suggest a blatent problem with correlated residuals,
so we proceed with the four specifications in the set.
(h) Forecast changes in MRK stock prices in January, 2012. For each
ARMA model in the adequate set, compare your predicted price
changes with real price changes in the data. Compare the forecasts you
obtained as well as their “quality” across ARMA models and comment
on the robustness of the generated forecasts.
13
Solution We forecast each model in the adequate set using the forecast com-
mand within a nested for loop. The option level = c(68, 95) instructs the
command to construct two sets of predictive intervals: one with 95% coverage and
another with 68% coverage.
ARMA(1, 1)
1.0
Changes in Stock Prices
0.5
0.0
−0.5
14
ARMA(1, 2)
1.0
Changes in Stock Prices
0.5
0.0
−0.5
ARMA(2, 1)
1.0
Changes in Stock Prices
0.5
0.0
−0.5
15
ARMA(3, 0)
1.0
Changes in Stock Prices
0.5
0.0
−0.5
When we use the plot command with output from the forecast command, we
get a nice depiction of how the data is extrapolated into the future, complete with
predictive intervals to capture uncertainty. We can also add the actual outcomes
in the forecast period to help us compare the forecast performance of each ARMA
in the adequate set.
We first note that predictive intervals for price changes (∆yt ) appear to have a
fixed width even as the forecast horizon increases (from 1 day to 20 days).
Comparing further across specifications, it is clear that all four generate very
similar forecasts for January 2012. Therefore, the specification differences between
them are not important for our purpose.
Alternatively, we may conclude that our forecast of price changes is robust to
minor differences in the specification of ARMA models in that we cannot clearly
distinguish between them with our diagnostic tools.
(i) Forecast MRK prices yt (levels this time, instead of changes) using an
ARMA(2, 1) model only. Compare your predicted prices with real prices
in the data. Compare the price forecasts obtained in this part with price
forecasts obtained by transforming the forecasts in part (h). HINT: you
will need convert predicted prices changes to predicted prices.
16
Solution To forecast prices yt , we use the same approach but replace Dy with y
throughout.
ARMA(2, 1)
Stock Prices of Merck (MRK)
32
30
28
26
The forecasts we obtain here are for prices, where as the forecasts that were
obtained for part (h) were for price changes. In order to compare them, we need
to convert predicted price changes to prices, which is achieved by cumulatively
suming:
t
X
yt = y0 + ∆yj ,
j=1
17
the middle instructs R to difference yt when estimating the ARMA parameters.
However, it will automatically reverse the differencing when computing forecasts
and predictive intervals! This specification is called the ARIMA(p, q). You can
verify (by trying it yourself) that an ARIMA(p, q) for yt yields the same AR and
MA coefficient estimates as an ARMA(p, q) for ∆yt .
ARIMA(1, 1)
Stock Prices of Merck (MRK)
32
30
28
26
18
ARIMA(1, 2)
Stock Prices of Merck (MRK)
32
30
28
26
ARIMA(2, 1)
34
Stock Prices of Merck (MRK)
32
30
28
26
19
ARIMA(3, 0)
Stock Prices of Merck (MRK)
32
30
28
26
(j) OPTIONAL: Repeat parts (d)-(h) for log returns rt . Note that here
you will forecast daily returns (yt − yt−1 )/yt−1 in January, 2012. Hint:
Recall that (yt − yt−1 )/yt−1 ≈ rt .
20
Solution The steps are nearly the same as those for working with ∆yt .
0.4
0.2
0.0
0 5 10 15 20
Lag
21
Stock Prices of Merck (MRK)
0.00 0.05 0.10
Partial ACF
−0.10
5 10 15 20
Lag
for (i in 1:length(adq_set))
{
checkresiduals(Arima(r[sel2011], order = adq_set[[i]]))
}
22
Residuals from ARIMA(1,0,1) with non−zero mean
0.025
0.000
−0.025
−0.050
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
0 5 10 15 20 25 −0.050 −0.025 0.000 0.025
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,1) with non-zero mean
## Q* = 7.6925, df = 8, p-value = 0.4641
##
## Model df: 2. Total lags used: 10
23
Residuals from ARIMA(1,0,2) with non−zero mean
0.025
0.000
−0.025
−0.050
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 25 −0.075 −0.050 −0.025 0.000 0.025
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,2) with non-zero mean
## Q* = 6.1518, df = 7, p-value = 0.5221
##
## Model df: 3. Total lags used: 10
24
Residuals from ARIMA(2,0,1) with non−zero mean
0.025
0.000
−0.025
−0.050
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
0 5 10 15 20 25 −0.075 −0.050 −0.025 0.000 0.025
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,0,1) with non-zero mean
## Q* = 6.2143, df = 7, p-value = 0.515
##
## Model df: 3. Total lags used: 10
25
Residuals from ARIMA(3,0,0) with non−zero mean
0.025
0.000
−0.025
−0.050
0.15
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05 10
−0.10
0
0 5 10 15 20 25 −0.075 −0.050 −0.025 0.000 0.025
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(3,0,0) with non-zero mean
## Q* = 11.181, df = 7, p-value = 0.1309
##
## Model df: 3. Total lags used: 10
26
axis(1, at = xticks, labels = dates[xticks])
}
ARMA(1, 1)
0.03
Log Returns
0.01
−0.01
−0.03
ARMA(1, 2)
0.03
Log Returns
0.01
−0.01
−0.03
27
ARMA(2, 1)
0.03
Log Returns
0.01
−0.01
−0.03
ARMA(3, 0)
0.03
Log Returns
0.01
−0.01
−0.03
28
ECON3350: Applied Econometrics
for Macroeconomics and Finance
• create a function in R;
• Select and adequate set of ARDL models and draw inference on dynamic
relationships.
where
b0 + b 1 c0 + c1 + c2 a0 − γ
α = −(1 − a1 ), βx = , βw = , µ= .
1 − a1 1 − a1 1 − a1
1
To convert this to the ECM representation, we add and subtract five terms: γ,
yt−1 , b0 xt−1 , c0 wt−1 and c2 wt−1 . Specifically,
θ(L) = b(L)/a(L) = θ0 + θ1 L + · · · + θh Lh + · · · ,
if (h == 0)
{
# if the horizon is zero, then just return theta0
# note: good practice would be to check that h is an integer
return(theta = theta0)
}
# get the orders of a(L) and b(L); in fact, the ARMA orders
# are p - 1 and q - 1 because we also have a0 and b0 to take
# into account
p <- length(a)
q <- length(b)
2
# things easier later
if (h > p)
{
a = c(a, numeric(1 + h - p))
}
if (h > q)
{
b = c(b, numeric(1 + h - q))
}
return(theta)
}
3
# get the number of exogenous variables in the ARDL: we want to
# get IRFs to each one of these separately
k <- length(order) - 1
if (cumirf)
{
# compute the first "h" terms of theta(L) = b(L)/a(L) if
# cumulative IRFs are requested, do a cumulative sum of
# theta coefficients
irfs[, i] <- cumsum(arma2ma(a, b, h))
}
else
{
# compute the first "h" terms of theta(L) = b(L)/a(L)
# and save them
irfs[, i] <- arma2ma(a, b, h)
}
lrm[i] <- sum(b) / sum(a)
}
4
4. The file wealth.csv contains observations on:
The sample period from 1952Q2 through 2006Q2 (see Koop, G., S. Potter
and R. W. Strachan (2008) “Re-examining the consumption-wealth relation-
ship: The role of uncertainty” Journal of Money, Credit and Banking, Vol.
40, No. 2.3, 341-367).
(a) Estimate an ARDL(1, 2, 2) specified for ct and use the functions created
in Questions 2 and 3 to obtain the estimated IRFs to permanent shocks
in at and yt as well the LRMs. Hint: to estimate the ARDL parameters,
try the ardl function that is provided by the ARDL package.
library(ARDL)
Next, load the data and use the ardl function to estimate the parameters of the
an ARDL(1, 1, 2).
Finally, use our ardl_irfs function to compute the cumulative IRFs and LRMs.
5
Cummulative IRFs to AT
0.20
Impulse Response
0.15
0.10
0 10 20 30 40
Horizon
Cummulative IRFs to YT
0.7
Impulse Response
0.6
0.5
0.4
0 10 20 30 40
Horizon
print(irfs_lrm$lrm)
## AT YT
## 0.2687276 0.7873063
6
(b) Estimate the ECM representation of the ARDL(1, 2, 2) and report the
results. How do the LRMs in the estimated ECM compare to those
computed in part (a)? Hint: use the recm and multipliers functions
to convert the output produced by ardl.
Solution Given output from the ardl function, obtaining the ECM form entails
two steps. First, use the recm function with the case = 2 option. This option
corresponds to “no linear trend’ ’ and an intercept within the equlibrium relation
(γ = 0 and µ unrestricted in our notation).1
The function recm will produce estimates of the “short-run’ ’ coefficients in the
ECM, but not the LRMs (recm only produces the aggregate error correction term,
which it calls ect). To obtain estimates of the LRMs (i.e., details of the ect), use
the multipliers function.
##
## Time series regression with "zooreg" data:
## Start = 3, End = 217
##
## Call:
## dynlm::dynlm(formula = full_formula, data = data, start = start,
## end = end)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.0230749 -0.0039518 0.0003092 0.0034368 0.0156863
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## d(AT) 0.063151 0.017998 3.509 0.000551 ***
## d(L(AT, 1)) 0.049423 0.017916 2.759 0.006318 **
## d(YT) 0.351155 0.041389 8.484 3.90e-15 ***
## d(L(YT, 1)) 0.183718 0.043249 4.248 3.24e-05 ***
1
A linear trend amounts to including t in the ARDL as a regressor—more on this later in the
course.
7
## ect -0.035626 0.007755 -4.594 7.50e-06 ***
## ---
## Signif. codes: 0 ’***’ 0.001 ’**’ 0.01 ’*’ 0.05 ’.’ 0.1 ’ ’ 1
##
## Residual standard error: 0.005683 on 210 degrees of freedom
## (0 observations deleted due to missingness)
## Multiple R-squared: 0.6333, Adjusted R-squared: 0.6246
## F-statistic: 72.54 on 5 and 210 DF, p-value: < 2.2e-16
print(ecm_lrm)
8
source("ardl_irfs_ci.R")
Use the function ardl_irfs_ci to estimate confidence intervals for IRFs to per-
manent shocks in at and yt .
for (i in 1:ncol(irfs_ci$md))
{
plot(0:40, irfs_ci$md[, i], type = "l",
ylab = "Impulse Response", xlab = "Horizon",
main = paste("Cumulative IRFs to",
colnames(irfs_ci$md)[i]),
ylim = c(min(irfs_ci$lb[, i]), max(irfs_ci$ub[, i])))
lines(0:40, irfs_ci$ub[, i], type = "l", col = "blue")
lines(0:40, irfs_ci$lb[, i], type = "l", col = "blue")
}
Cumulative IRFs to AT
0.5
0.4
Impulse Response
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
9
Cumulative IRFs to YT
1.2
Impulse Response
0.8
0.4
0.0
0 10 20 30 40
Horizon
We first observe that the IRF confidence intervals increase in width as the horizon h
increases. This is equally true for shocks in both at and yt . This is not surprising—
because we are analysing “cumulative’ ’ responses, we expect that responses at
more distant horizons are more difficult to estimate accurately with the same
sample size.
In this particular case, we also observe that our estimate of a1 is close to 1, which
means the estimated a(L) has a root close to unity, and the estimated ARDL is
close to unstable. Hence, we are drawing inference on realised ARDLs that are
“close’ ’ to the instability region.
Recall that an unstable ARDL does not have finite LRMs. When realised ARDLs
are “close’ ’ to this, but still stable, they will result in finite LRMs. However, the
sampling variance of these LRMs will be very large, thereby resulting in very wide
confidence intervals. Our cumulative IRFs tend towards such LRMs as the horizon
increases, and so, it is not surprising that the confidence intervals become wider
at more distant horizons.
The bottom line is that when an ARDL is estimated close to instability, cumulative
IRFs at longer horizons are not reliable. What this means in practical terms is
that certain dynamic effects are very difficult to infer in the long run. This is
the case here: the effect of permanent increases in either income or wealth on
expenditures are difficult to infer for horizons beyond 20 quarters or so (i.e., five
years).
Any attempt at long-run inference would be accompanied by a high degree of
uncertainty—i.e., be rather inaccurate. Is it still useful? That of course depends
on the objective. For example, we would conclude that with 68% confidence, a $1
10
increase in wealth leads to anywhere between $0 and $0.50 increase in expenditures
after 10 years.
Whether or not this is useful depends on the question. If the question is: does
more wealth lead to a permanent increase in expenditures? Then, our long-run
inference is not very useful because our confidence intervals include negative effects
for all horizons beyond 10 years. On the other hand, if the question is: do people
end up spending all wealth increases in the long run? In this case, our data tells
us that with 68% confidence they do not—less than half of the wealth increase
expected to be spent after 10 years.
Finally, even if long-run effects are difficult to infer, short-term dynamics are typ-
ically still accurately estimated and are often themselves of interest. For example,
in this case we can infer that with 68% confidence, a $1 increase in wealth leads
to an immediate increase in expenditures between $0.05 and $0.15. On the other
hand, a $1 increase in income leads to an immediate increase in expenditures
between $0.45 and $0.65. So conclusion we can confidently claim is that with
68% confidence, an increase in income leads to more expenditures relative to an
equivalent increase in wealth, in the short-run.
There are many other interesting inferential claims we can make from these plots!
Try and see if you can draw more conclusions.
(d) Compare the values in md to the IRFs estimates obtained in part (a).
Solution The midpoint of the confidence interval is exactly the estimate so the
values in md should match exactly to the estimated IRFs. However, this may not
be the case due to “rounding’ ’ errors in practice. The best way to compare two
vectors or matrices is to look at the norm of their difference. Even when rounding
errors result in a norm that is not zero (when in theory it should be), the norm
should yield an obviously small number.
print(norm(irfs_lrm$irfs - irfs_ci$md))
## [1] 0
(e) Use the LRM estimates and standard deviations obtained in part (b)
to construct 68% confidence intervals for the LRMs, assuming the sam-
pling distributions of the LRM estimators are approximately normal.
11
How do they compare to the IRF confidence intervals obtained in part
(c)?
Solution To construct the confidence intervals, we first need to obtain the ap-
propriate percentile z from the normal distribution. To obtain a 68% confidence
interval, this requires setting z to be the 84th percentile. We know that for the
normal distribution Pr(z ≤ 1) ≈ 0.84, so z ≈ 1, but we can also use the R function
qnorm to compute it.
z <- qnorm(.84)
## AT CT
## lb 0.1480907 0.6473332
## md 0.2687276 0.7873063
## ub 0.3893645 0.9272794
## AT YT
## lb -0.03213304 0.04864858
## md 0.23256522 0.72974583
## ub 0.49726349 1.41084308
The key observation in these results is that the confidence intervals for cumulative
impulse response at h = 40 are in fact wider than the confidence intervals for the
LRMs. You should find this quite unsettling!
12
In fact, both confidence intervals are asymptotically correct (with few exceptions),
meaning that in an infinite sample we should observe confidence intervals for LRMs
that are wider than those for the 40th horizon IR. But we do not have an infinite
sample, and this is the main reason for the discrepancy.
We have already discussed in part (d) how inference on cumulative impulse re-
sponses in a finite sample is expected to be less accurate at more distant horizons.
Indeed, the same is true for estimates of the standard errors that we use to form
the confidence intervals!
At more distant horizons, and culminating with the LRMs, standard errors es-
timates are subject to (often substantial) finite sample bias. The exercise here
underscores two points: (i) it is not uncommon to encounter discrepancies, and
(ii) inference on dynamic effects at longer horizons requires extra care. The under-
lying lesson is simply that one should never take output from statistical software
for granted.
i <- 0;
for (p in 1:5)
{
for (l in 0:4)
{
for (s in 0:4)
{
i <- i + 1
ardl_est[[i]] <- ardl(CT ~ AT + YT, mydata,
order = c(p, l, s))
ic[i,] <- c(p, l, s, AIC(ardl_est[[i]]),
13
BIC(ardl_est[[i]]))
}
}
}
The first six models preferred by the BIC also have sufficient support in terms of
the AIC, so we take this to be the adequate set.
We also need to match the orders in the adequate set to the set of all models that
we have estimated.
for (i in 1:length(adq_idx))
{
order <- adq_set[i,1:3]
acf(ardl_est[[adq_idx[i]]]$residuals,
xlim = c(1, 20), xaxp = c(1, 20, 1),
ylim = c(-0.15, 0.15), yaxp = c(-0.15, 0.15, 2),
main = paste("Residuals ACF for ARDL(", order[1], ", ",
order[2], ", ",
order[3], ")",
sep = ""))
}
14
Residuals ACF for ARDL(1, 2, 2)
0.15
ACF
0.00
−0.15
1 20
Lag
0.00
−0.15
1 20
Lag
15
Residuals ACF for ARDL(1, 3, 2)
0.15
ACF
0.00
−0.15
1 20
Lag
0.00
−0.15
1 20
Lag
16
Residuals ACF for ARDL(2, 2, 2)
0.15
ACF
0.00
−0.15
1 20
Lag
0.00
−0.15
1 20
Lag
We do not observe anything drastic so we proceed with the set of six models.
17
and wealth.
Solution Generate the plots of IRFs with confidence intervals for all ARDL
specifications in the adequate set.
for (i in 1:length(adq_idx))
{
order <- adq_set[i,1:3]
plot(0:40, irfs_ci[[i]][, 2], type = "l", ylim = c(y_min, y_max),
ylab = "Impulse Response", xlab = "Horizon",
main = paste("ARDL(", order[1], ", ", order[2], ", ", order[3],
"): Cumulative IRFs to ", shock_name, sep = ""))
lines(0:40, irfs_ci[[i]][, 1], type = "l", col = "blue")
lines(0:40, irfs_ci[[i]][, 3], type = "l", col = "blue")
lines(0:40, numeric(41), type = "l", col = "red")
}
18
ARDL(1, 2, 2): Cumulative IRFs to AT
0.5
0.4
Impulse Response
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
19
ARDL(1, 3, 2): Cumulative IRFs to AT
0.5
0.4
Impulse Response
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
20
ARDL(2, 2, 2): Cumulative IRFs to AT
0.5
0.4
Impulse Response
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
0.3
0.2
0.1
0.0
0 10 20 30 40
Horizon
We divide the inference into short-run and long-run effects. By long-run we will
mean around 10 years (equivalently, h ≈ 40) following a shock to wealth. By
short-run we will mean within the first year (equivalent, h ≤ 4).
Starting with the long-run effects, we conclude with reasonable confidence that,
cetiris paribus, an increase in wealth will be at most partially spent after 10 years.
21
In particular, it is very unlikely that more than half of a wealth increase is spent,
but there is a small possibility that overall expenditures contract, in the ten years
following a wealth increase.
In the short-run, we conclude with reasonable confidence that an increase in wealth
leads to an increase in expenditures. Two scenarios are possible. In the first, ex-
penditures jump quickly (within one quarter) and then level off. In the second
scenario, expenditures rise gradually. Under both scenarios, expenditures are un-
likely exceed 20% of the wealth increase within the first year. However, the first
scenario results in a greater short-term expenditure increase relative to the second
scenario.
What inference can you obtain about the dynamic relationship between expendi-
tures and income?
22
ECON3350: Applied Econometrics
for Macroeconomics and Finance
Tutorial 6: Cointegration - I
Problems
In this tutorial you will test for cointegration using the Engle-Granger method.
The data consists of four Australian interest rates: the 5 year (i3y) and 3 year
(i3y) Treasury Bond (i.e., Capital Market) rates, along with the 180 day (i180d)
and 90 (i90d) day Bank Accepted Bill (i.e., Money Market) rates. The data are
annualized monthly rates for the period June 1992—August 2010 (T = 219), and
are saved in term_structure.csv.
library(forecast)
library(dplyr)
library(zoo)
library(aTSA)
1
It is also useful to create some functions to help automate the task of constructing
adequate sets for ADF specifications. The following two functions estimate the
coefficients and record AIC/BIC values for a range of ADF regressions specified
by lags combined with the inclusion and/or excludion of a constant and/or trend.
One function performs the estimation in levels, while the other does the same in
differences.
# create a function to estimate a range of ADF regression
# specifications in levels along with the AICs and BICs
ADF_estimate_lev <- function(y, p_max = 9)
{
TT <- length(y)
ADF_est <- list()
ic <- matrix(nrow = 3 * (1 + p_max), ncol = 5)
colnames(ic) <- c("const", "trend", "p", "aic", "bic")
i <- 0
for (const in 0:1)
{
for (p in 0:p_max)
{
i <- i + 1
try(silent = T, expr =
{
ADF_est[[i]] <- Arima(diff(y), xreg = y[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = F)
ic[i,] <- c(const, 0, p, ADF_est[[i]]$aic,
ADF_est[[i]]$bic)
})
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
for (p in 0:p_max)
{
i <- i + 1
try(silent = T, expr =
{
ADF_est[[i]] <- Arima(diff(y), xreg = y[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic[i,] <- c(const, 1, p, ADF_est[[i]]$aic,
2
ADF_est[[i]]$bic)
})
}
}
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
for (p in 0:p_max)
{
3
i <- i + 1
try(silent = T, expr =
{
ADF_est_diff[[i]] <- Arima(diff(diff(y)),
xreg = diff(y)[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic_diff[i,] <- c(const, 1, p, ADF_est_diff[[i]]$aic,
ADF_est_diff[[i]]$bic)
})
}
}
}
return(list(ADF_est_diff = ADF_est_diff,
ic_diff = ic_diff,
ic_aic_diff = ic_aic_diff,
ic_bic_diff = ic_bic_diff))
}
Next, load the data and and extract the four variables.
Now, consider the proximity of {i3yt } to a unit root process. We begin by con-
structing an adequate set of ADF regressions in the level of {i3yt }.
4
## [3,] 1 1 11 101.7485 152.5159
## [4,] 1 0 12 102.8333 153.6008
## [5,] 1 1 13 102.9466 160.4830
## [6,] 1 0 10 103.1882 147.1866
## [7,] 0 0 12 103.5612 150.9442
## [8,] 1 1 14 103.5876 164.5085
## [9,] 1 1 7 103.6625 140.8919
## [10,] 1 0 11 104.2917 151.6746
print(i3y_ADF_lev$ic_bic)
The AIC and BIC ranking do not have any specifications in common, so we select
from both top 10 rankings in a way that reflects some agreement. This is obviously
very subjective! The justification we use as follows. From the AIC list, take the
most preferred specification along with a few others that have the lowest BIC
values. Then, do the same using the BIC list.
As result, we obtain the following set of specifications on which we run our residuals
analysis.
for (i in 1:length(i3y_adq_idx))
{
checkresiduals(i3y_ADF_lev$ADF_est[[i3y_adq_idx[i]]])
}
5
Residuals from Regression with ARIMA(1,0,0) errors
0.1 30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1 0 1 2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 20.038, df = 9, p-value = 0.01768
##
## Model df: 1. Total lags used: 10
6
Residuals from Regression with ARIMA(2,0,0) errors
40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1 0 1 2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 18.425, df = 8, p-value = 0.01826
##
## Model df: 2. Total lags used: 10
7
Residuals from Regression with ARIMA(3,0,0) errors
0.2
40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1 0 1 2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 16.161, df = 7, p-value = 0.02369
##
## Model df: 3. Total lags used: 10
8
Residuals from Regression with ARIMA(10,0,0) errors
0.15 40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(10,0,0) errors
## Q* = 5.2834, df = 3, p-value = 0.1522
##
## Model df: 10. Total lags used: 13
9
Residuals from Regression with ARIMA(2,0,0) errors
30
0.1
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 19.404, df = 8, p-value = 0.01284
##
## Model df: 2. Total lags used: 10
10
Residuals from Regression with ARIMA(3,0,0) errors
40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 15.443, df = 7, p-value = 0.03072
##
## Model df: 3. Total lags used: 10
11
Residuals from Regression with ARIMA(7,0,0) errors
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(7,0,0) errors
## Q* = 6.1322, df = 3, p-value = 0.1054
##
## Model df: 7. Total lags used: 10
12
Residuals from Regression with ARIMA(10,0,0) errors
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(10,0,0) errors
## Q* = 4.848, df = 3, p-value = 0.1833
##
## Model df: 10. Total lags used: 13
We reject white noise residuals at the 5% significance level for all models with
p < 7. Hence, we remove all models except the three with p = 7, 10, all containing
a constant and two also containing a trend.
Given our adequate set of ADF regressions, we should run the ADF test with
nlag = 11, but we will use nlag = 15 just to check how sensitive the results are
to including more lags (which the AIC prefers, but the BIC rejects).
13
## [2,] 1 -0.697 0.429
## [3,] 2 -1.220 0.242
## [4,] 3 -1.161 0.264
## [5,] 4 -1.103 0.284
## [6,] 5 -1.022 0.313
## [7,] 6 -0.915 0.352
## [8,] 7 -0.950 0.339
## [9,] 8 -0.761 0.406
## [10,] 9 -0.773 0.402
## [11,] 10 -0.738 0.415
## [12,] 11 -0.807 0.390
## [13,] 12 -0.709 0.425
## [14,] 13 -0.603 0.463
## [15,] 14 -0.645 0.448
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -1.74 0.4298
## [2,] 1 -2.05 0.3087
## [3,] 2 -2.80 0.0634
## [4,] 3 -3.10 0.0295
## [5,] 4 -2.85 0.0553
## [6,] 5 -2.38 0.1779
## [7,] 6 -2.22 0.2424
## [8,] 7 -2.65 0.0893
## [9,] 8 -2.32 0.2036
## [10,] 9 -2.54 0.1154
## [11,] 10 -2.09 0.2924
## [12,] 11 -1.97 0.3400
## [13,] 12 -1.60 0.4828
## [14,] 13 -1.55 0.5018
## [15,] 14 -1.37 0.5683
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -2.27 0.4618
## [2,] 1 -2.90 0.1999
## [3,] 2 -3.29 0.0728
## [4,] 3 -3.79 0.0203
## [5,] 4 -3.51 0.0422
## [6,] 5 -2.97 0.1689
## [7,] 6 -2.90 0.1985
## [8,] 7 -3.45 0.0475
## [9,] 8 -3.28 0.0758
## [10,] 9 -3.63 0.0310
## [11,] 10 -3.05 0.1333
## [12,] 11 -2.83 0.2293
14
## [13,] 12 -2.52 0.3550
## [14,] 13 -2.65 0.3046
## [15,] 14 -2.39 0.4093
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
print(i3y_ADF_diff$ic_bic_diff)
15
## [5,] 1 0 4 80.46394 104.12322
## [6,] 1 0 1 91.37490 104.89449
## [7,] 0 0 3 90.16004 107.05953
## [8,] 1 0 5 81.28020 108.31938
## [9,] 1 0 2 92.37827 109.27776
## [10,] 1 1 4 82.30717 109.34635
for (i in 1:length(i3y_adq_idx_diff))
{
checkresiduals(
i3y_ADF_diff$ADF_est_diff[[i3y_adq_idx_diff[i]]])
}
0.5
0.0
−0.5
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
16
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 7.1851, df = 6, p-value = 0.3041
##
## Model df: 4. Total lags used: 10
0.5
0.0
−0.5
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1.0 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(5,0,0) errors
## Q* = 6.5018, df = 5, p-value = 0.2604
##
## Model df: 5. Total lags used: 10
17
Residuals from Regression with ARIMA(4,0,0) errors
1.0
0.5
0.0
−0.5
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 7.1557, df = 6, p-value = 0.3067
##
## Model df: 4. Total lags used: 10
adf.test(diff(i3y))
18
## [3,] 2 -6.29 0.01
## [4,] 3 -6.31 0.01
## [5,] 4 -6.86 0.01
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -12.19 0.01
## [2,] 1 -8.30 0.01
## [3,] 2 -6.27 0.01
## [4,] 3 -6.30 0.01
## [5,] 4 -6.84 0.01
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
print(i5y_ADF_lev$ic_bic)
19
## [8,] 1 1 3 78.72176 102.41322
## [9,] 1 0 3 82.46661 102.77358
## [10,] 0 0 3 86.18707 103.10955
for (i in 1:length(i5y_adq_idx))
{
checkresiduals(i5y_ADF_lev$ADF_est[[i5y_adq_idx[i]]])
}
1.0
0.5
0.0
−0.5
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 14.115, df = 9, p-value = 0.1183
##
## Model df: 1. Total lags used: 10
20
Residuals from Regression with ARIMA(2,0,0) errors
1.5
1.0
0.5
0.0
−0.5
0.15 40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −1.0 −0.5 0.0 0.5 1.0 1.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 14.329, df = 8, p-value = 0.07357
##
## Model df: 2. Total lags used: 10
21
Residuals from Regression with ARIMA(3,0,0) errors
1.5
1.0
0.5
0.0
−0.5
0.15
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −1 0 1
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 11.163, df = 7, p-value = 0.1317
##
## Model df: 3. Total lags used: 10
22
Residuals from Regression with ARIMA(10,0,0) errors
1.0
0.5
0.0
−0.5
0.15
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(10,0,0) errors
## Q* = 3.6386, df = 3, p-value = 0.3032
##
## Model df: 10. Total lags used: 13
23
## [10,] 9 -0.784 0.398
## [11,] 10 -0.785 0.398
## [12,] 11 -0.913 0.352
## [13,] 12 -0.823 0.384
## [14,] 13 -0.729 0.418
## [15,] 14 -0.725 0.419
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -1.69 0.4488
## [2,] 1 -1.88 0.3735
## [3,] 2 -2.63 0.0922
## [4,] 3 -2.75 0.0730
## [5,] 4 -2.60 0.0972
## [6,] 5 -2.30 0.2089
## [7,] 6 -2.13 0.2773
## [8,] 7 -2.34 0.1955
## [9,] 8 -2.01 0.3246
## [10,] 9 -2.22 0.2403
## [11,] 10 -1.99 0.3310
## [12,] 11 -1.91 0.3620
## [13,] 12 -1.56 0.5015
## [14,] 13 -1.34 0.5782
## [15,] 14 -1.16 0.6408
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -2.21 0.4869
## [2,] 1 -2.78 0.2467
## [3,] 2 -3.22 0.0851
## [4,] 3 -3.59 0.0347
## [5,] 4 -3.39 0.0565
## [6,] 5 -2.96 0.1745
## [7,] 6 -2.88 0.2073
## [8,] 7 -3.21 0.0868
## [9,] 8 -3.04 0.1379
## [10,] 9 -3.48 0.0455
## [11,] 10 -3.15 0.0973
## [12,] 11 -2.86 0.2133
## [13,] 12 -2.51 0.3591
## [14,] 13 -2.41 0.4049
## [15,] 14 -2.24 0.4752
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
24
## const trend p aic bic
## [1,] 0 0 4 53.98123 74.26061
## [2,] 0 0 12 54.93903 102.25759
## [3,] 0 0 5 55.07313 78.73242
## [4,] 1 0 4 55.81398 79.47326
## [5,] 0 0 13 56.01841 106.71687
## [6,] 0 0 6 56.29025 83.32943
## [7,] 1 0 12 56.61626 107.31472
## [8,] 1 0 5 56.89064 83.92982
## [9,] 0 0 11 57.33228 101.27094
## [10,] 1 0 13 57.65940 111.73776
print(i5y_ADF_diff$ic_bic_diff)
for (i in 1:length(i5y_adq_idx_diff))
{
checkresiduals(
i5y_ADF_diff$ADF_est_diff[[i5y_adq_idx_diff[i]]])
}
25
Residuals from Regression with ARIMA(4,0,0) errors
0.5
0.0
−0.5
0.10
30
0.05
ACF
df$y
20
0.00
−0.05
10
−0.10
0
0 5 10 15 20 −1.0 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 3.8498, df = 6, p-value = 0.697
##
## Model df: 4. Total lags used: 10
26
Residuals from Regression with ARIMA(5,0,0) errors
1.0
0.5
0.0
−0.5
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(5,0,0) errors
## Q* = 3.42, df = 5, p-value = 0.6355
##
## Model df: 5. Total lags used: 10
27
Residuals from Regression with ARIMA(6,0,0) errors
1.0
0.5
0.0
−0.5
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(6,0,0) errors
## Q* = 3.2818, df = 4, p-value = 0.5118
##
## Model df: 6. Total lags used: 10
28
Residuals from Regression with ARIMA(4,0,0) errors
1.0
0.5
0.0
−0.5
0.10
30
0.05
ACF
df$y
20
0.00
−0.05
10
−0.10
0
0 5 10 15 20 −0.5 0.0 0.5 1.0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 3.8035, df = 6, p-value = 0.7032
##
## Model df: 4. Total lags used: 10
adf.test(diff(i5y))
29
## [3,] 2 -6.41 0.01
## [4,] 3 -6.33 0.01
## [5,] 4 -6.73 0.01
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -12.05 0.01
## [2,] 1 -8.35 0.01
## [3,] 2 -6.39 0.01
## [4,] 3 -6.32 0.01
## [5,] 4 -6.72 0.01
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
For {i5yt }, we fail to reject H0 at the 5% significance level for all specifications
except with a constant, trend and p = 3, 9. Again, p = 3 is one of four specifica-
tions in the adequate set. As with {i3yt }, we might lean towards inferring that
{i5yt } is not empirically distinguishable from a unit root process, but there would
be a nontrivial degree of uncertainty in this conclusion.
On the other hand, the null is rejected in all specifications for {∆i5yt }, leading
us to conclude that it is empirically distinguishable from I(1). Thus, we can infer
that {i5yt } is empirically distinguishable from any unit root process with an order
of integration greater than one, with a high degree of confidence. However, we do
not have conclusive inference on how distinguishable it is from an I(1).
Repeating for {i90dt } and {∆i90dt }, we obtain the following.
print(i90d_ADF_lev$ic_bic)
30
## [1,] 1 0 1 -116.7680 -103.24839
## [2,] 1 0 2 -119.4153 -102.51579
## [3,] 0 0 1 -111.5606 -101.42094
## [4,] 1 0 3 -121.5855 -101.30607
## [5,] 1 0 4 -124.6213 -100.96201
## [6,] 1 1 1 -115.5881 -98.68865
## [7,] 0 0 2 -112.1658 -98.64624
## [8,] 1 1 2 -118.3177 -98.03834
## [9,] 0 0 4 -117.4682 -97.18884
## [10,] 1 1 3 -120.3162 -96.65695
for (i in 1:length(i90d_adq_idx))
{
checkresiduals(i90d_ADF_lev$ADF_est[[i90d_adq_idx[i]]])
}
0.0
−0.5
−1.0
0.2 40
0.1 30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.0 −0.5 0.0 0.5
Lag residuals
##
31
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 19.272, df = 9, p-value = 0.02298
##
## Model df: 1. Total lags used: 10
0.0
−0.5
−1.0
0.15
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 8.1896, df = 7, p-value = 0.3162
##
## Model df: 3. Total lags used: 10
32
Residuals from Regression with ARIMA(4,0,0) errors
0.5
0.0
−0.5
−1.0
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 5.2493, df = 6, p-value = 0.5123
##
## Model df: 4. Total lags used: 10
33
Residuals from Regression with ARIMA(3,0,0) errors
0.5
0.0
−0.5
−1.0
40
0.10
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 8.3316, df = 7, p-value = 0.3043
##
## Model df: 3. Total lags used: 10
adf.test(i90d)
34
## [3,] 2 -3.19 0.0230
## [4,] 3 -3.71 0.0100
## [5,] 4 -3.16 0.0243
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -1.50 0.7837
## [2,] 1 -2.89 0.2003
## [3,] 2 -3.28 0.0749
## [4,] 3 -3.84 0.0178
## [5,] 4 -3.29 0.0736
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
For all specifications in the adequate set, we reject H0 at the 5% significance level
and conclude that {i90dt } is empirically distinguishable from a unit root process.
Since we infer that i90d is I(0), there is no need to run the test on {∆i90dt }.
Repeating for {i180dt } and {∆i180dt }, we obtain the following.
print(i180d_ADF_lev$ic_bic)
35
## [9,] 1 1 3 -37.21378 -13.55450
## [10,] 0 0 3 -29.18731 -12.28782
for (i in 1:length(i180d_adq_idx))
{
checkresiduals(i180d_ADF_lev$ADF_est[[i180d_adq_idx[i]]])
}
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
0.2 40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 11.854, df = 9, p-value = 0.2217
##
## Model df: 1. Total lags used: 10
36
Residuals from Regression with ARIMA(2,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 9.7071, df = 8, p-value = 0.2862
##
## Model df: 2. Total lags used: 10
37
Residuals from Regression with ARIMA(3,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 4.2242, df = 7, p-value = 0.7536
##
## Model df: 3. Total lags used: 10
38
Residuals from Regression with ARIMA(4,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 2.7058, df = 6, p-value = 0.8448
##
## Model df: 4. Total lags used: 10
39
Residuals from Regression with ARIMA(1,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
0.2
40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 11.99, df = 9, p-value = 0.2138
##
## Model df: 1. Total lags used: 10
40
Residuals from Regression with ARIMA(2,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 9.6403, df = 8, p-value = 0.2912
##
## Model df: 2. Total lags used: 10
41
Residuals from Regression with ARIMA(3,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 4.3218, df = 7, p-value = 0.7421
##
## Model df: 3. Total lags used: 10
42
Residuals from Regression with ARIMA(4,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 2.7166, df = 6, p-value = 0.8435
##
## Model df: 4. Total lags used: 10
adf.test(i180d)
43
## [3,] 2 -3.19 0.0228
## [4,] 3 -3.72 0.0100
## [5,] 4 -3.28 0.0184
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -1.71 0.6989
## [2,] 1 -2.99 0.1602
## [3,] 2 -3.28 0.0756
## [4,] 3 -3.84 0.0178
## [5,] 4 -3.40 0.0538
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
print(i180d_ADF_diff$ic_bic_diff)
44
i180d_adq_set_diff <- as.matrix(arrange(as.data.frame(
intersect(as.data.frame(i180d_ADF_diff$ic_aic_diff),
as.data.frame(i180d_ADF_diff$ic_bic_diff))),
const, trend, p))
for (i in 1:length(i180d_adq_idx_diff))
{
checkresiduals(i180d_ADF_diff$ADF_est_diff[[i180d_adq_idx_diff[i]]])
}
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
0.2
40
0.1 30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −1 0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 10.653, df = 10, p-value = 0.3852
##
## Model df: 0. Total lags used: 10
45
Residuals from Regression with ARIMA(1,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
10
−0.1
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 8.8595, df = 9, p-value = 0.4503
##
## Model df: 1. Total lags used: 10
46
Residuals from Regression with ARIMA(2,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −1 0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.4383, df = 8, p-value = 0.7099
##
## Model df: 2. Total lags used: 10
47
Residuals from Regression with ARIMA(3,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 2.9199, df = 7, p-value = 0.8923
##
## Model df: 3. Total lags used: 10
48
Residuals from Regression with ARIMA(4,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
0.0
ACF
df$y
20
−0.1 10
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(4,0,0) errors
## Q* = 3.0154, df = 6, p-value = 0.8069
##
## Model df: 4. Total lags used: 10
49
Residuals from Regression with ARIMA(2,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −1 0
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.4376, df = 8, p-value = 0.7099
##
## Model df: 2. Total lags used: 10
50
Residuals from Regression with ARIMA(3,0,0) errors
0.5
0.0
−0.5
−1.0
−1.5
0 50 100 150 200
0.1 40
30
ACF
0.0
df$y
20
−0.1 10
0
0 5 10 15 20 −1.5 −1.0 −0.5 0.0 0.5
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 2.9201, df = 7, p-value = 0.8923
##
## Model df: 3. Total lags used: 10
51
## [10,] 9 -4.76 0.01
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -8.31 0.01
## [2,] 1 -6.70 0.01
## [3,] 2 -5.32 0.01
## [4,] 3 -5.73 0.01
## [5,] 4 -5.43 0.01
## [6,] 5 -5.35 0.01
## [7,] 6 -4.97 0.01
## [8,] 7 -5.11 0.01
## [9,] 8 -4.66 0.01
## [10,] 9 -4.74 0.01
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -8.29 0.01
## [2,] 1 -6.68 0.01
## [3,] 2 -5.31 0.01
## [4,] 3 -5.72 0.01
## [5,] 4 -5.42 0.01
## [6,] 5 -5.34 0.01
## [7,] 6 -4.96 0.01
## [8,] 7 -5.12 0.01
## [9,] 8 -4.67 0.01
## [10,] 9 -4.76 0.01
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
52
Solution We need to construct an adequate set of ADF specifications for the
estimated residuals from the regression of i5yt on a constant, i3yt , i90dt , and
i180dt . A regression in R is implemented using the lm function.
Now, use the same approach as in Question 1 but with eg_res instead of an
observed sample.
print(egr_ADF_lev$ic_bic)
53
egr_adq_set <- as.matrix(arrange(as.data.frame(
egr_ADF_lev$ic_bic[c(1, 2, 4, 7), ]),
const, trend, p))
egr_adq_idx <- match(data.frame(t(egr_adq_set[, 1:3])),
data.frame(t(egr_ADF_lev$ic[, 1:3])))
for (i in 1:length(egr_adq_idx))
{
checkresiduals(egr_ADF_lev$ADF_est[[egr_adq_idx[i]]])
}
0.2
0.0
−0.2
0.1 40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.2 0.0 0.2 0.4
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 9.1103, df = 10, p-value = 0.5217
##
## Model df: 0. Total lags used: 10
54
Residuals from Regression with ARIMA(1,0,0) errors
0.2
0.0
−0.2
50
0.10
40
0.05
30
ACF
df$y
0.00
20
−0.05
−0.10 10
−0.15 0
0 5 10 15 20 −0.2 0.0 0.2 0.4
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.2714, df = 9, p-value = 0.6089
##
## Model df: 1. Total lags used: 10
55
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.0
−0.2
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.1884, df = 8, p-value = 0.7373
##
## Model df: 2. Total lags used: 10
56
Residuals from Regression with ARIMA(3,0,0) errors
0.2
0.0
−0.2
0.15
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
−0.15
0 5 10 15 20 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 5.7923, df = 7, p-value = 0.5642
##
## Model df: 3. Total lags used: 10
All residuals look OK. Hence, we can continue and use the function coint.test
from the aTSA package to implement the Engle-Granger test for each of the specifi-
cations in the adequate set. The inputs to coint.test are the dependent variable
in the regression, a matrix containing independent variables and the number of
lags to use in the unit root test on the residuals series.
We use a for loop to implement the test on each of the specifications in the
adequate set. Instead of generating output at each iteration, we use the option
output = F to suppress it and store the p-values in an easy-to-read table.
57
eg_test[, l] <- eg_l[1, 3]
colnames(eg_test)[l] <- paste("Lag", l)
}
print(eg_test)
For specifiations with no constant and no trend, the unit root in the residuals
is rejected at low significance levels. The best inference we can draw is that if
the residual in the regression i5yt on a constant, i3yt , i90dt , and i180dt is mean-
independent, then it also does not have a unit root. The reasoning behind this is
that if a residual series is mean-independent of the regressors, then its uncondi-
tional mean is zero. This scenario matches ADF specifications above that restrict
the constant to be zero.
2. any three processes are I(1) and cointegrated while a fourth is I(0); for
example, we could have that i3yt , i5yt and i90dt are cointegrated and i180dt
is is I(0). The same could hold for any other combination.
3. Any two processes are I(1) and cointegrated while the other two are I(0); for
example, we could have that i3yt and i5yt are cointegrated while i90dt and
i180dt are both I(0).
4. any two processes are I(1) and cointegrated, and the other two processes are
also I(1) and cointegrated, but the four processes are not all cointegrated
with each other in a single cointegrating relation;
58
5. all four processes are I(1) and cointegrated in a single cointegrating relation.
Which of these five scenarios prevails? It depends on what we assume about the
integration properties of the processes involved. Our unit root tests in Question 1
did not clearly reject a unit root in any of the processes, except {i90dt }. If {i90dt }
is I(0), then we can rule out scenarios 4 and 5.
In terms of scenarios 1-3, we can in principle make the unit root assumption about
any combination of i3yt on i5yt and i180dt , which will determine the appropriate
interpretation. The important thing to remember is that it is always an assump-
tion that a unit root exists! Whether or not it is a useful one depends on the
application.
4. Repeat Question 2 three more times but each time change the dependent
variable. Is the inference regarding cointegration affected?
Solution The steps are exactly the same if we replace the dependent variable.
For example, letting i3yt be the dependent variable, we obtain the following.
print(egr_ADF_lev$ic_bic)
59
## const trend p aic bic
## [1,] 0 0 0 -490.4155 -483.6557
## [2,] 0 0 1 -490.1551 -480.0154
## [3,] 1 0 0 -488.4332 -478.2935
## [4,] 0 0 2 -489.8021 -476.2825
## [5,] 1 0 1 -488.1889 -474.6693
## [6,] 1 1 0 -486.4333 -472.9137
## [7,] 0 0 3 -488.4683 -471.5688
## [8,] 1 0 2 -487.8534 -470.9539
## [9,] 1 1 1 -486.2086 -469.3091
## [10,] 1 0 3 -486.5075 -466.2281
for (i in 1:length(egr_adq_idx))
{
checkresiduals(egr_ADF_lev$ADF_est[[egr_adq_idx[i]]])
}
0.2
0.1
0.0
−0.1
−0.2
−0.3
0 50 100 150 200
0.1 40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.2 0.0 0.2
Lag residuals
##
60
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 7.9494, df = 10, p-value = 0.6338
##
## Model df: 0. Total lags used: 10
50
0.10
40
0.05
30
ACF
df$y
0.00
20
−0.05
−0.10 10
−0.15 0
0 5 10 15 20 −0.3 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 6.6997, df = 9, p-value = 0.6684
##
## Model df: 1. Total lags used: 10
61
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
−0.3
0 50 100 150 200
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.3 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.096, df = 8, p-value = 0.7473
##
## Model df: 2. Total lags used: 10
62
Residuals from Regression with ARIMA(3,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
−0.3
0 50 100 150 200
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.3 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 5.5928, df = 7, p-value = 0.588
##
## Model df: 3. Total lags used: 10
We obtain the same results as with i5yt being the dependent variable. In fact, noth-
ing of substance changes by setting i90dt or i180dt to be the dependent variables
63
either. Changing the dependent variable does not materially affect our inference
about cointegrating relations involving these four processes.
print(egr_ADF_lev$ic_bic)
for (i in 1:length(egr_adq_idx))
{
checkresiduals(egr_ADF_lev$ADF_est[[egr_adq_idx[i]]])
}
64
Residuals from Regression with ARIMA(0,0,0) errors
0.50
0.25
0.00
−0.25
0 50 100 150 200
0.1 40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.25 0.00 0.25 0.50
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 6.4587, df = 10, p-value = 0.7754
##
## Model df: 0. Total lags used: 10
65
Residuals from Regression with ARIMA(1,0,0) errors
0.50
0.25
0.00
−0.25
0 50 100 150 200
50
0.1
40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.25 0.00 0.25 0.50
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 6.1121, df = 9, p-value = 0.7287
##
## Model df: 1. Total lags used: 10
66
Residuals from Regression with ARIMA(2,0,0) errors
0.50
0.25
0.00
−0.25
0 50 100 150 200
50
0.1
40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.25 0.00 0.25 0.50
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.9864, df = 8, p-value = 0.6488
##
## Model df: 2. Total lags used: 10
67
Residuals from Regression with ARIMA(3,0,0) errors
0.50
0.25
0.00
−0.25
0 50 100 150 200
40
0.1
30
ACF
0.0
df$y
20
−0.1 10
0
0 5 10 15 20 −0.25 0.00 0.25 0.50
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 3.844, df = 7, p-value = 0.7976
##
## Model df: 3. Total lags used: 10
68
eg_reg <- lm( i180d ~ i3y + i5y + i90d, mydata)
eg_res <- eg_reg$residuals
print(egr_ADF_lev$ic_bic)
for (i in 1:length(egr_adq_idx))
{
checkresiduals(egr_ADF_lev$ADF_est[[egr_adq_idx[i]]])
}
69
Residuals from Regression with ARIMA(0,0,0) errors
0.25
0.00
−0.25
−0.50
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 8.1843, df = 10, p-value = 0.6108
##
## Model df: 0. Total lags used: 10
70
Residuals from Regression with ARIMA(1,0,0) errors
0.25
0.00
−0.25
−0.50
0 50 100 150 200
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.50 −0.25 0.00 0.25
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 6.6843, df = 9, p-value = 0.6699
##
## Model df: 1. Total lags used: 10
71
Residuals from Regression with ARIMA(2,0,0) errors
0.25
0.00
−0.25
−0.50
0 50 100 150 200
0.10 40
0.05
30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.8484, df = 8, p-value = 0.6642
##
## Model df: 2. Total lags used: 10
72
Residuals from Regression with ARIMA(3,0,0) errors
0.25
0.00
−0.25
−0.50
0 50 100 150 200
40
0.10
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.50 −0.25 0.00 0.25
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 4.0301, df = 7, p-value = 0.7763
##
## Model df: 3. Total lags used: 10
73
Residuals from Regression with ARIMA(5,0,0) errors
0.25
0.00
−0.25
−0.50
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
10
−0.1
0
0 5 10 15 20 −0.50 −0.25 0.00 0.25
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(5,0,0) errors
## Q* = 2.776, df = 5, p-value = 0.7345
##
## Model df: 5. Total lags used: 10
74
5. Next, use the data to test the expectations theory of the term structure of
interest rates (ETT). Specifically, investigate whether the spreads in the
Capital Market (i5y − i3y) and Money Market (i180d − i90d) are stable (and
therefore stationary assuming constant variances and auto-covariances).
print(cm_ADF_lev$ic_bic)
75
cm_adq_set <- as.matrix(arrange(as.data.frame(
cm_ADF_lev$ic_bic[c(2:3, 6:8, 10),]),
const, trend, p))
cm_adq_idx <- match(data.frame(t(cm_adq_set[, 1:3])),
data.frame(t(cm_ADF_lev$ic[, 1:3])))
for (i in 1:length(cm_adq_idx))
{
checkresiduals(cm_ADF_lev$ADF_est[[cm_adq_idx[i]]])
}
0.1
0.0
−0.1
−0.2
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −0.3 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 19.261, df = 10, p-value = 0.03707
##
## Model df: 0. Total lags used: 10
76
Residuals from Regression with ARIMA(1,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
30
0.1
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 12.915, df = 9, p-value = 0.1665
##
## Model df: 1. Total lags used: 10
77
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
0.15
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 10.092, df = 8, p-value = 0.2587
##
## Model df: 2. Total lags used: 10
78
Residuals from Regression with ARIMA(0,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
40
0.1
30
ACF
df$y
0.0 20
10
−0.1
0
0 5 10 15 20 −0.3 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(0,0,0) errors
## Q* = 19.346, df = 10, p-value = 0.03608
##
## Model df: 0. Total lags used: 10
79
Residuals from Regression with ARIMA(1,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
40
0.1 30
ACF
df$y
20
0.0
10
−0.1
0
0 5 10 15 20 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 12.354, df = 9, p-value = 0.1941
##
## Model df: 1. Total lags used: 10
80
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.1
0.0
−0.1
−0.2
0.15
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.2 −0.1 0.0 0.1 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 10.031, df = 8, p-value = 0.2629
##
## Model df: 2. Total lags used: 10
81
## lag ADF p.value
## [1,] 0 -3.48 0.045
## [2,] 1 -4.09 0.010
## [3,] 2 -3.04 0.141
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
For i5y − i3y, the test rejects a unit root for models except with a constant, no
trend and p = 2, which it fails to reject at the 5% significance level (although it
would be reject at the 6.2% level). We are unable to conclusively confirm the ETT
in the Capital Market.
print(mm_ADF_lev$ic_bic)
82
mm_adq_idx <- match(data.frame(t(mm_adq_set[, 1:3])),
data.frame(t(mm_ADF_lev$ic[, 1:3])))
for (i in 1:length(mm_adq_idx))
{
checkresiduals(mm_ADF_lev$ADF_est[[mm_adq_idx[i]]])
}
0.0
−0.2
−0.4
0 50 100 150 200
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.5858, df = 9, p-value = 0.5764
##
## Model df: 1. Total lags used: 10
83
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.0
−0.2
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
−0.15
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 7.7336, df = 8, p-value = 0.4599
##
## Model df: 2. Total lags used: 10
84
Residuals from Regression with ARIMA(3,0,0) errors
0.2
0.0
−0.2
40
0.10
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 7.1189, df = 7, p-value = 0.4166
##
## Model df: 3. Total lags used: 10
85
Residuals from Regression with ARIMA(1,0,0) errors
0.2
0.0
−0.2
−0.4
0 50 100 150 200
0.10 30
0.05
20
ACF
df$y
0.00
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.8281, df = 9, p-value = 0.5516
##
## Model df: 1. Total lags used: 10
86
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.0
−0.2
−0.4
0 50 100 150 200
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 7.6639, df = 8, p-value = 0.467
##
## Model df: 2. Total lags used: 10
87
Residuals from Regression with ARIMA(3,0,0) errors
0.2
0.0
−0.2
−0.4
0 50 100 150 200
40
0.10
0.05 30
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 6.6809, df = 7, p-value = 0.4628
##
## Model df: 3. Total lags used: 10
88
Residuals from Regression with ARIMA(1,0,0) errors
0.2
0.0
−0.2
−0.4
0 50 100 150 200
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.8597, df = 9, p-value = 0.5483
##
## Model df: 1. Total lags used: 10
89
Residuals from Regression with ARIMA(2,0,0) errors
0.2
0.0
−0.2
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
−0.15 0
0 5 10 15 20 −0.4 −0.2 0.0 0.2
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 7.6345, df = 8, p-value = 0.47
##
## Model df: 2. Total lags used: 10
adf.test(i180d - i90d)
90
## [3,] 2 -4.34 0.0100
## [4,] 3 -4.64 0.0100
## [5,] 4 -4.52 0.0100
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -3.40 0.0551
## [2,] 1 -4.26 0.0100
## [3,] 2 -4.33 0.0100
## [4,] 3 -4.64 0.0100
## [5,] 4 -4.52 0.0100
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
The test rejects a unit root for all models in the adequate set. Note that some
specifications lead to a failure to reject, but they are not in our adequate set, so
we can ignore them! We can confidently conclude that the money market spread
is I(0) and the ETT holds for the Money Market.
91
ECON3350: Applied Econometrics
for Macroeconomics and Finance
Tutorial 9: Modelling Volatility - II
1
library(forecast)
library(dplyr)
library(rugarch)
Next, load the data, extract the variables and plot them to get an idea on what
we are working with.
−0.1
−0.2
−0.3
To construct and adquate set of models, we use a similar approach to the one de-
veloped in Week 8 for the class of basic GARCH models. The additional dimension
considered here is whether the model includes the “threshold term’ ’.
Note that the rugarch package has a different naming convention for threshold
GARCH models. Specifically, what we refer to as TGARCH, is called the gjr-
GARCH in the package, whereas TGARCH denotes a slightly different model.
This is not uncommon, so it is always important to check the documentation of
any particular software / package carefully!
2
submods <- c("sGARCH", "gjrGARCH")
ARMA_TGARCH_est <- list()
ic_arma_tgarch <- matrix( nrow = 4 ˆ 2 * 2 ˆ 3, ncol = 7 )
colnames(ic_arma_tgarch) <- c("pm", "qm", "ph", "qh",
"thresh", "aic", "bic")
i <- 0; t0 <- proc.time()
for (pm in 0:3)
{
for (qm in 0:3)
{
for (ph in 0:1)
{
for (qh in 0:1)
{
for (thresh in 0:1)
{
i <- i + 1
ic_arma_tgarch[i, 1:5] <- c(pm, qm, ph, qh, thresh)
if (ph == 0 && qh == 0)
{
# no such thing as a homoscedastic threshold ARMA!
if (!thresh)
{
# for models with constant variance, the ugarchspec
# and ugarchfit functions do not work well;
# instead, the documentation advises to use
# arfimaspec and arfimafit
try(silent = T, expr =
{
ARMA_TGARCH_mod <- arfimaspec(
mean.model = list(armaOrder = c(pm, qm)))
3
ARMA_TGARCH_mod <- ugarchspec(
mean.model = list(armaOrder = c(pm, qm)),
variance.model = list(model = submods[1 + thresh],
garchOrder = c(ph, qh)))
##
## 166.33 2.6 211 NA NA
Note that we have selected the entire intersecting set of models. The next step is
to have a look at residual autocorrelation. As with the basic GARCH, one must
be careful in interpreting the Ljung-Box test with conditional heteroscedasticity.
Indeed, we will avoid it altogether and instead just examine the SACF.
4
for (i in 1:nmods)
{
sacf_tgarch[i,1:5] <- adq_set_arma_tgarch[i,1:5]
sacf_tgarch[i,6:15] <-
acf(ARMA_TGARCH_est[[adq_idx_arma_tgarch[i]]]@fit$z,
lag = 10, plot = F)$acf[2:11]
}
All the residuals look relatively small, so we do not eliminate any specifications
from the existing set of models. Hence, this is our adequate set.
Solution Plotting estimated volatilities is the same as for the basic GARCH
(note that we still do not get confidence intervals with the rugarch package).
5
ARMA(0,0)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(0,1)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
6
ARMA(0,1)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(0,2)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
7
ARMA(0,3)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(0,3)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
8
ARMA(1,0)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,0)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
9
ARMA(1,1)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,2)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
10
ARMA(1,2)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,3)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
11
ARMA(2,1)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(3,0)−TGARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
All volatility estimates generally look very similar across the specifications in the
adequate set. TGARCH vs GARCH specifications generally do not produce no-
ticeable differences for fixed pm , qm , ph and qh . However, larger ARMA lags (pm
and qm ) appear to be associated with larger “spikes’ ’ in volatilities when they do
occur.
12
(c) Draw inference on the existence of leverage effects.
for (i in 1:nmods)
{
if (adq_set_arma_tgarch[i, 5] == 1)
{
lambda_est <- ARMA_TGARCH_est[[
adq_idx_arma_tgarch[i]]]@fit$coef["gamma1"]
lambda_tvl <- ARMA_TGARCH_est[[
adq_idx_arma_tgarch[i]]]@fit$tval["gamma1"]
cat(paste0(title_tgarch[i], ": lambda_hat = ",
round(lambda_est, 2),
", t-value = ",
round(lambda_tvl, 2)),
"\n")
}
}
13
(d) Forecast volatility for the four trading days past the end of the sample.
for (i in 1:nmods)
{
plot(ugarchboot(ARMA_TGARCH_est[[adq_idx_arma_tgarch[i]]],
method = "Partial"), which = 3)
}
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
0.0105
forecast
bootstrapped
0.0095
sigma
0.0085
2 4 6 8 10
T+i
14
Sigma Forecast
with Bootstrap Error Bands
0.012 (q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.008 0.009 0.010 0.011
sigma
2 4 6 8 10
T+i
15
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.008 0.009 0.010 0.011
sigma
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
0.012
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
16
Sigma Forecast
with Bootstrap Error Bands
0.011 (q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.010
sigma
0.009
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
0.012
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
17
Sigma Forecast
with Bootstrap Error Bands
0.011 (q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.010
sigma
0.009
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
18
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.012
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.008 0.009 0.010 0.011
sigma
2 4 6 8 10
T+i
19
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.011
bootstrapped
0.010
sigma
0.009
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.011
bootstrapped
0.010
sigma
0.009
2 4 6 8 10
T+i
20
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.008 0.009 0.010 0.011
sigma
T+i
There are subtle differences between the volatility forecasts generated by different
GARCH and TGARCH specifications, but all agree that volatilities across the
forecast horizon will remain well below the levels estimated around 2005 and then
again in 2008/2009.
2. Consider a class of GARCH-M models for returns rt , with one ARCH lag
and one GARCH lag.
21
{
for (q in 0:3)
{
for (m in 0:1)
{
i <- i + 1
ic_arma_garchm[i, 1:3] <- c(p, q, m)
try(silent = T, expr =
{
ARMA_GARCHM_mod <- ugarchspec(
mean.model = list(armaOrder = c(p, q),
archm = m),
variance.model = list(garchOrder = c(1, 1)))
##
## 21.81 0.48 36.5 NA NA
22
nmods <- length(adq_idx_arma_garchm)
sacf_garchm <- matrix(nrow = nmods, ncol = 13)
colnames(sacf_garchm) <- c("p", "q", "m", 1:10)
for (i in 1:nmods)
{
sacf_garchm[i,1:3] <- adq_set_arma_garchm[i,1:3]
sacf_garchm[i,4:13] <-
acf(ARMA_GARCHM_est[[adq_idx_arma_garchm[i]]]@fit$z,
lag = 10, plot = F)$acf[2:11]
}
23
ARMA(0,0)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(0,0)−GARCHM(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
24
ARMA(0,1)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(0,1)−GARCHM(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
25
ARMA(0,3)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,0)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
26
ARMA(1,0)−GARCHM(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,1)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
27
ARMA(1,1)−GARCHM(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(1,2)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
28
ARMA(1,3)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
ARMA(2,1)−GARCH(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
29
ARMA(3,0)−GARCHM(1,1)
0.08
0.06
volatilities
0.04
0.02
0.00
All volatility estimates generally look very similar. Including the GARCH-in-mean
term appears to produce only a minor difference in estimated volatilities for fixed
p, q. The periods of high volatility match up to those estimated using GARCH
and TGARCH models.
for (i in 1:nmods)
{
if (adq_set_arma_garchm[i, 3] == 1)
{
archm_est <- ARMA_GARCHM_est[[
adq_idx_arma_garchm[i]]]@fit$coef["archm"]
archm_tvl <- ARMA_GARCHM_est[[
adq_idx_arma_garchm[i]]]@fit$tval["archm"]
cat(paste0(title_garchm[i], ": archm_hat = ",
30
round(archm_est, 2),
", t-value = ",
round(archm_tvl, 2)),
"\n")
}
}
(d) Forecast volatility for the four trading days past the end of the sample.
for (i in 1:nmods)
{
plot(ugarchboot(ARMA_GARCHM_est[[adq_idx_arma_garchm[i]]],
method = "Partial"), which = 3)
}
31
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
32
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.012
bootstrapped
sigma
0.010
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
33
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.012
bootstrapped
sigma
0.010
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
0.012
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
34
Sigma Forecast
with Bootstrap Error Bands
0.012 (q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
35
Sigma Forecast
with Bootstrap Error Bands
0.012 (q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
36
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.012
sigma
0.010
2 4 6 8 10
T+i
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
0.012
bootstrapped
0.010
sigma
2 4 6 8 10
T+i
37
Sigma Forecast
with Bootstrap Error Bands
(q: 5%, 25%, 75%, 95%)
forecast
bootstrapped
0.008 0.009 0.010 0.011
sigma
T+i
38
ECON3350: Applied Econometrics
for Macroeconomics and Finance
1
The file usdata.csv contains 209 observations on:
• yt ≡ log real per capita GDP (GDP); and
• rt ≡ the overnight Federal Funds Rate for the US (FFR).
1. For yt :
(a) Plot the observed time series and comment on potential trends.
Next, load the data and plot log real US GDP per capita. Clearly, per capita GDP
levels are increasing in the US over the sample period, so we suspect a trend exists
in the data generating process.
mydata <- read.delim("usdata.csv", header = TRUE, sep = ",")
2
Log Real US GDP per Capita
0.0
−0.5
y
−1.0
−1.5
Time (Quarters)
Solution ADF regression are specified by lag length p along with the inclusion /
exclusion of a constant and trend. Note that a trend is only included if a constant
is included (i.e., we do not consider specifications with a trend, but no constant).
With that in mind, we implement the familiar approach.
TT <- length(y)
ADF_est <- list()
ic <- matrix( nrow = 30, ncol = 5 )
colnames(ic) <- c("cons", "trend", "p", "aic", "bic")
i <- 0
for (const in 0:1)
{
for (p in 0:9)
{
i <- i + 1
ADF_est[[i]] <- Arima(diff(y), xreg = y[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = F)
3
ic[i,] <- c(const, 0, p, ADF_est[[i]]$aic,
ADF_est[[i]]$bic)
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
for (p in 0:9)
{
i <- i + 1
ADF_est[[i]] <- Arima(diff(y), xreg = y[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic[i,] <- c(const, 1, p, ADF_est[[i]]$aic,
ADF_est[[i]]$bic)
}
}
}
print(ic_aic)
4
## [6,] 1 0 3 -1377.156 -1357.130
## [7,] 0 0 2 -1367.494 -1354.144
## [8,] 1 1 4 -1380.779 -1354.079
## [9,] 0 0 1 -1362.530 -1352.518
## [10,] 1 0 4 -1375.519 -1352.156
The AIC prefers specifications with both a constant and trend as well as lag
lengths in the range p = 1, . . . , 5. The BIC ranking includes specifications with
both a constant and trend as well as lags p = 1, . . . , 3. However, it also includes
specifications with a constant only and lags p = 1, . . . , 2. Putting this information
together, we select the top five specifications preferred by the BIC.
adq_set <- as.matrix(arrange(as.data.frame(ic_bic[1:5,]),
const, trend, p))
adq_idx <- match(data.frame(t(adq_set[, 1:3])),
data.frame(t(ic[, 1:3])))
Finally, we check the residuals for all specifications in the adequate set.
for (i in 1:length(adq_idx))
{
checkresiduals(ADF_est[[adq_idx[i]]])
}
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
5
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 8.4811, df = 7, p-value = 0.2921
##
## Model df: 3. Total lags used: 10
0.02
0.00
−0.02
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 6.822, df = 6, p-value = 0.3376
##
## Model df: 4. Total lags used: 10
6
Residuals from Regression with ARIMA(1,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.7825, df = 6, p-value = 0.2545
##
## Model df: 4. Total lags used: 10
7
Residuals from Regression with ARIMA(2,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.4569, df = 5, p-value = 0.3627
##
## Model df: 5. Total lags used: 10
8
Residuals from Regression with ARIMA(3,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 5.466, df = 4, p-value = 0.2427
##
## Model df: 6. Total lags used: 10
As no obvious problems jump out from the residuals analysis, we proceed with the
adequate set constructed above.
(c) Implement the ADF test for a stochastic trend and draw inference
regarding the integration properties of yt .
9
## [1,] 0 -10.33 0.01
## [2,] 1 -5.31 0.01
## [3,] 2 -4.05 0.01
## [4,] 3 -3.79 0.01
## [5,] 4 -3.54 0.01
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -1.347 0.575
## [2,] 1 -0.931 0.721
## [3,] 2 -0.637 0.824
## [4,] 3 -0.648 0.820
## [5,] 4 -0.659 0.816
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -1.99 0.577
## [2,] 1 -2.45 0.385
## [3,] 2 -2.54 0.347
## [4,] 3 -2.44 0.390
## [5,] 4 -2.36 0.424
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
Since only “Type 2” and “Type 3” specifications are in our adequate set, we ignore
the output related to “Type 1” specifications.Consequently, for all specifications in
our adequate set, the null of unit root cannot be rejected. We conclude that the
process is not empirically distinguishable from an integrated process with a drift
(and possibly linear growth).
10
i <- i + 1
ADF_est_diff[[i]] <- Arima(diff(diff(y)),
xreg = diff(y)[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = F)
ic_diff[i,] <- c(const, 0, p, ADF_est_diff[[i]]$aic,
ADF_est_diff[[i]]$bic)
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
for (p in 0:9)
{
i <- i + 1
ADF_est_diff[[i]] <- Arima(diff(diff(y)),
xreg = diff(y)[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic_diff[i,] <- c(const, 1, p, ADF_est_diff[[i]]$aic,
ADF_est_diff[[i]]$bic)
}
}
}
print(ic_aic_diff)
11
print(ic_bic_diff)
Finally, we check the residuals for all specifications in the adequate set.
for (i in 1:length(adq_idx))
{
checkresiduals(ADF_est[[adq_idx[i]]])
}
12
Residuals from Regression with ARIMA(1,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 8.4811, df = 7, p-value = 0.2921
##
## Model df: 3. Total lags used: 10
13
Residuals from Regression with ARIMA(2,0,0) errors
0.02
0.00
−0.02
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 6.822, df = 6, p-value = 0.3376
##
## Model df: 4. Total lags used: 10
14
Residuals from Regression with ARIMA(1,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(1,0,0) errors
## Q* = 7.7825, df = 6, p-value = 0.2545
##
## Model df: 4. Total lags used: 10
15
Residuals from Regression with ARIMA(2,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(2,0,0) errors
## Q* = 5.4569, df = 5, p-value = 0.3627
##
## Model df: 5. Total lags used: 10
16
Residuals from Regression with ARIMA(3,0,0) errors
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(3,0,0) errors
## Q* = 5.466, df = 4, p-value = 0.2427
##
## Model df: 6. Total lags used: 10
As no obvious problems jump out from the residuals analysis, we proceed with
ADF test using specifications in the adequate set.
adf.test(diff(y))
17
## [2,] 1 -7.88 0.01
## [3,] 2 -7.21 0.01
## [4,] 3 -6.67 0.01
## [5,] 4 -6.66 0.01
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -10.60 0.01
## [2,] 1 -7.88 0.01
## [3,] 2 -7.21 0.01
## [4,] 3 -6.67 0.01
## [5,] 4 -6.68 0.01
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
A unit root is rejected at very small significance level for all specifications. Hence,
the differenced process is empirically distinguishable from an integrated process.
18
• Some specifications will be so bad that MLE will run into numerical problems
and return an error. We want to ignore these specifications in the least
disruptive way possible. The way to do it is to embed Arima as an argument
to the try function with the silent = T option. This in general a very
useful programming technique when automating a large number of steps that
may potentially cause errors.
TT <- length(y)
ARIMA_est <- list()
ic_arima <- matrix( nrow = (2 * 2 + 2) * 4 ˆ 2, ncol = 7 )
colnames(ic_arima) <- c("d", "cons", "trend", "p", "q", "aic",
"bic")
i <- 0
for (d in 0:1)
{
for (const in 0:1)
{
for (p in 0:3)
{
for (q in 0:3)
{
i <- i + 1
d1 <- as.logical(d)
c1 <- as.logical(const)
try(silent = T, expr =
{
ARIMA_est[[i]] <- Arima(y, order = c(p, d, q),
include.constant = c1)
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
i <- i + 1
if (d1)
{
x <- c(0,cumsum(1:(TT - 1)))
}
else
19
{
x <- NULL
}
try(silent = T, expr =
{
ARIMA_est[[i]] <- Arima(y, order = c(p, d, q),
xreg = x,
include.constant = c1,
include.drift = T)
print(ic_aic_arima)
20
## [6,] 1 1 0 1 1 -1378.786 -1365.436
## [7,] 1 1 0 0 1 -1375.166 -1365.153
## [8,] 0 1 1 2 1 -1385.080 -1365.026
## [9,] 1 1 1 1 0 -1378.280 -1364.930
## [10,] 0 1 1 1 2 -1383.951 -1363.897
The AIC generally prefers models with d = 0, while the BIC top 10 includes a
more varied mix of integrated and non-integrated ARMAs. It also seems helpful in
this case to compute the intersecting set of the top 10 AIC and top 10 BIC ranked
specifications.
ic_int_arima <- intersect(as.data.frame(ic_aic_arima),
as.data.frame(ic_bic_arima))
print(ic_int_arima)
Finally, we check the residuals for every model in the adequate set.
for (i in 1:length(adq_idx_arima))
{
checkresiduals(ARIMA_est[[adq_idx_arima[i]]])
}
21
Residuals from ARIMA(1,0,2) with drift
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,2) with drift
## Q* = 6.4524, df = 5, p-value = 0.2647
##
## Model df: 5. Total lags used: 10
22
Residuals from ARIMA(2,0,1) with drift
0.02
0.00
−0.02
0.15 40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,0,1) with drift
## Q* = 5.3012, df = 5, p-value = 0.3802
##
## Model df: 5. Total lags used: 10
23
Residuals from ARIMA(2,0,0) with drift
0.02
0.00
−0.02
0.15 40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,0,0) with drift
## Q* = 7.0155, df = 6, p-value = 0.3194
##
## Model df: 4. Total lags used: 10
24
Residuals from ARIMA(3,0,0) with drift
0.02
0.00
−0.02
0.15
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02 0.04
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(3,0,0) with drift
## Q* = 5.1452, df = 5, p-value = 0.3984
##
## Model df: 5. Total lags used: 10
25
Residuals from ARIMA(1,1,0) with drift
0.02
0.00
−0.02
0.10 40
0.05 30
ACF
df$y
0.00
20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,1,0) with drift
## Q* = 8.1496, df = 8, p-value = 0.419
##
## Model df: 2. Total lags used: 10
26
Residuals from ARIMA(2,1,0) with drift
0.02
0.00
−0.02
40
0.10
30
0.05
ACF
df$y
0.00 20
−0.05
10
−0.10
0
0 5 10 15 20 −0.02 0.00 0.02
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,1,0) with drift
## Q* = 6.6179, df = 7, p-value = 0.4697
##
## Model df: 3. Total lags used: 10
All the residuals look fine so our construction of the adequate set is complete.
2. Repeat parts (a)-(e) of Question 1 for rt (you do not need to do part (f)).
27
plot(dates, r, type = "l", xlab = "Time (Quarters)",
main = "Federal Funds Rate")
0.05
Time (Quarters)
TT <- length(r)
ADF_est <- list()
ic <- matrix( nrow = 30, ncol = 5 )
colnames(ic) <- c("cons", "trend", "p", "aic", "bic")
i <- 0
for (const in 0:1)
{
for (p in 0:9)
{
i <- i + 1
ADF_est[[i]] <- Arima(diff(r), xreg = r[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = F)
ic[i,] <- c(const, 0, p, ADF_est[[i]]$aic,
ADF_est[[i]]$bic)
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
28
for (p in 0:9)
{
i <- i + 1
ADF_est[[i]] <- Arima(diff(r), xreg = r[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic[i,] <- c(const, 1, p, ADF_est[[i]]$aic,
ADF_est[[i]]$bic)
}
}
}
print(ic_aic)
29
print(ic_int)
for (i in 1:length(adq_idx))
{
checkresiduals(ADF_est[[adq_idx[i]]])
}
0.050
0.025
0.000
−0.025
0 50 100 150 200
0.1 40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.025 0.000 0.025 0.050
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(6,0,0) errors
30
## Q* = 9.1461, df = 3, p-value = 0.02741
##
## Model df: 8. Total lags used: 11
0.050
0.025
0.000
−0.025
0 50 100 150 200
40
0.1
30
ACF
df$y
0.0
20
10
−0.1
0
0 5 10 15 20 −0.025 0.000 0.025 0.050
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(7,0,0) errors
## Q* = 3.3278, df = 3, p-value = 0.3438
##
## Model df: 9. Total lags used: 12
31
Residuals from Regression with ARIMA(7,0,0) errors
0.050
0.025
0.000
−0.025
0 50 100 150 200
0.1 40
30
ACF
0.0
df$y
20
−0.1 10
0
0 5 10 15 20 −0.025 0.000 0.025 0.050
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(7,0,0) errors
## Q* = 3.4685, df = 3, p-value = 0.3249
##
## Model df: 8. Total lags used: 11
Residuals all look reasonable, although some autocorrelations exceed the 95%
confidence intervals very slightly (and at larger lags). For robustness, we might
add a few models with a larger p into the adequate set, such as p = 8, 9.
Proceeding the the ADF test, the default option p ≤ 5 implemented in the
adf.test function is insuffcient, so we need to explicitly specify longer lag lengths
with the nlag option.
adf.test(r, nlag = 10)
32
## [5,] 4 -1.110 0.281
## [6,] 5 -1.324 0.205
## [7,] 6 -1.087 0.290
## [8,] 7 -0.871 0.367
## [9,] 8 -0.908 0.354
## [10,] 9 -0.880 0.364
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -2.30 0.2106
## [2,] 1 -2.86 0.0549
## [3,] 2 -2.40 0.1734
## [4,] 3 -2.76 0.0714
## [5,] 4 -2.71 0.0788
## [6,] 5 -3.16 0.0244
## [7,] 6 -2.70 0.0804
## [8,] 7 -2.26 0.2244
## [9,] 8 -2.37 0.1833
## [10,] 9 -2.31 0.2055
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -2.24 0.4757
## [2,] 1 -2.81 0.2363
## [3,] 2 -2.34 0.4328
## [4,] 3 -2.71 0.2769
## [5,] 4 -2.67 0.2935
## [6,] 5 -3.14 0.0992
## [7,] 6 -2.66 0.2974
## [8,] 7 -2.20 0.4895
## [9,] 8 -2.31 0.4439
## [10,] 9 -2.25 0.4693
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
Only “Type 1” and “Type 2” specifications are in our adequate set, so we ignore
the output related to “Type 3”. For all specifications in our adequate set, the null
of a unit root cannot be rejected.
Note, however, that there are specifications for which the null is indeed rejected.
One such specification includes a constant, but no trend contains p = 5 lags. We
observe that this is the 9th ranked specification by the BIC, and it is outside the
top 10 in terms of AIC.
We can summarise our inference as follows. The process is not empirically distin-
guishable from an integrated process with a drift, but there is a small element of
uncertainty in this conclusion.
Next, we repeat the construction of an adequate set of ADF regressions of ∆rt .
33
TT <- length(diff(r))
ADF_est_diff <- list()
ic_diff <- matrix( nrow = 30, ncol = 5 )
colnames(ic_diff) <- c("cons", "trend", "p", "aic", "bic")
i <- 0
for (const in 0:1)
{
for (p in 0:9)
{
i <- i + 1
ADF_est_diff[[i]] <- Arima(diff(diff(r)),
xreg = diff(r)[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = F)
ic_diff[i,] <- c(const, 0, p, ADF_est_diff[[i]]$aic,
ADF_est_diff[[i]]$bic)
}
if (const)
{
# only add a specification with trend if there is a
# constant (i.e., exclude no constant with trend)
for (p in 0:9)
{
i <- i + 1
ADF_est_diff[[i]] <- Arima(diff(diff(r)),
xreg = diff(r)[-TT],
order = c(p, 0, 0),
include.mean = as.logical(const),
include.drift = T)
ic_diff[i,] <- c(const, 1, p, ADF_est_diff[[i]]$aic,
ADF_est_diff[[i]]$bic)
}
}
}
print(ic_aic_diff)
34
## [1,] 0 0 6 -1368.762 -1342.100
## [2,] 0 0 7 -1367.974 -1337.980
## [3,] 1 0 6 -1366.834 -1336.839
## [4,] 1 0 7 -1366.045 -1332.718
## [5,] 0 0 8 -1365.990 -1332.662
## [6,] 1 1 6 -1365.403 -1332.076
## [7,] 0 0 9 -1364.708 -1328.048
## [8,] 1 1 7 -1364.569 -1327.909
## [9,] 1 0 8 -1364.061 -1327.401
## [10,] 1 0 9 -1362.778 -1322.785
print(ic_bic_diff)
for (i in 1:length(adq_idx_diff))
{
checkresiduals(ADF_est_diff[[adq_idx_diff[i]]])
}
35
Residuals from Regression with ARIMA(6,0,0) errors
0.050
0.025
0.000
−0.025
0 50 100 150 200
40
0.1
30
ACF
0.0
df$y
20
−0.1 10
0
0 5 10 15 20 −0.02 0.00 0.02 0.04 0.06
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(6,0,0) errors
## Q* = 2.1855, df = 3, p-value = 0.5348
##
## Model df: 7. Total lags used: 10
36
Residuals from Regression with ARIMA(7,0,0) errors
0.06
0.04
0.02
0.00
−0.02
0.1 40
30
ACF
df$y
0.0
20
−0.1 10
0
0 5 10 15 20 −0.025 0.000 0.025 0.050
Lag residuals
##
## Ljung-Box test
##
## data: Residuals from Regression with ARIMA(7,0,0) errors
## Q* = 3.424, df = 3, p-value = 0.3308
##
## Model df: 8. Total lags used: 11
As with levels, residuals look ok, but with some indication that longer lag lengths
should be considered. Finally, we implement the ADF test.
adf.test(diff(r), nlag = 10)
37
## [9,] 8 -5.28 0.01
## [10,] 9 -5.40 0.01
## Type 2: with drift no trend
## lag ADF p.value
## [1,] 0 -11.26 0.01
## [2,] 1 -10.78 0.01
## [3,] 2 -7.35 0.01
## [4,] 3 -6.58 0.01
## [5,] 4 -5.06 0.01
## [6,] 5 -5.69 0.01
## [7,] 6 -6.42 0.01
## [8,] 7 -5.55 0.01
## [9,] 8 -5.27 0.01
## [10,] 9 -5.39 0.01
## Type 3: with drift and trend
## lag ADF p.value
## [1,] 0 -11.25 0.01
## [2,] 1 -10.78 0.01
## [3,] 2 -7.35 0.01
## [4,] 3 -6.58 0.01
## [5,] 4 -5.05 0.01
## [6,] 5 -5.69 0.01
## [7,] 6 -6.43 0.01
## [8,] 7 -5.56 0.01
## [9,] 8 -5.28 0.01
## [10,] 9 -5.42 0.01
## ----
## Note: in fact, p.value = 0.01 means p.value <= 0.01
A unit root is rejected at very small significance level for all specifications. We
infer that FFR is not empirically distinguishable from an I(1) process.
38