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 知识体系图
下面这张图,帮你理清本章的核心逻辑:
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