Skip to content

做什么(One-liner)

2-state Markov-switching autoregression (MS-AR(1), switching variance) 对返回序列做体制识别。statsmodels 主路径 + rolling-vol fallback。返回当前 regime、probs、每 regime 均值/σ、label_map (low_volatility / high_volatility)。

怎么用

Canvas 拖 markov_regime_v1,上游 price_factor 的 close → 前端 derive returns(或 params.returns 直接填)。默认 n_regimes=2。典型用法:

price_factor → markov_regime_v1 → institution_composite / casa_strategy (regime overlay)

核心公式

python
# Primary path (statsmodels MarkovAutoregression):
mod = MarkovAutoregression(returns, k_regimes=2, order=1, switching_variance=True)
res = mod.fit(maxiter=200)

# 2026-04-20 shim (pandas or ndarray):
smoothed = res.smoothed_marginal_probabilities
last = smoothed.iloc[-1] if hasattr(smoothed, 'iloc') else smoothed[-1]
current_regime = argmax(last)

# Named param lookup supports both DataFrame-style and ndarray + mod.param_names
means  = [_param_by_name(f'const[{i}]')  for i in range(2)]
sigmas = [sqrt(_param_by_name(f'sigma2[{i}]')) for i in range(2)]

# Label map (n_regimes=2 only):
low_idx = argmin(sigmas)
label_map = {low_idx: 'low_volatility', 1-low_idx: 'high_volatility'}

# Fallback (on any statsmodels exception):
vol_ratio = std(second_half) / std(first_half)
label = 'high_volatility' if vol_ratio > 1.3 else 'low_volatility'

假设与适用场景

假设:≥30 obs + daily 等频 + 2-regime + order=1 + switching_variance=True + single EM fit。

适用:Canvas 单标的 returns regime 识别、crisis/normal 阶段、reflexivity/contagion 前置。

不适用:intraday、3+ regimes(label_map 不工作)、multi-start Bayesian、需要 transition matrix 的场景。

输入 / 输出契约

Primary: {returns: list, n_regimes?=2}{n_observations, n_regimes, current_regime, current_regime_label, regime_probabilities, regime_means, regime_sigmas, regime_labels, _method='MarkovAutoregression (statsmodels)'}

Fallback: {n_observations, n_regimes=2, current_regime, current_regime_label, regime_probabilities, vol_ratio, _method='rolling_volatility_fallback', _fallback_reason}

Error: {error: 'need_more_data', message}

已知局限

  1. 主路径曾经静默失效 (2026-04-20 修复前):statsmodels 新旧版本 DataFrame vs ndarray 差异导致 AttributeError → ALL fallback。shim 已加。
  2. switching_variance=True hardcoded(mean-switching-only 模型无法选)
  3. order=1 hardcoded
  4. Single EM fit(no multi-start / Bayesian)
  5. 纯噪声数据 → 退化 regime(σ~1e-5 + σ~real)
  6. No trend/drift preprocessing
  7. Fallback threshold vol_ratio > 1.3 hardcoded
  8. n_regimes=3+ 接口接受但 label_map 不映射(client 需处理 'regime_X' 字符串)

参考文献

Hamilton (1989) Econometrica MS-AR + Kim-Nelson (1999) State-Space with Regime Switching + Ang-Timmermann (2012) Regime Changes in Financial Markets。详见 frontmatter。

Golden Test

tests/golden/fixtures/tier3/markov_regime/statsmodels reference。1e-10 tolerance。9 tests:

  • too_short_returns — 10 obs → error='need_more_data'
  • low_vol_regime — stable σ=0.005 → primary path + degenerate regime OK
  • regime_switching — half low-vol + half high-vol → current=1, probs [0.04, 0.96]
  • trending_up — positive drift → primary path, near-uniform probs
  • determinism — 5 reruns 一致
  • result_structure_primary_path — 9 fixed keys
  • probabilities_sum_to_one — 有效概率分布
  • current_regime_in_range — ∈ [0, n_regimes)
  • label_map_low_high — 2-regime + sigmas →

Changelog

  • 1.0.1 (2026-04-20) — statsmodels primary-path 修复 + golden v1.0.1
  • 1.0.0 (2026-04-19) — Canvas shipped (Phase B advanced quant)

Verifiable intelligence for the decisions that demand scrutiny.