VECMXResult#

class cultivars.multivariate.reduced_form.error_correction.VECMXResult(*, 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, exog, exog_names, impact, contemporaneous)[source]#

A fitted conditional vector error-correction model.

The Pesaran-Shin-Smith specification: k_y modelled variables share a cointegrating space with k_x weakly exogenous integrated regressors, and only the modelled equations are estimated,

\[\Delta y_t = \alpha \beta' z_{t-1} + \sum_{i=1}^{p-1} \Gamma_i\, \Delta z_{t-i} + \Lambda_0\, \Delta x_t + \mu_t + u_t, \qquad z_t = (y_t', x_t')',\]

so beta spans the combined vector, Gamma is (k_y, k_y + k_x) because lagged differences of both blocks enter, and impact (\(\Lambda_0\)) carries the contemporaneous response to the exogenous differences. The regressors are weakly exogenous: they may share the long-run relations, but their own equations are not written and their adjustment to the disequilibria is assumed away rather than estimated.

Everything that reads the estimated regression is inherited and correct: params, bse, pvalues, conf_int, the residual diagnostics, the weak-exogeneity test, and the two-channel Granger test. What is not inherited is the half of the surface that needs a closed system. Impulse responses, the variance decomposition, the historical decomposition, the companion matrix, and the stability check all require a law of motion for every integrated variable in the system, and this model deliberately does not have one for x – that omission is the specification, not a gap. Those six raise rather than returning a number computed from the modelled block alone, which would look like an impulse response and be an artifact.

forecast() survives the same test and is kept: it needs a path for the exogenous block, not a model of it, so the caller supplies one exactly as for a VARX. to_varx() is the other thing a conditional model does have – its own equations in levels – and is what GVAR consumes to close several such units into one system.

Note

The inherited levels fields are placeholders here: coefficients is (0, k_y, k_y) and deterministic is (0, k_y), because the levels representation of a conditional model is not square and lives in to_varx() instead. n_common_trends counts the joint system, k_y + k_x - r, since the exogenous block carries its own unit roots. The rank may run to k_y rather than k_y - 1: every modelled variable cointegrating with the exogenous block is a valid conditional specification.

Variables:
  • exog – The weakly exogenous sample.

  • exog_names – Exogenous labels.

  • impact – (k_y, k_x) contemporaneous response to exogenous differences, zero-width when the model excludes it.

  • contemporaneous – Whether the current exogenous difference is included.

See also

  • VECMX – the model whose fit() returns this record.

  • VECMResult – the closed parent, whose short-run inference this result inherits and whose propagation surface it refuses.

  • VARXResult – the conditional levels model with the same refusals and the same to_varx() currency.

  • GVARResult – the closed system assembled from units like this one, where the refused members become available.

References

Pesaran, M. H., Shin, Y., & Smith, R. J. (2000). Structural analysis of vector error correction models with exogenous I(1) variables. Journal of Econometrics, 97(2), 293-343.

Harbo, I., Johansen, S., Nielsen, B., & Rahbek, A. (1998). Asymptotic inference on cointegrating rank in partial systems. Journal of Business & Economic Statistics, 16(4), 388-399.

Example

One modelled variable error-corrects toward an exogenous random walk while a second modelled variable wanders on its own. The conditional fit recovers the relation \(y_1 - x_1\), finds that y1 adjusts and y2 does not, and refuses an impulse response while forecasting along a supplied path for x:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> x = np.cumsum(rng.standard_normal(300))
>>> y1 = np.zeros(300)
>>> for t in range(1, 300):
...     y1[t] = y1[t - 1] + 0.4 * (x[t - 1] - y1[t - 1]) + 0.5 * rng.standard_normal()
>>> y = np.column_stack([y1, np.cumsum(rng.standard_normal(300))])
>>> res = VECMX(y, x[:, None], order=2, rank=1).fit()
>>> res.k_exog, res.n_common_trends, res.beta.shape
(1, 2, (3, 1))
>>> res.normalized_beta().ravel().round(1)
array([ 1.,  0., -1.])
>>> adjusts = [res.weak_exogeneity(name).pvalue < 0.05 for name in res.names]
>>> adjusts
[True, False]
>>> res.irf(4)
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: a conditional vector error-correction model has ...
>>> path = res.forecast(6, exog_future=np.full((6, 1), x[-1]))
>>> gap = path[:, 0] - x[-1]
>>> path.shape, bool(abs(gap[-1]) < abs(gap[0]))
((6, 2), True)

