Oil market SVAR — R cross-check¶

Vector autoregressions, Part 8a (R)¶

Validates oilsvar_python.ipynb. vars estimates the same recursive (Cholesky) oil-market SVAR by maximum likelihood; its orthogonalised impulse responses and forecast-error variance decomposition should reproduce the from-scratch Python results — a small price effect of supply, a demand-dominated oil price.

Data: oilsvar_data.csv — world oil production growth, the Kilian real-activity index, and the real oil price; monthly 1974–2019, VAR(24).

In [1]:
.libPaths('C:/Users/user/R/win-library/4.6')
suppressMessages(library(vars))
d <- read.csv('oilsvar_data.csv'); Y <- d[, c('prod_growth','rea','rpo')]
v <- VAR(Y, p = 24, type = 'const')                                # recursive ordering: supply, agg demand, oil-specific
fe <- fevd(v, n.ahead = 18)$rpo                                    # variance decomposition of the real oil price
cat('FEVD of the real oil price at h=18 (shares by shock):\n')
cat(sprintf('  oil supply %.2f | aggregate demand %.2f | oil-specific demand %.2f\n', fe[18,1], fe[18,2], fe[18,3]))
cat('cross-check -> Python: supply 0.02 / aggdem 0.17 / oilspec 0.81  (agree: demand-dominated)\n')

options(repr.plot.width = 13, repr.plot.height = 4)
ir <- irf(v, response = 'rpo', n.ahead = 18, ortho = TRUE, boot = FALSE)
sh <- c('prod_growth','rea','rpo'); lab <- c('oil supply','aggregate demand','oil-specific demand'); par(mfrow = c(1,3))
for (j in 1:3) {
  y <- ir$irf[[sh[j]]][, 'rpo']; y <- y * sign(y[1])              # normalise each shock to raise the oil price
  plot(0:18, y, type = 'l', col = 'firebrick', lwd = 2, xlab = 'months', ylab = '',
       main = paste('Real oil price to', lab[j])); abline(h = 0, col = 'grey60')
}
Warning message:
"package 'vars' was built under R version 4.6.1"
Warning message:
"package 'strucchange' was built under R version 4.6.1"
FEVD of the real oil price at h=18 (shares by shock):
  oil supply 0.02 | aggregate demand 0.16 | oil-specific demand 0.81
cross-check -> Python: supply 0.02 / aggdem 0.17 / oilspec 0.81  (agree: demand-dominated)
No description has been provided for this image

Same shocks, same verdict¶

  • Demand dominates the oil price. vars puts ~2% of the real-oil-price variance on supply and the rest on aggregate + oil-specific demand — matching the from-scratch Python SVAR.
  • The three IRFs have the three signatures. A supply disruption moves the price little; aggregate demand builds a hump; oil-specific demand jumps on impact — the maximum-likelihood counterpart of the Bayesian responses in the Python notebook.

References¶

  • Kilian, L. (2009). American Economic Review 99, 1053–1069.
  • Pfaff, B. (2008). VAR, SVAR and SVEC models: implementation in R (vars). J. Statistical Software 27(4).