cultivars.multivariate.regime_switching.markov_switching#

The Markov-switching VAR: latent regimes, and a posterior instead of a date.

An M-regime vector autoregression

\[y_t = D_{S_t} d_t + \sum_{i=1}^{p} A_{i, S_t}\, y_{t-i} + u_t, \qquad u_t \mid S_t = m \sim N(0, \Sigma_m), \qquad \Pr(S_t = j \mid S_{t-1} = i) = P_{ij},\]

whose deterministic block, lag coefficients and innovation covariance may each switch with a latent first-order Markov chain (Krolzig 1997; Sims and Zha 2006). Where the threshold and smooth-transition families compute their regime from an observable, here the regime is never observed at all: what comes back is a posterior over states at every date, and every reported quantity – fitted values, residuals, even the regime a date “is in” – is an expectation under that posterior rather than a fact about the data. Estimation is EM on the same Hamilton filter and Kim smoother that power the univariate family: the E-step filters and smooths per-regime multivariate Gaussian densities, and the M-step updates the transition matrix from expected transition counts and all regimes’ coefficient blocks in one probability-weighted GLS system, so a non-switching block is estimated jointly across regimes rather than per regime and then averaged. The likelihood is multimodal, so fit screens several starts and refines the best – which is why it takes a seed and reports convergence.

Two commitments shape the surface. First, the two facts about mixtures that a reader would otherwise have to remember are enforced. The likelihood is invariant to permuting regime labels, so a sorting convention is imposed and label_ordering names it on every result; without it two runs of the same model could not be compared coefficient by coefficient. And the number of regimes cannot be tested by a likelihood ratio – under the null of fewer regimes the extra regime’s parameters are unidentified and its transition probabilities sit on the boundary – so that specific comparison is refused while tests holding M fixed remain available. Second, the regime is the composition hook. Conditional on the chain sitting in regime m the model is a linear VAR, and MarkovSwitchingVARResult.regime() returns that system dressed as a closed reduced form, identity-stable across calls, which every identification model in structural accepts directly. MarkovSwitchingSVAR builds on exactly that: one declaration, applied per regime, with the responses held frozen in the regime they were computed in and read against its expected duration.

Layout. MarkovSwitchingVAR is a thin fit() over _MarkovSwitchingVectorAutoRegressionModel in _internals, which extends the linear VAR model with the regime count and switching flags, builds per-regime selection matrices for the joint M-step, runs hamilton_filter and kim_smoother from _internals inside _run_em, and screens starts in _fit_markov before applying the label permutation. MarkovSwitchingVARResult carries the summary and comparison mixins and builds one _RegimeSystemResult per regime, the closed-system view the structural layer and MarkovSwitchingSVAR consume; its _likelihood_ratio_obstacle is where the regime-count test is refused. MarkovSwitchingDFM is a separate estimator on the same substrate: the Kim-Nelson one-factor model with a switching intercept, written as a _RegimeSwitchingLinearStateSpace and maximized through the continuous-state Kim filter, returning MarkovSwitchingDFMResult with the smoothed low-state probability as its chronology. The scalar family is regime_switching; the observed-regime alternatives are threshold and smooth_transition.

References

Hamilton, J. D. (1990). Analysis of time series subject to changes in regime. Journal of Econometrics, 45(1-2), 39-70.

Kim, C.-J. (1994). Dynamic linear models with Markov-switching. Journal of Econometrics, 60(1-2), 1-22.

Krolzig, H.-M. (1997). Markov-Switching Vector Autoregressions: Modelling, Statistical Inference, and Application to Business Cycle Analysis. Springer. Chapters 6 and 9.

Kim, C.-J., & Nelson, C. R. (1998). Business cycle turning points, a new coincident index, and tests of duration dependence based on a dynamic factor model with regime switching. Review of Economics and Statistics, 80(2), 188-201.

Sims, C. A., & Zha, T. (2006). Were there regime switches in U.S. monetary policy? American Economic Review, 96(1), 54-81.

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

Two regimes that differ in mean and scale around a common lag block. The fit dates the regimes, the comparison against the one-regime VAR is refused on principle while the comparison against a nested switching specification goes through, and a recursive identification applied per regime gives one impact matrix for each:

>>> import numpy as np
>>> from cultivars.multivariate.reduced_form.vector_autoregression import VAR
>>> rng = np.random.default_rng(0)
>>> s = np.repeat([0, 1, 0, 1], 100)
>>> y = np.array([[-1.0, -0.5], [1.5, 1.0]])[s] + 0.4 * rng.standard_normal((400, 2))
>>> res = MarkovSwitchingVAR(y, order=1, n_regimes=2, names=("a", "b")).fit(seed=0)
>>> res.specification, bool((res.most_likely_regime == s[1:]).mean() > 0.98)
('MSIH(2)-VAR(1)', True)
>>> res.likelihood_ratio_test(VAR(y, order=1).fit())
Traceback (most recent call last):
cultivars.exceptions.SpecificationError: a chi-squared likelihood-ratio test cannot compare ...
>>> nested = MarkovSwitchingVAR(y, order=1, n_regimes=2, switching_variance=False)
>>> nested.fit(seed=0).likelihood_ratio_test(res).df
3
>>> svar = MarkovSwitchingSVAR(res).identify()
>>> svar.shock_names, svar.impact(0).shape, svar.irf(4, regime=1).shape
(('a', 'b'), (2, 2), (5, 2, 2))

Classes#

MarkovSwitchingDFM

Markov-switching dynamic factor model, Kim-Nelson.

MarkovSwitchingDFMResult

A fitted switching factor model: the factor, and the regime chronology.

MarkovSwitchingSVAR

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

MarkovSwitchingSVARResult

An identified Markov-switching system, one structural result per regime.

MarkovSwitchingVAR

Markov-switching vector autoregression with M latent regimes.

MarkovSwitchingVARResult

A fitted Markov-switching vector autoregression.

RegimeSystemResult