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)
Same shocks, same verdict¶
- Demand dominates the oil price.
varsputs ~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).