R : VAR Impulse Response Function

This post draws the orthogonal impulse response functions from an estimated VAR model with 1 standard deviation or 1 unit shock. vars R package does not provide 1 unit shock so I implemented it using the Cholesky decomposition.


Orthogonal IRF of VAR model





R code


The following R code loads yield curve data, calculates empirical yield factors, and estimates VAR(1) model using vars R package.

#========================================================#
# Quantitative Financial Econometrics & Derivatives 
# Machine/Deep Learing, R, Python, Tensorflow 
# by Sang-Heon Lee 
#
# https://shleeai.blogspot.com
#--------------------------------------------------------#
# Orthogonal Impulse Response
#========================================================#
graphics.off(); rm(list = ls())
 
library(vars)
 
#-----------------------------------------------------------
# Data : US Yield Curve 1972 - 2000
#-----------------------------------------------------------
url <- 'https://www.dropbox.com/s/inpnlugzkddp42q/bonds.csv?dl=1'
df  <- read.csv(url, sep = ";")
 
# Empirical yield factors
<- df[,"M120"]
<- df[,"M3"- df[,"M120"]
<- 2 * df[,"M30"- df[,"M3"- df[,"M120"]
 
# VAR endogenous variables
data  <- data.frame(L=L, S=S, C=C)
nvar  <- ncol(data)
nobs  <- nrow(data)
vname <- colnames(data)
head(data)
 
#-----------------------------------------------------------
# VAR estimation
#-----------------------------------------------------------
var.est <- VAR(data, p = 1, type = "const", season=NULL)
var.summary <- summary(var.est)
var.summary
 
cs


> head(data)
      L      S     C
1 6.088 -2.706 0.730
2 6.283 -2.813 0.327
3 6.269 -2.395 1.037
4 6.240 -2.592 0.820
5 6.249 -2.414 0.272
6 6.301 -2.200 0.710
 
cs



The orthogonal impulse responses with 1 SD (standard deviation) shocks are easily calculated using the irf() function as follows.

#-----------------------------------------------------------
# one SD shock IRF
#-----------------------------------------------------------
irf_1sd <- list()
for (im in 1:nvar) {
    irf_1sd[[im]] <- irf(var.est, impulse = vname[im], 
                         n.ahead = 36
                         ortho = TRUE, boot = TRUE)
    windows(width = 4, height = 6)
    plot(irf_1sd[[im]], lwd = c(3,1,1), col = "black"
         main = paste0("1 SD orthogonal IRF from ", vname[im]))
}
 
cs


R code : VAR Orthogonal Impulse Response, 1 unit shock


However, as far as I can tell, the irf() function does not provide the 1 unit shock IRFs. The IRFs based on 1 SD shock or 1 unit shock have the same shape, just different scales. In the latter case, the size of the shock is 1 unit, and since the unit of the variable used in this post is %, the 1 unit shock corresponds to the 1% shock. I calculate it by using the Cholesky decomposition as follows.

#-----------------------------------------------------------
# one unit shock IRF
#-----------------------------------------------------------
 
# Cholesky decomposition for scaling
# PP' = cov
= t(chol(var.summary$covres))
vscale <- diag(P); vscale
 
irf_1ut <- list() 
for (im in 1:nvar) {
 
    irf_1ut[[im]] <- irf_1sd[[im]]
    
    # To make shock size 1 unit, dividing by diag(P) 
    irf_1ut[[im]]$irf[[1]]   <- irf_1ut[[im]]$irf[[1]]/vscale[im]
    irf_1ut[[im]]$Lower[[1]] <- irf_1ut[[im]]$Lower[[1]]/vscale[im]
    irf_1ut[[im]]$Upper[[1]] <- irf_1ut[[im]]$Upper[[1]]/vscale[im]
    
    windows(width = 4, height = 6)
    plot(irf_1ut[[im]], lwd = c(3,1,1), col = "blue",
         main = paste0("1 unit orthogonal IRF from ", vname[im]))
}
 
cs


R code : VAR Orthogonal Impulse Response, 1 unit shock


It would be nice if the IRF plots generated by the irf() function were displayed in a matrix like EViews for multiple impulse shocks, but this is not the case. Therefore, we need to concatenate mannualy the IRF plots, which appear as a single column, horizontally,

In the next post, I'd like to discuss the IRF using the local projection of Jordà (2005), which takes nonlinearities into account to calculate IRFs.


No comments:

Post a Comment