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