Illustrating the new LPIRF Stata 18’s command

Good news! In the new version of Stata 18, we have a new command that produces local-projection impulse–response functions. You can find the complete description of the command here. Local projections were introduced in 2005 by Òscar Jordà in the following AER article: Estimation and Inference of Impulse Responses by Local Projections.

To illustrate the new Stata command, we will use the database found in a previous article of mine, written with Valérie Mignon and Yifei Cai. We will start the Stata code by estimating a SVAR from January 2000 to December 2019. The variables involved are: political tension between US and China, a proxy for the oil demand, the oil production and the real price of oil. We use short-run restrictions based on a Cholesky decomposition. Once model is estimated, we will retrieve the structural shocks. As explained to me by Miguel Dorta (Stata Corp), I can use the matrix command to recover the structural shock from a VAR model with the A and B matrixes:

/*

In the "Short-run SVAR models" section of the "[TS] var intro" manual 
(PDF documentation) you can see that 

     A*epsilon_t = B*e_t
     
Where e_t is the matrix of structural shocks and epsilon_t is the matrix of
the residuals for the reduced form VAR model. Therefore,

     e_t = inv(B)*A*epsilon_t 
     
Below is an example that computes the structural shocks (e_t).

*/

Now, I will reproduce the code to draw a time-series plot for the structural residuals (e1) and the reduced-form residuals (Residuals).

**# Analysing US-CHN tensions on oil price
**********************************************************

version 18.0
set more off
cd "C:\Users\jamel\Dropbox\stata\lpirf"
capture log close                               
log using blog-lpirf.smcl, replace

import excel .\data_svar.xlsx,/*
*/ sheet("data") firstrow clear

generate mth = tm(1960m1) + _n-1
format %tm mth

label variable pri "Political Relationship Index"
label variable pri_s "PRI Standardized"
label variable gop "Global Oil Production"
label variable rspri "Real Spot Price"
label variable wip "World Industrial Production"
label variable dinv "Variation of Inventories"
label variable gprcn ///
"Percent of Articles on China in the Bil. GPR"

rename gop pro
rename wip dem
rename rspri rpo

capture generate lpro = log(pro)
la var lpro "Natural log of PRO"
capture generate lrpo = log(rpo)
la var lpro "Natural log of RPO"
capture generate ldem = log(dem)
la var ldem "Natural log of DEM"

drop t
order mth, first

**#  Declare time series

tsset mth, monthly

matrix A = (1,0,0,0\.,1,0,0\.,.,1,0\.,.,.,1)
matlist A

matrix B = (.,0,0,0\0,.,0,0\0,0,.,0\0,0,0,.) 
matlist B

svar lpri lpro ldem lrpo if mth>tm(2000m1), aeq(A) beq(B) ///
lags(1/24) 

