Bayesian VECM — II. Fisher effect — R cross-check¶
Vector autoregressions, Part 6b (R)¶
Validates bvecm_fisher_python.ipynb. Two urca tools: ur.df for the Augmented Dickey-Fuller unit-root tests (is each series I(1)?) and ca.jo for the Johansen rank test. Both should confirm the Python verdict — inflation is already stationary, so the Fisher pair is jointly stationary (full rank), not cointegrated.
Data: bvecm_fisher_data.csv — 3-month rate and annualised CPI inflation, quarterly 1959–2019 (FRED).
In [1]:
.libPaths('C:/Users/user/R/win-library/4.6')
suppressMessages(library(urca))
d <- read.csv('bvecm_fisher_data.csv'); Y <- d[, c('tbill','inflation')]
for (nm in c('tbill','inflation')) {
s <- summary(ur.df(Y[[nm]], type = 'drift', lags = 4, selectlags = 'AIC'))
cat(sprintf('ADF %-9s: stat %6.2f (5%% crit %.2f) -> %s\n', nm, s@teststat[1], s@cval[1,2],
ifelse(s@teststat[1] > s@cval[1,2], 'I(1): unit root not rejected', 'stationary I(0)')))
}
jo <- ca.jo(Y, type = 'trace', ecdet = 'none', K = 2, spec = 'transitory')
cat('\nJohansen trace test:\n'); print(round(cbind(trace = jo@teststat, jo@cval), 1))
cat('\ncross-check -> Python: tbill I(1), inflation I(0). Rank is borderline (urca r=1 vs statsmodels full rank,\n')
cat(' different critical-value tables on the 2nd trace stat); with inflation I(0) the Fisher cointegration premise fails either way.\n')
ADF tbill : stat -2.29 (5% crit -2.88) -> I(1): unit root not rejected ADF inflation: stat -3.14 (5% crit -2.88) -> stationary I(0)
Johansen trace test:
trace 10pct 5pct 1pct r <= 1 | 5.9 6.5 8.2 11.7 r = 0 | 48.5 15.7 18.0 23.5
cross-check -> Python: tbill I(1), inflation I(0). Rank is borderline (urca r=1 vs statsmodels full rank,
different critical-value tables on the 2nd trace stat); with inflation I(0) the Fisher cointegration premise fails either way.
Same verdict: no cointegration¶
ur.dfsplits the integration orders. The nominal rate does not reject a unit root (I(1)); inflation does (stationary, I(0)) — matching the Python ADF tests. With mixed orders, cointegration is undefined.- The rank is borderline, and it doesn't matter. On the second trace statistic the two packages disagree —
urca's Osterwald-Lenum critical values call it $r=1$, statsmodels' MacKinnon-Haug-Michelis values call it full rank — because the statistic sits right between the two tables. This ambiguity is itself the point: with inflation already I(0), the system does not have the clean unit-root structure a cointegration rank is meant to describe, so the exact rank is neither well-determined nor economically meaningful. - The lesson survives translation: pre-test the integration order before reaching for a VECM.
References¶
- Pfaff, B. (2008). Analysis of Integrated and Cointegrated Time Series with R. Springer.
- Mishkin, F. S. (1992). J. Monetary Economics 30, 195–215.