3. 隐马尔可夫模型入门
在金融市场里,我们每天能直接看到的只有价格、成交量、涨跌幅、波动率这些观测数据;但真正决定行情走向的,往往是背后那个看不见的市场状态——是趋势、是震荡、还是恐慌。隐马尔可夫模型(Hidden Markov Model,HMM)正是用来处理这类“状态不可见、只能通过观测反推”的问题。本节我们把 HMM 的四个核心概念讲透:隐状态、观测序列、马尔可夫链、转移概率与发射概率。
一、核心原理:两层结构,一条链
HMM 的直觉可以用一句话概括:市场在几个“隐藏状态”之间来回切换,每个状态会以不同的概率“发射”出我们看到的观测值。它由两层组成:
- 隐状态层(Hidden State):真实但不可直接观测,例如“牛市趋势”“震荡整理”“熊市下跌”。记作
S = {S₁, S₂, …, S_N}。 - 观测层(Observation):我们实际能拿到的数据,例如日收益率、成交量、波动率。记作
O = {o₁, o₂, …, o_T}。
两层之间靠两个概率矩阵连接:转移概率决定“状态怎么变”,发射概率决定“这个状态长什么样”。再加上一个初始状态概率,HMM 的参数就齐了,通常记作 λ = (A, B, π)。
二、马尔可夫链:状态切换的“记忆只有一步”
马尔可夫链描述的是状态序列的演化规律,它的关键假设是无后效性:下一时刻的状态只取决于当前状态,与更早的历史无关。用公式表达就是:
P(S_{t+1} | S_t, S_{t-1}, …, S_1) = P(S_{t+1} | S_t)
这个假设在市场上当然是一种简化,但它让模型变得可计算。转移概率矩阵 A 的每一行表示“从当前状态出发,下一时刻去往各状态的概率”,每行之和为 1。例如三个市场状态的转移矩阵:
| 当前状态 \ 下一状态 | 趋势上涨 | 震荡整理 | 趋势下跌 |
|---|---|---|---|
| 趋势上涨 | 0.90 | 0.08 | 0.02 |
| 震荡整理 | 0.15 | 0.75 | 0.10 |
| 趋势下跌 | 0.03 | 0.12 | 0.85 |
读表要点:对角线数值大,说明状态有黏性,行情一旦进入某状态往往会持续一段时间;非对角线数值小,说明切换是“偶发事件”。这正是 HMM 能刻画“趋势延续”和“状态突变”的原因。
三、发射概率:每个状态“长什么样”
发射概率矩阵 B 描述的是:在某个隐状态下,观测到某个具体数值的概率有多大。在量化实战中,观测通常是连续值(如日收益率),因此常用高斯发射,即每个状态对应一个均值 μ 和标准差 σ。
- 趋势上涨状态:μ 为正、σ 较小 → 多数日子温和上涨。
- 震荡整理状态:μ 接近 0、σ 中等 → 涨跌互现、方向不明。
- 趋势下跌状态:μ 为负、σ 较大 → 下跌为主且波动剧烈。
把转移概率和发射概率放在一起看,就能理解 HMM 的“生成逻辑”:先按初始概率选一个状态,再按发射概率生成今天的观测;然后按转移概率跳到下一个状态,再发射下一个观测……如此循环,就生成了一整条观测序列。
四、案例场景:用 HMM 识别市场状态
假设我们只用一个观测:沪深300的日收益率。设定 3 个隐状态,用历史数据训练 HMM 后,模型会输出每一天最可能属于哪个状态。一个典型的实战流程如下:
- 准备观测序列:取对数收益率,做标准化,剔除停牌与异常值。
- 设定状态数 N:一般 2~4 个,太多会过拟合,太少区分度不足。
- 训练参数:用 Baum-Welch(EM 算法)估计 A、B、π。
- 状态解码:用 Viterbi 算法求出最可能的隐状态序列。
- 映射与验证:把状态标注为“上涨/震荡/下跌”,检查其收益均值、波动是否符合直觉。
# 伪代码示意
model = GaussianHMM(n_components=3, covariance_type="diag", n_iter=200)
model.fit(returns) # 训练 A, B, π
states = model.predict(returns) # Viterbi 解码隐状态
print(model.transmat_) # 查看转移矩阵
print(model.means_) # 查看各状态均值
训练完成后,如果发现某个状态的日均收益显著为正、波动低,且自身留存概率高,就可以把它理解为“趋势上涨状态”,并据此设计仓位规则。
五、常见误区与复盘
- 误区二:状态数越多越好。状态数增加会提升拟合度,但也会让状态含义模糊、切换频繁,反而失去策略价值。
- 误区三:忽略无后效性假设。市场存在长记忆和 regime 依赖,HMM 只是近似,需配合滚动训练与样本外验证。
- 误区四:只看解码结果,不看概率。应关注状态的后验概率,当概率接近 0.5 时说明状态不明确,不宜重仓。