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]
Bases:
VECMResultA fitted conditional vector error-correction model.
The Pesaran-Shin-Smith specification:
k_ymodelled variables share a cointegrating space withk_xweakly 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
betaspans the combined vector,Gammais(k_y, k_y + k_x)because lagged differences of both blocks enter, andimpact(\(\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 forx– 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 whatGVARconsumes to close several such units into one system.Note
The inherited levels fields are placeholders here:
coefficientsis(0, k_y, k_y)anddeterministicis(0, k_y), because the levels representation of a conditional model is not square and lives into_varx()instead.n_common_trendscounts the joint system,k_y + k_x - r, since the exogenous block carries its own unit roots. The rank may run tok_yrather thank_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 whosefit()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 sameto_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
y1adjusts andy2does not, and refuses an impulse response while forecasting along a supplied path forx:>>> 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)
Private methods#
Short-run coefficients, laid out exactly as the design columns. |
|
Short specification label for a ranking table. |
|
|
Assemble the public result from the internal fit and its model. |
Lagged-difference column names over the joint vector. |
|
|
Raise the shared explanation for a quantity the conditional model lacks. |
The impact block, then the adjustment loadings, in design order. |
|
Contemporaneous exogenous differences, then the error-correction terms. |