MarkovSwitchingSVAR#

class cultivars.multivariate.regime_switching.markov_switching.MarkovSwitchingSVAR(msvar, structurals=None, *, order=None)[source]

Bases: object

Per-regime structural identification of an MS-VAR, Sims-Waggoner-Zha.

Constructs with a fitted MarkovSwitchingVAR result. Not an _IdentificationModel: that contract is one closed system, and an MS-VAR has M of them – the regime views, each of which any scheme in this package already accepts directly. What this model adds is the discipline of one declaration for all regimes, and a packaged per-regime answer. Two routes: pass nothing (or order) and every regime is factorized recursively under one ordering; or identify each msvar.regime(m) yourself with any point-identified scheme and pass the results, which are checked by identity against the views they must have come from.

Variables:
  • _msvar – The fitted reduced form.

  • _structurals – The supplied per-regime identifications, or None for the recursive route.

  • _order – The recursive ordering, or None for names order.

See also

References

Sims, C. A., Waggoner, D. F., & Zha, T. (2008). Methods for inference in large multiple-equation Markov-switching models. Journal of Econometrics, 146(2), 255-274.

Example

>>> import numpy as np
>>> from cultivars.multivariate.regime_switching.markov_switching import MarkovSwitchingVAR
>>> rng = np.random.default_rng(0)
>>> p = np.array([[0.97, 0.03], [0.05, 0.95]])
>>> mu = np.array([[-1.0, -0.5], [1.5, 1.0]])
>>> s = np.zeros(600, dtype=int)
>>> y = np.zeros((600, 2))
>>> for t in range(1, 600):
...     s[t] = np.searchsorted(np.cumsum(p[s[t - 1]]), rng.random())
...     y[t] = mu[s[t]] + 0.3 * y[t - 1] + 0.4 * rng.standard_normal(2)
>>> res = MarkovSwitchingVAR(y, order=1, n_regimes=2).fit(seed=0, n_init=3)
>>> svar = MarkovSwitchingSVAR(res).identify()
>>> svar.impact(0).shape
(2, 2)

The packaging route takes identifications built from this fit’s own regime views, and refuses any other:

>>> from cultivars.multivariate.structural.zero_restrictions import RecursiveSVAR
>>> mine = [RecursiveSVAR(res.regime(m)).identify() for m in range(2)]
>>> bool(np.allclose(MarkovSwitchingSVAR(res, mine).identify().impact(1), svar.impact(1)))
True
>>> other = MarkovSwitchingVAR(y, order=1, n_regimes=2).fit(seed=1, n_init=3)
>>> theirs = [RecursiveSVAR(other.regime(m)).identify() for m in range(2)]
>>> MarkovSwitchingSVAR(res, theirs)
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: structurals[0] was not built from this MS-VAR's ...

Private attributes#