LongRunSVAR#
- class cultivars.multivariate.structural.zero_restrictions.LongRunSVAR(result, *, order=None)[source]#
Long-run recursive identification, Blanchard-Quah (1989).
The restriction lives at the infinite horizon: the cumulated response matrix is lower triangular in the declared ordering, so the first shock is the only one with a permanent effect on the first variable, and so on. In the bivariate Blanchard-Quah economy – output growth first, unemployment second – the first shock is supply, the only one that moves the level of output forever, and demand is whatever remains. Computed in closed form: with \(F = A(1)^{-1} M(1)\) the long-run impact of the innovations,
\[F \Sigma_u F' = \Theta \Theta', \qquad \Theta \text{ lower triangular}, \qquad B = F^{-1} \Theta,\]the lower Cholesky factor of the long-run covariance is the long-run impact of the shocks, and the impact matrix is \(F^{-1}\) times it. The system must be stationary for \(F\) to exist, and nearly nonstationary systems make it ill-conditioned: the result is checked against the innovation covariance and refused when it fails to reproduce it.
- Parameters:
- Raises:
SpecificationError – If the result is not a closed system, is not stationary, or the ordering is not a permutation of its names.
- Variables:
_source – The closed reduced-form result being identified.
_perm – The ordering as column indices into the variable names.
See also
SVARResult– the complete result returned.RecursiveSVAR– the same triangle on the impact matrix.MixedSVAR– zeros split between the two horizons.
References
Blanchard, O. J., & Quah, D. (1989). The dynamic effects of aggregate demand and supply disturbances. American Economic Review, 79(4), 655-673.
Example
A bivariate system built so that the long-run impact matrix of the structural shocks is lower triangular: only the first shock moves the first variable’s level permanently. The long-run factorization recovers the impact matrix – which is not triangular – and the first shock series:
>>> import numpy as np >>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR >>> rng = np.random.default_rng(0) >>> A = np.array([[0.5, 0.1], [0.0, 0.4]]) >>> F = np.array([[1.0, 0.0], [0.5, 1.0]]) >>> B = (np.eye(2) - A) @ F >>> eps = rng.standard_normal((602, 2)) >>> y = np.zeros((602, 2)) >>> for t in range(1, 602): ... y[t] = A @ y[t - 1] + B @ eps[t] >>> res = VAR(y, order=1, names=("dy", "u")).fit() >>> svar = LongRunSVAR(res).identify() >>> svar.scheme, svar.shock_names, svar.is_complete ('long-run', ('dy', 'u'), True) >>> svar.long_run_impact.round(2).tolist() [[1.06, -0.0], [0.67, 0.94]] >>> svar.impact.round(2).tolist(), B.round(2).tolist() ([[0.44, -0.11], [0.31, 0.58]], [[0.45, -0.1], [0.3, 0.6]]) >>> bool(np.corrcoef(svar.structural_shocks()[:, 0], eps[1:, 0])[0, 1] > 0.95) True
Attributes#
Methods#
|
Factor the long-run covariance and map back to impact. |