Jorda AER 2005 |
This computes the impulse responses by local projections from Jorda(2005). This does the New Keynesian model example (3 variable VAR using Cholesky factor shocks).
The calculations for this are actually quite simple. The \(h\) step responses are computed by regressing \(\bf{Y}_t\) on \(\bf{Y}_{t-h}\), \(\bf{Y}_{t-h+1}\), ... and extracting the coefficient vector on the leading lag (that is, the \(\bf{Y}_{t-h}\) in that. That \(M \times M\) matrix gives the local projection responses of the \(M\) variables (rows) to unit shocks in the \(M\) variables (columns). Different shock patterns can be obtained by post-multiplying that matrix by a set of weights on the unit shocks (in this case, by the Cholesky factor of the residuals from a standard VAR). Standard IRF's effectively do the same thing for multi-step responses except the multi-step projection is a known function of the standard VAR coefficients rather than being estimated directly.
The regression with skipped lags will have serially correlated errors. The standard errors of the IRF's are computed using some form of HAC covariance estimates for that lead coefficient matrix. Because there are different ways of computing those, the standard errors will differ as well.
A few things to note.
•The graphs in the RATS program label the impact shock as 0 (as is more typical) while Jorda uses 1.
•The RATS graphs are organized in the more typical way with variables across and shocks down. They also use a common scale going across for all responses of a given variable.
•This does not do the cubic projections. That's not dramatically more complicated, but it's not clear that there's a great advantage to it, and the cubic responses have to be linearized about some value for the lagged y's anyway (which the linear projection responses are independent of those).
This looks at the lag length choices using information criteria.
@varlagselect(lags=8,crit=sbc)
# ygap infl rate
@varlagselect(lags=8,crit=aic)
# ygap infl rate
The paper picks 4 based upon AIC, though the RATS AICC (AIC-corrected) very narrowly picks 6 over 4. We assume they use a slightly different form of the AICC.
This estimates the original VAR without lag gaps. You would typically get the impacts based upon this.
estimate
compute nregeqn=%nreg
This sets the number of steps of responses, the shocks to be used and the labels for the graph. In this case, the shocks are Cholesky shocks, so they are associated 1-1 with the variables. To use different shocks, change the way fshock is computed and make the required adjustment to the shocklabels. Note that FSHOCK does not have to be a square matrix if you don't need a full set of shocks.
compute nstep=12
compute fshock=%decomp(%sigma)
compute nshock=%cols(fshock)
compute shocklabels=||"Y-Gap","Inflation","Fed Funds"||
This computes the shocks using the standard VAR methods, saved into baseirf.
impulse(steps=nstep+1,factor=fshock,model=basevar,results=baseirf)
This sets up the arrays needed for the calculation of the multi-step responses. LINPRJIRF and LINPRJSTDERR will be the two end results. Both are RECT[SERIES] with the shock in the column and target series in the row, with LINPRJIRF for the IRF itself and LINPRJIRF for the standard error. PIX, PIXVAR and DELTAWT will be needed in the calculation.
dec rect pix(%nvar,%nvar) pixvar(%nvar,%nvar)
dec rect[series] linprjirf(%nvar,nshock)
dec rect[series] linprjstderr(%nvar,nshock)
clear(length=nstep+1) linprjirf linprjstderr
dec rect deltawt(%nregsystem,%nvar)
dec integer k
The impacts are the ones specified by the choice of the FSHOCK matrix. Because RATS series are based at entry 1, the impacts go in entry 1 and the h step responses into h+1.
compute %pt(linprjirf,1,fshock)
This creates the system of equations with the lags shifted to start at H. This is estimated by SUR using a Newey-West covariance matrix with H-1 lags (the theoretical number of autocorrelations in the error process for such a VAR). (Because the equations all have the same explanatory variables, the point estimates are the same as with least squares, equation by equation, but SUR is able to do the full system covariance matrix).
system(model=linvar)
variables ygap infl rate
lags h to h+nlags-1
det constant
end(system)
*
sur(model=linvar,robust,lwindow=newey,lags=h-1,noprint)
The calculation of the IRF itself is quite simple—you just need to pull out the matrix of VAR coefficients for lag H (using %MODELLAGMATRIX) and post-multiply it by the desired impact matrix.
compute pix=%modellagmatrix(linvar,h)
compute %pt(linprjirf,h+1,pix*fshock)
Getting the standard errors is somewhat more complicated. The response of variable I to a shock is a linear function of that lead lag matrix of coefficients in the VAR, so its variance will be a quadratic form in the covariance matrix of the lead lag coefficients. This pulls out into PIXVAR the covariance of the coefficients that are for equation I (DELTAWT is just 1's and 0's) in the proper places, and computes the standard errors as the square root of the quadratic form in the shock weights.
do i=1,%nvar
do j=1,%nvar
ewise deltawt(k,j)=(k==(i-1)*nregeqn+(j-1)*nlags+1)
end do j
compute pixvar=%mqform(%xx,deltawt)
do j=1,nshock
compute linprjstderr(i,j)(h+1)=sqrt(%qform(pixvar,%xcol(fshock,j)))
end do j
end do i
Finally, this organizes and graphs the IRF's for +/- two standard error bounds. As mentioned above, this does the more standard arrangement with target variables in the rows and shocks in the columns. All the graphs in a row use the same range to avoid misleading appearances by spreading a small range across an entire box.
dec vect[series] lower(nshock) upper(nshock)
spgraph(hfields=nshock,vfields=%nvar,xlabels=varlabels,ylabels=shocklabels,$
footer="Figure 5. Impulse Responses for the New Keynesian Model based on a VAR and Linear Projections")
do i=1,%nvar
*
* Compute the upper and lower bounds for each of the responses
* for variable i, then find the max and min across all the shocks
*
do j=1,nshock
set lower(j) 1 nstep+1 = linprjirf(i,j)-2.0*linprjstderr(i,j)
set upper(j) 1 nstep+1 = linprjirf(i,j)+2.0*linprjstderr(i,j)
end do j
table(noprint) 1 nstep+1 lower upper
do j=1,nshock
graph(row=i,col=j,number=0,min=%minimum,max=%maximum) 4
# baseirf(i,j)
# linprjirf(i,j)
# lower(j) / 3
# upper(j) / 3
end do j
end do i
spgraph(done)
Copyright © 2025 Thomas A. Doan