/* compute the inv(B)*A matrix */
matrix A=e(A)
matrix B=e(B)
matrix BA = inv(B)*A
/* compute reduced form epsilon_t residuals */
var lpri lpro ldem lrpo if mth>tm(2000m1)
capture drop epsilon*
predict double epsilon1 if mth>tm(2000m1),residual eq(#1)
predict double epsilon2 if mth>tm(2000m1),residual eq(#2)
predict double epsilon3 if mth>tm(2000m1),residual eq(#3)
predict double epsilon4 if mth>tm(2000m1),residual eq(#4)
/* store the epsilon* variables in the epsilon matrix */
mkmat epsilon*, matrix(epsilon) 
/* compute e_t matrix of structural shocks */
matrix e = (BA*epsilon')'
/* store columns of e as variables e1, e2, and e3 */  
svmat double e

twoway (tsline e1 if mth>tm(2000m1)) (tsline epsilon1 ///
if mth>tm(2000m1), yaxis(2)), ///
 name(G1, replace)
 
graph export "G1.svg", as(svg) replace

You need to be careful on the matrixes size and each epsilon corresponds to the structural shock in the ordering, namely, US–China political relations at first, oil supply, oil demand, and, at last, oil prices.

Once I have the structural shocks, I will follow now the approach presented on the Stata website with identified shocks obtained at the previous step to estimate the impact of an unanticipated improvement of political relationship will produce on the real price of oil:

irf set comparemodels.irf, replace
quietly lpirf lpro ldem lrpo, step(48) lags(1/24) ///
  exog(L(0/24).e1)
irf create lpmodel 

quietly var lpro ldem lrpo, lags(1/24)            ///
  exog(L(0/24).e1)
irf create varmodel, step(48)

irf graph dm, impulse(e1) response(lrpo)   ///
  irf(lpmodel varmodel) level(95) name(G2, replace) ///
    xline(0 10 20 30 40 50, lcolor(blue)) yline(-.05 0 .05 .1, lcolor(blue))

graph export "G2.svg", replace

Here, we assess the impact of political relations shocks on the real price of oil. The dynamic is similar between the dynamic multipliers, but the oil price increase is more significant in the LP than in the VAR.

We can redo the same exercise for the well-established bilateral Geopolitical Risk index for China. The bilateral GPR index measures the share of press articles related to a specific country, here, China in the leading US journal. So, the interpretation of impulse-response functions could be quite different from the case of the political relation index between China and the US from the Chinese perspective.

The results are very interesting. In the LP, an increase of the bilateral GPR (share of press articles on China) produces an increase that persists for several months. Maybe, before Trump’s trade war, an unanticipated increase in the share of articles on China were associated with good news that positively impacted the real price of oil. The results are quite different in the SVAR. I reproduce the code below.

/* GPR */

svar gprcn lpro ldem lrpo if mth>tm(2000m1), aeq(A) beq(B) ///
lags(1/24) 

/* compute the inv(B)*A matrix */
matrix A=e(A)
matrix B=e(B)
matrix BA = inv(B)*A
/* compute reduced form epsilon_t residuals */
var gprcn lpro ldem lrpo if mth>tm(2000m1)
capture drop epsilon*
predict double epsilon1 if mth>tm(2000m1),residual eq(#1)
predict double epsilon2 if mth>tm(2000m1),residual eq(#2)
predict double epsilon3 if mth>tm(2000m1),residual eq(#3)
predict double epsilon4 if mth>tm(2000m1),residual eq(#4)
/* store the epsilon* variables in the epsilon matrix */
mkmat epsilon*, matrix(epsilon) 
/* compute e_t matrix of structural shocks */
matrix e_ = (BA*epsilon')'
/* store columns of e as variables e1, e2, and e3 */  
svmat double e_

twoway (tsline e_1 if mth>tm(2000m1)) (tsline epsilon1 ///
if mth>tm(2000m1), yaxis(2)), ///
 name(G3, replace)
 
graph export "G3.svg", as(svg) replace

irf set comparemodels1.irf, replace
quietly lpirf lpro ldem lrpo, step(48) lags(1/24) ///
  exog(L(0/24).e_1)
irf create lpmodel1

quietly var lpro ldem lrpo, lags(1/24)            ///
  exog(L(0/24).e_1)
irf create varmodel1, step(48)

irf graph dm, impulse(e_1) response(lrpo)   ///
  irf(lpmodel1 varmodel1) level(95) name(G4, replace) ///
    xline(0 10 20 30 40 50, lcolor(blue)) yline(-.05 0 .05 .1, lcolor(blue))

graph export "G4.svg", replace

twoway (tsline e_1 if mth>tm(2000m1)) (tsline e1 ///
if mth>tm(2000m1), yaxis(1)), ///
 name(G5, replace)
 
graph export "G5.svg", replace

save lpirf_EEter, replace

Conclusion: we illustrate the new LPIRF command in Stata 18. An improvement of political relation between the US and China and / or an increase in the share of articles related to China can cause an increase in the real price of oil in the short-run during 10 months. While LP and VAR impulse-response functions have similar patterns in the medium run, the LP impulse-response functions seem to capture short-run dynamics.

Please note that the files for replicating this blog are (or will be) available here: https://github.com/JamelSaadaoui/EconMacroBlog

3 Comments

Hi Jamel,
I am an undergraduate student at the University of Warwick. I am currently doing my dissertations and wish to decompose oil price shocks using the svar function in stata. I then wish to produce an IRF graph to analyse the effect of structural oil price shocks on financial market data I have collected on a set of countries. Following the code in this blog, I am unable to run an IRF graph on my svar as the shock is treated as an exogenous variable. How should I go about this?

Your guidance on the above would be deeply appreciated.

Hi Ishmael,
Thanks for your question, plotting structural IRFs after the var or svar command is possible with Stata. In this blog, we first identify a exogenous with the svar command, then, we use the identified shocks in Local Projections.
Is that sufficiently clear for you?
Kind regards,
Jamel

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.