VECMResult#

class cultivars.multivariate.reduced_form.error_correction.VECMResult(*, endog, names, order, trend, sigma_u, sigma_ml, resid, fittedvalues, design, llf, nobs, n_params, posterior=None, prior_label='none', rank, cointegration_trend, alpha, beta, gamma, short_run_deterministic, eigenvalues, coefficients, deterministic)[source]

Bases: _ErrorCorrectionResult, _SummaryMixin, _ComparisonMixin, _VectorInferenceMixin, _VectorPropagationMixin

A fitted vector error-correction model.

A VAR of order \(p\) in \(k\) integrated variables, rewritten around its unit roots,

\[\Delta y_t = \Pi\, y_{t-1} + \sum_{i=1}^{p-1} \Gamma_i\, \Delta y_{t-i} + \mu_t + u_t, \qquad \Pi = \alpha \beta',\]

with \(\Pi\) of rank \(r < k\): the columns of \(\beta\) are the cointegrating vectors, \(\beta' y_{t-1}\) the stationary disequilibria, \(\alpha\) the speeds at which each variable corrects them, and \(k - r\) common stochastic trends drive the rest. Estimation is Johansen’s reduced-rank maximum likelihood: concentrate out the short-run terms, take \(\beta\) from the eigenvalue problem, then regress the differences on [deterministic | lagged differences | error-correction terms] for everything else.

The result carries two representations of one estimate, and each half of the inherited surface reads the one it needs.

The short-run representation is what was actually regressed: differences on deterministic terms, lagged differences, and the error-correction terms. design, resid, fittedvalues, and everything built on the coefficient covariance – params, bse, pvalues, conf_int – describe that regression, so a standard error here belongs to an alpha, a Gamma, or a deterministic term, conditional on beta. The conditioning is what makes them exact rather than approximate: beta converges at rate T against the usual root-T, fast enough that everything estimated alongside it behaves as though the cointegrating space were known.

The levels representation is the vector autoregression this model reparameterizes, recovered by to_var() and exposed as coefficients. Impulse responses, the variance decomposition, and the historical decomposition read it, which is why they are inherited rather than rewritten: an error-correction model has no separate impulse-response theory, only different coordinates.

Three members depart from the reduced-form surface deliberately. stability_check() permits unit roots, because k - r of them are the specification rather than a failure. forecast() folds any restricted deterministic term back out of the cointegrating space, since a constant that lives inside beta still shifts the level of a forecast. granger_causality() restricts both transmission channels at once.

Note

Two things this record does not do. It does not test its own rank: the Johansen trace and maximum-eigenvalue tests have non-standard null distributions and live on the model as rank_test(), to be read before a rank is chosen, and a likelihood-ratio comparison of this result against a levels VAR or a VECM of another rank through the inherited likelihood_ratio_test is a chi-squared test of a restriction that is not chi-squared and should not be read. And it reports no standard errors for beta: its asymptotics are mixed-Gaussian and conditional on the normalization, so the summary prints the cointegrating vectors without inference columns.

Variables:
  • endog – The sample in levels.

  • names – Variable labels, in Cholesky order.

  • order – Lags of the levels system; order - 1 lagged differences.

  • rank – Cointegrating rank.

  • cointegration_trend – The Johansen case the model was estimated under.

  • trend – Deterministic terms of the levels representation, with any restricted term folded back out.

  • alpha – (k, r) adjustment loadings.

  • beta – (k or k + 1, r) cointegrating vectors.

  • gamma – (p - 1, k, k) coefficients on lagged differences.

  • coefficients – (p, k, k) implied levels autoregressive matrices.

  • deterministic – (d, k) deterministic coefficients of the levels representation, restricted terms folded in.

  • short_run_deterministic – (d_s, k) unrestricted deterministic terms, as they entered the short-run regression.

  • eigenvalues – Squared canonical correlations, descending.

  • sigma_u – Residual covariance with the degrees-of-freedom correction.

  • sigma_ml – Residual covariance divided by the effective sample.

  • resid – Residuals of the short-run equation.

  • fittedvalues – Fitted differences.

  • design – The short-run regressor matrix.

  • llf – Gaussian log-likelihood.

  • nobs – Effective sample size.

  • n_params – Free parameters, covariance included.

See also

  • VECM – the model whose fit() returns this record and whose rank_test() chooses the rank.

  • VECMXResult – the conditional extension with weakly exogenous integrated regressors.

  • VARResult – the levels system this result reparameterizes and whose propagation surface it inherits.

  • GVAR – the assembler that links conditional error-correction units into one closed system.

References

Johansen, S. (1991). Estimation and hypothesis testing of cointegration vectors in Gaussian vector autoregressive models. Econometrica, 59(6), 1551-1580.

Johansen, S. (1995). Likelihood-Based Inference in Cointegrated Vector Autoregressive Models. Oxford University Press.

Lütkepohl, H. (2005). New Introduction to Multiple Time Series Analysis. Springer. Chapters 6-7.

Example

Two series sharing one stochastic trend, the second twice the first plus noise. At rank one the fit recovers the relation \(y_1 - y_2 / 2\) with the second variable doing all the adjusting, the levels companion carries exactly one unit root, and the inherited propagation surface reads the levels representation:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> common = np.cumsum(rng.standard_normal(300))
>>> y = np.column_stack([common, 2 * common + rng.standard_normal(300)])
>>> res = VECM(y, order=2, rank=1).fit()
>>> res.n_common_trends, res.trend
(1, 'c')
>>> res.normalized_beta().ravel().round(2)
array([ 1.  , -0.49])
>>> bool(res.pvalues["y1: ec1"] > 0.1), bool(res.pvalues["y2: ec1"] < 0.001)
(True, True)
>>> check = res.stability_check()
>>> check.n_unit_roots, bool(abs(check.max_modulus - 1.0) < 1e-6)
(1, True)
>>> res.irf(4).shape, res.forecast(3).shape
((5, 2, 2), (3, 2))

Private attributes#

_lag_offset

Short-run deterministic columns ahead of the lagged-difference block.

Private methods#

_coefficient_stack()

Short-run coefficients, laid out exactly as the design columns.

_comparison_label()

Short specification label for a ranking table.

_deterministic_labels()

Unrestricted deterministic column names of the short-run equation.

_from_fit(fit, model)

Assemble the public result from the internal fit and its model.

_lag_labels()

Lagged-difference column names.

_pivot(on)

The loadings of variable on across the cointegrating vectors, validated.

_summary_table()

Build the structured summary.

_trailing_blocks()

The adjustment loadings, laid out as design rows.

_trailing_labels()

Error-correction column names.