10.5 Homework assignment II
Exchange rates can influence domestic inflation (through import prices), and inflation can affect exchange rates through purchasing power parity (PPP). To confirm this theory, import the monthly time-series data from EUROSTAT into RStudio, considering
inflation
and exchange
rates for Poland observed from January 2010
to December 2024
. Start the analysis by plotting both time-series and checking if they are stationary or nonstationary by using ur.df()
command from the package urca
.
Solution
Copy the code lines below to the clipboard and paste them into an R Script file opened in RStudio. In this example both time-series are nonstationary in the levels but stationary in the first differences, which means thatinflation
and exchange
are integrated of the same order \(I(1)\). This finding is supported by the failure to reject the ADF null hypothesis (presence of a unit root) in the levels, but the rejection of the null hypothesis in first differences at the \(5\%\) significance level for both variables.
# Loading the "eurostat" package from the library
library(eurostat)
# Loading inflation data from EUROSTAT with appropriate filters
# Note: arguments "sinceTimePeriod" and "untilTimePeriod" are applied only for quarterly or monthly data
=get_eurostat("prc_hicp_manr",
inflationfilters=list(coicop="CP00",
geo="PL",
sinceTimePeriod=2010,
untilTimePeriod=2024,
freq="M",
unit="RCH_A"),cache=FALSE)
# Note: one data is missing for December 2024 (179 observations in total)
# Converting the values of inflation into time-series object by ts() command
=ts(inflation$values,frequency=12,start=c(2010,1))
inflation
# Loading exchange rate from EUROSTAT with appropriate filters
=get_eurostat("ert_bil_eur_m",
exchangefilters=list(currency="PLN",
statinfo="AVG",
sinceTimePeriod=2010,
untilTimePeriod=2024,
freq="M",
unit="NAC"),cache=FALSE)
# Converting first 179 exchange rates into time-series object
# This ensures that two time-series are of the same length
=ts(exchange$values[1:179],frequency=12,start=c(2010,1))
exchange
# Plotting both time-series
layout(1:2)
ts.plot(inflation,main="Inflation in Poland",ylab="annual %",xlab="months")
ts.plot(exchange,main="Exchange rate to EUR", ylab="Polish zloty",xlab="months")
# Loading the "urca" package from the library
library(urca)
# Checking for (non)statinarity by ADF test in the levels and in first differences
# Note: when time-series does not exhibit trending behavior and has non-zero mean type="drift" is appropriate
# AIC lags selection criteria should be used just in case
summary(ur.df(inflation,type="drift",selectlags = "AIC"))
summary(ur.df(diff(inflation),type="drift",selectlags = "AIC"))
# Repeating ADF test for exchange rate
summary(ur.df(exchange,type="drift",selectlags = "AIC"))
summary(ur.df(diff(exchange),type="drift",selectlags = "AIC"))
\(~~~\)
When both variables are nonstationary and with the same integration order we should check if they are cointegrated in the next step, assuming that
exchange
rate is strictly exogenous variable. This requires checking (non)stationarity of residuals from a static
model (Engle-Granger approach). Thus, estimate a static
model by regressing inflation
on exchange
rate with dynlm()
command, and perform ADF test on it’s residuals (without drift and without linear trend, i.e. type=“none”
). Conclude if inflation
and exchange
rate are cointegrated or not, and explain what does it imply.
Solution
Copy the code lines below to the clipboard and paste them into an R Script file opened in RStudio. Null hypothesis of ADF test in the levels is rejected, indicating that residuals from astatic
model are stationary, i.e. integrated of order zero \(I(0)\), because the test statistic \(-2.7252\) is more negative than the critical value (tau
) \(-1.95\) at the \(5\%\) significance level. This finding confirms that inflation
and exchange
rate in Poland are cointegrated. It also implies that inflation
and exchange
rate are related both in the long-run and in the short-run.
# Loading "dynlm" package which is useful for estimating both static and dynamic regression models
library(dynlm)
=dynlm(inflation~exchange)
staticsummary(ur.df(resid(static),type="none",selectlags="AIC"))
\(~~~\)
When two variables (time-series) are related both in the long-run and in the short-run, a
static
model is treated as an equilibrium equation, which provides the long-run effect information. Additionally, error correction model (ECM) should be estimated as it combines short-run effect information with correction of short-term disequilibrium. Therefore, estimate ecm
using dynlm()
command and report results of both estimated models (static
and ecm
) in a single table by modelsummary()
command. What is the short-run and what is the long-run effect of the exchange rate on inflation? Are these effects statisticaly significant? Does speed of adjustment have expected negative sign?
Solution
Copy the code lines below to the clipboard and paste them into an R Script file opened in RStudio. From the equilibrium equation (static
model) we obtain the long-run effect of \(13.52\%\), which means that increase of \(1\) Polish zloty per EUR (exchange rate depreciation) will increase inflation for \(13.52\%\) in the long-run. From ECM we obtain the short-run effect of \(1.15\%\), which is also positive (inflation is boosted by exchange rate depreciation). Moreover, the long-run effect is significant at all significance levels, while the short-run effect is statistically significant only at \(10\%\) level. The speed of adjustment (correction term) in the ECM have expected negative sign (\(-0.0386\)), because the correction always happens in the opposite direction of the short-run disequilibrium and brings the system back into equilibrium or steady state.
# Estimating error correction model (ECM) proposed by Engle and Granger
=dynlm(d(inflation)~d(exchange)+L(resid(static)))
ecm# Presenting results of static and dynamic model (ecm) in a single table
library(modelsummary)
modelsummary(list("Static"=static,"ECM"=ecm),stars=TRUE,fmt=4)
\(~~~\)
Assuming that both variables are endogenously related (
exchange
effects inflation
and inflation
effects exchange
rate) estimate an VAR(\(p\)) model (Vector AutoRegression) with appropriate number of lags on the RHS. Beforehand, combine two time-series into a single object z
and select the appropriate number of lags \(p\) by employing VARselect()
command supported from vars
package. Apply modelsummary()
command to report results from VAR(\(p\)) model.
Solution
Copy the code lines below to the clipboard and paste them into an R Script file opened in RStudio. According to information criteria two of them (HQ and SC) suggest using \(2\) lags, while other two suggest \(5\) lags. The parsimony principle always gives a preference to a simpler model with less number of parameters and thus a fewer lags should be considered, unless the additional lags improves the model (with all variables stationary). Simpler (parsimonious) models are preferred as they are less likely to overfit and easier to interpret. Therefore, the VAR analysis continues with two lags (\(p=2\)).# Loading "vars" package from the library which supports VAR analysis
library(vars)
# Prior to appropriate lag selection, variables should be combined into one object
=cbind(inflation,exchange)
z
# Appropriate lag selection according to information criteria
VARselect(z,type="const",lag.max=12)
# Note: makes sense to specify the maximum number of lags to 12 when dealing with monthly data
# Estimating VAR(2) model with a constant (intercept) but no trend or other deterministic terms
=VAR(z,p=2,type="const")
var2
# Reporting the results of estimated VAR(2) model in a table
modelsummary(list("inflation"=var2[["varresult"]][["inflation"]],"exchange"=var2[["varresult"]][["exchange"]]), stars=TRUE,fmt=4)
\(~~~\)
Perform diagnostic checking of estimated VAR(\(2\)) model by applying the commands:
roots()
, serial.test()
, arch.test()
and normality.test()
. Afterwards, obtain Granger causality test in both directions by causality()
command and plot two orthogonal impulse response functions (OIRF). Finally, perform Johansen cointegration trace test with constant term but without linear trend to check the number of cointegrating relations (if any) by employing ca.jo()
command.
Solution
Copy the code lines below to the clipboard and paste them into an R Script file opened in RStudio. If the results are not consistent or if you have doubts about the validity of the results because the model was estimated using nonstationary variables, try re-estimating the model using first differences and one lag fewer compared to the initial model, i.e VAR(\(1\)) in the first differences (lets say objectvar1d
). But before that you may try to take the logs of exchange
rate to check if results of VAR(\(2\)) improves (both options are left to you to explore by using the codes you have learned so far).
# Diagnostic checking of VAR(2) model
roots(var2)
serial.test(var2,type="BG")
arch.test(var2)
normality.test(var2)
# Granger causality testing in both directions
causality(var2,cause="exchange")
causality(var2,cause="inflation")
# Plotting two OIRFs
plot(irf(var2,response="inflation",impulse="exchange",ortho=TRUE,boot=TRUE))
plot(irf(var2,response="exchange",impulse="inflation",ortho=TRUE,boot=TRUE))
# Performing Johansen trace test of cointegration
summary(ca.jo(z,type="trace",ecdet="const",K=2))