MarkovSwitchingVAR#

class cultivars.multivariate.regime_switching.markov_switching.MarkovSwitchingVAR(endog, *, order, n_regimes=2, switching_mean=True, switching_variance=True, switching_ar=False, trend='c', names=None)[source]

Bases: _MarkovSwitchingVectorAutoRegressionModel[MarkovSwitchingVARResult]

Markov-switching vector autoregression with M latent regimes.

The constructor is inherited from _MarkovSwitchingVectorAutoRegressionModel: it validates the panel and the VAR specification as the linear model does, then the regime count and the switching flags. At least one block must switch, and a switching mean needs a deterministic block to switch.

Parameters:
  • endog (ArrayLike) – The observed panel, shape (nobs, k).

  • order (int) – Autoregressive order within each regime.

  • n_regimes (int) – Number of latent regimes M, at least two.

  • switching_mean (bool) – Whether the deterministic block switches.

  • switching_variance (bool) – Whether the innovation covariance switches.

  • switching_ar (bool) – Whether the lag coefficients switch. Off by default: switching the lag block multiplies the parameter count by M and is rarely what identifies the regimes.

  • trend (Literal['n', 'c', 'ct']) – Deterministic terms per regime.

  • names (Sequence[str] | None) – One label per variable. Defaults to y1 ... yk.

Raises:
  • SpecificationError – If no block switches, if switching_mean is requested with trend="n", or if the order, trend or names are malformed.

  • DimensionError – If the sample cannot support M regimes of the specification.

Variables:
  • _endog – The validated (nobs, k) panel.

  • _names – The resolved variable labels.

  • _order – The autoregressive order.

  • _trend – The validated trend code.

  • _prior – Always _NoPrior; the EM has no shrinkage path.

  • _m – The number of regimes.

  • _sw_mean – Whether the deterministic block switches.

  • _sw_ar – Whether the lag block switches.

  • _sw_var – Whether the covariance switches.

See also

Example

>>> import numpy as np
>>> 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)
>>> bool(res.regimes[0].deterministic[0, 0] < res.regimes[1].deterministic[0, 0])
True
>>> MarkovSwitchingVAR(
...     y, order=1, switching_mean=False, switching_variance=False
... )
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: at least one of switching_mean, ...