3. 马尔可夫性质:马尔可夫链的定义、转移概率矩阵、稳态分布

聊到随机过程,有个概念你绕不开——马尔可夫性质

我第一次接触这东西,是在做高频交易策略回测的时候。当时我发现,很多传统的统计模型都假设「历史会重演」,但实际行情根本不是那么回事。后来我导师跟我说:「你试试马尔可夫链,它只关心当前状态,不纠结过去。」 嗯,这句话让我记到现在。

3.1 马尔可夫性质到底是什么?

说白了,马尔可夫性质就一句话:

「给定现在,未来与过去无关。」

用数学语言表达就是:

P(X_{n+1} = x | X_n = x_n, X_{n-1} = x_{n-1}, ..., X_0 = x_0) 
= P(X_{n+1} = x | X_n = x_n)

什么意思?你想想看——

假设你在盯盘,当前价格是100元。马尔可夫性质认为:下一步价格怎么走,只取决于「当前是100元」这个事实,跟它之前是从80涨上来的、还是从120跌下来的,没有关系。

我在项目中遇到过不少质疑:「这合理吗?历史走势明明有趋势啊!」 嗯,你说得对。但马尔可夫性质不是真理,它是一种建模假设。就像物理里的「无摩擦」假设一样——简化问题,才能算出东西来。

我的经验: 在量化交易里,高频数据往往更接近马尔可夫性质。因为市场微观结构变化极快,过去几秒的信息基本已经反映在当前价格里了。低频策略就别硬套了,容易翻车。

3.2 马尔可夫链的定义

有了马尔可夫性质,我们就可以定义马尔可夫链了。

一个马尔可夫链由三部分组成:

  • 状态空间 S:所有可能状态的集合。比如 {上涨, 下跌, 横盘}
  • 转移概率:从一个状态跳到另一个状态的概率
  • 初始分布:最开始处于各个状态的概率

举个例子。我做过一个简单的「牛熊判断模型」,状态只有两个:

  • 状态 0:熊市
  • 状态 1:牛市

假设历史数据显示:

  • 如果今天是熊市,明天继续熊市的概率是 0.7,变成牛市的概率是 0.3
  • 如果今天是牛市,明天继续牛市的概率是 0.8,变成熊市的概率是 0.2

这就是一个最简单的马尔可夫链。

3.3 转移概率矩阵

上面那些概率,写成矩阵就是转移概率矩阵

对于刚才的例子:

       熊市    牛市
熊市    0.7    0.3
牛市    0.2    0.8

用数学符号表示:

P = [[0.7, 0.3],
     [0.2, 0.8]]

这里有个关键性质——每一行加起来等于1。为什么?因为从某个状态出发,下一步总要落到某个状态上,概率总和必须是1。

注意: 我曾经在写代码时犯过一个低级错误——把列求和当成了1,结果算出来的稳态分布全是错的。排查了整整一下午才发现。记住:行和为1,不是列和为1

有了转移矩阵,我们就可以做预测了。比如:

  • 今天熊市,明天牛市的概率?→ 查矩阵第一行第二列:0.3
  • 今天牛市,后天熊市的概率?→ 需要两步转移,把矩阵平方一下

两步转移概率的计算:

P^2 = P × P = [[0.7×0.7+0.3×0.2, 0.7×0.3+0.3×0.8],
               [0.2×0.7+0.8×0.2, 0.2×0.3+0.8×0.8]]
     = [[0.55, 0.45],
        [0.30, 0.70]]

你看,牛市两天后还是牛市的概率是0.70,比一天后的0.8稍微低了一点。这就是马尔可夫链的「记忆消退」效应——时间越长,初始状态的影响越小。

3.4 稳态分布

说到「记忆消退」,就引出了稳态分布

你想想看——如果我们让马尔可夫链一直跑下去,最终各个状态的概率会趋于稳定,不再随时间变化。这个稳定的概率分布,就叫稳态分布。

用数学表达:

π = π × P

其中 π 是一个行向量,表示稳态时各个状态的概率。这个方程的意思是:经过一次转移后,分布不变

对于我们的牛熊模型,解这个方程:

设 π = [π₀, π₁]
π₀ = 0.7π₀ + 0.2π₁
π₁ = 0.3π₀ + 0.8π₁
π₀ + π₁ = 1

解得:

π₀ = 0.4, π₁ = 0.6

也就是说,长期来看,这个市场有40%的时间在熊市,60%的时间在牛市。

实际应用: 我在做资产配置时,会用稳态分布来估算「长期仓位比例」。比如上面这个结果,如果我相信模型,那么长期持有60%的股票仓位是比较合理的。

3.5 知识体系图

下面这张图,帮你理清本章的核心逻辑:

马尔可夫链知识体系 马尔可夫性质 马尔可夫链定义 状态空间 S 转移概率矩阵 P 初始分布 稳态分布 π = π × P

3.6 代码实战:计算稳态分布

光说不练假把式。下面我用 Python 演示一下,怎么算稳态分布。

import numpy as np

# 定义转移概率矩阵
P = np.array([[0.7, 0.3],
              [0.2, 0.8]])

# 方法1:迭代法(模拟链跑很多步)
def steady_state_iteration(P, steps=10000):
    n = P.shape[0]
    pi = np.ones(n) / n  # 初始均匀分布
    for _ in range(steps):
        pi = pi @ P
    return pi

pi_iter = steady_state_iteration(P)
print(f"迭代法结果: {pi_iter}")
# 输出: [0.4, 0.6]

# 方法2:解方程法
def steady_state_eigen(P):
    eigenvalues, eigenvectors = np.linalg.eig(P.T)
    # 找到特征值1对应的特征向量
    idx = np.argmin(np.abs(eigenvalues - 1))
    pi = eigenvectors[:, idx].real
    pi = pi / pi.sum()  # 归一化
    return pi

pi_eigen = steady_state_eigen(P)
print(f"特征值法结果: {pi_eigen}")
# 输出: [0.4, 0.6]

我的建议: 实际项目中我更喜欢用迭代法。虽然看起来笨,但稳定、不容易出错。特征值法在矩阵维度高的时候容易遇到复数特征值,处理起来麻烦。

3.7 避坑指南

最后,分享几个我踩过的坑:

  • 不是所有链都有稳态分布。比如周期性的链(状态0→1→0→1...)会一直震荡,不会收敛。检查一下你的转移矩阵,确保它是「非周期」的。
  • 稳态分布不依赖初始状态。不管你从熊市开始还是牛市开始,最终都会收敛到[0.4, 0.6]。这是马尔可夫链的「遗忘」特性。
  • 小心「吸收态」。如果某个状态一旦进入就再也出不来(比如退市),那稳态分布就会全部集中在这个状态上。这在建模时要特别注意。

嗯,马尔可夫链的内容就讲到这里。记住三个核心:性质、矩阵、稳态。下次你看到行情数据,不妨试试用马尔可夫链建模——说不定会有意外收获。


公众号:蓝海资料掘金营,微信deep3321