Attributes#

exog

The (nobs, k_x) weakly exogenous integrated regressors, in levels.

exog_names

Labels of the exogenous block, ``x1 .

impact

The (k_y, k_x) coefficients \(\Lambda_0\) on the current exogenous differences.

contemporaneous

Whether the current exogenous difference entered the short-run regression.

alpha

beta

bse

Standard errors, keyed identically to params.

coefficient_covariance

Covariance of the coefficient matrix, sampling or posterior.

coefficients

The (p, k, k) levels autoregressive matrices \(A_i\) the fit implies.

cointegrating_matrix

The long-run impact matrix \(\Pi = \alpha \beta'\), over the variables only.

cointegration_trend

companion

a conditional model has no closed companion.

design

deterministic

The (d, k) deterministic coefficients of the levels representation.

eigenvalues

endog

fittedvalues

gamma

information_criteria

AIC, BIC, and HQIC derived from the likelihood and parameter count.

is_stable

Whether every companion eigenvalue lies inside the unit circle.

k_endog

Number of endogenous variables.

k_exog

Weakly exogenous integrated regressors.

llf

n_common_trends

Unit roots the joint system carries, k_y + k_x - r.

n_params

names

nobs

order

params

Every coefficient, keyed "{equation}: {regressor}".

posterior

prior_label

pvalues

Two-sided p-values against zero, keyed identically to params.

rank

resid

short_run_deterministic

sigma_ml

sigma_u

trend

tvalues

Normal test statistics against zero, keyed identically to params.

Methods#

arch_test(variable[, lags])

Engle's LM test for conditional heteroskedasticity in one equation.

compare(*others[, criterion])

Rank this result against others by an information criterion.

conf_int(*[, alpha])

Confidence bounds for every coefficient.

equation(name)

The coefficients of one equation, keyed by regressor.

error_correction_terms()

The fitted disequilibria, one column per cointegrating relation.

fevd([horizon])

Unavailable: propagation needs a law of motion for the exogenous block.

forecast([steps, exog_future])

Point forecasts conditional on a future path for the exogenous block.

generalized_fevd([horizon])

Variance shares from the generalized responses, normalized to sum to one.

generalized_irf([horizon, cumulative])

Pesaran-Shin impulse responses, which do not depend on variable order.

granger_causality(cause, effect)

Test that one variable drives another through neither channel.

historical_decomposition()

Unavailable: propagation needs a law of motion for the exogenous block.

identify(strategy)

Declare an identification scheme and return the structural view.

irf([horizon, orthogonalized, cumulative])

Unavailable: propagation needs a law of motion for the exogenous block.

likelihood_ratio_test(unrestricted)

Test this result as the restricted model against a nesting one.

ma_representation([horizon])

Unavailable: propagation needs a law of motion for the exogenous block.

normality_test(variable)

Jarque-Bera test on one equation's residuals.

normalized_alpha(*[, on])

Adjustment loadings rescaled to pair with normalized_beta().

normalized_beta(*[, on])

Cointegrating vectors scaled so one variable's loading is one in each.

portmanteau_test([lags])

Multivariate Ljung-Box test for residual autocorrelation.

residual_diagnostics(*[, portmanteau_lags, ...])

Run every residual test and collect them into one table.

simulate([n, seed, burn])

A fresh sample path from the fitted system.

stability_check()

Unavailable: stability is a property of the closed system.

structural_shocks()

Orthogonalized innovations P^{-1} u_t, shape (nobs, k).

summary()

The estimation summary, renderable as text, HTML, or a dataframe.

to_var()

Unavailable: a conditional model has no levels representation.

to_varx()

The conditional levels form this error-correction model implies.

weak_exogeneity(variable)

Test that a variable does not adjust to any disequilibrium.