3. 状态分类与遍历性:常返态、瞬态、周期性与非周期性、平稳分布
好,咱们接着聊。上一节我们把马尔可夫链的数学框架搭起来了,知道了转移矩阵怎么用。但光有这些还不够——你想想看,一个状态到底能不能反复回来?会不会一去不返?这些性质直接决定了你的交易策略能不能「长期稳定赚钱」。说白了,这就是状态分类要解决的问题。
我个人习惯把状态分类比作「城市里的不同街区」。有些街区你去了还能回来,有些则是单行道。咱们今天就把这些概念一个个拆开讲清楚。
3.1 常返态与瞬态
先问个问题:一个状态,你从它出发,最终还能回到它自己吗?
能回来的,叫常返态。回不来的,叫瞬态。
数学上怎么定义?设 \( f_{ii} \) 为从状态 \( i \) 出发,最终返回状态 \( i \) 的概率。如果 \( f_{ii} = 1 \),那就是常返态;如果 \( f_{ii} < 1 \),那就是瞬态。
我在项目中遇到过这样一个场景:用马尔可夫链建模某只股票的涨跌状态。结果发现「大跌」状态居然是瞬态——也就是说,一旦进入大跌,几乎不可能再回到大跌状态(因为跌到底就反弹了)。嗯,这其实是个有用的信号。
- 常返态:\( f_{ii} = 1 \),一定能回来
- 瞬态:\( f_{ii} < 1 \),有可能一去不返
还有一个更实用的判断方法:计算从状态 \( i \) 出发,访问状态 \( i \) 的期望次数。如果这个期望次数是无穷大,那就是常返态;如果是有限值,那就是瞬态。
你可能会问:「这跟趋势跟踪有什么关系?」关系大了。如果你的策略依赖某个「震荡状态」反复出现,但这个状态其实是瞬态,那你的策略迟早会失效。我曾经就踩过这个坑——用历史数据回测时某个状态出现频率很高,但实盘时它再也不出现了。后来一分析,原来是个瞬态。
3.2 周期性
好,常返态和瞬态讲完了。接下来看周期性。
什么叫周期性?简单说:从一个状态出发,经过多少步才能回来?如果只能经过某个步长的整数倍回来,那就是有周期。
举个例子:假设你只能在第2步、第4步、第6步...回到状态 \( i \),那周期就是2。如果任何步数都有可能回来,那就是非周期性的。
数学定义:设 \( d \) 为所有可能的返回步数的最大公约数。如果 \( d > 1 \),则状态是周期性的,周期为 \( d \);如果 \( d = 1 \),则是非周期性的。
我记得有一次帮朋友分析一个高频策略,发现他的「买入信号」状态周期为3。也就是说,每3个tick就会出现一次买入信号。这显然不合理——后来发现是他的数据采样频率和策略逻辑产生了共振。嗯,这种坑要小心。
3.3 遍历性与平稳分布
接下来是重头戏:遍历性。
一个马尔可夫链是遍历的,当且仅当它满足两个条件:
- 不可约:所有状态互相可达
- 非周期性:所有状态都是非周期的
遍历性意味着什么?意味着无论你从哪个状态出发,经过足够长的时间,系统都会「忘记」初始状态,进入一个稳定的分布——这就是平稳分布。
平稳分布 \( \pi \) 满足:
π = πP
∑π_i = 1
说白了,平稳分布就是转移矩阵的不动点。你一直转移下去,状态的概率分布就不再变化了。
我建议你在实际项目中这样理解:平稳分布告诉你,长期来看,每个状态出现的概率是多少。比如在趋势跟踪中,如果平稳分布显示「上涨状态」占60%,「下跌状态」占40%,那你的策略就应该偏向做多。
咱们用一张图来总结一下整个知识体系:
3.4 实际应用:如何判断你的链是否遍历
好,理论讲完了。咱们来点实际的。怎么判断一个马尔可夫链是否遍历?
我一般按这个步骤来:
- 检查不可约性:画个状态转移图,看是不是所有状态都能互相到达。如果有孤立的状态,那就不是不可约的。
- 检查非周期性:看每个状态的周期。如果所有状态周期都是1,那就是非周期的。
- 计算平稳分布:解方程 \( \pi = \pi P \),看解是否唯一且所有分量都为正。
给你看个代码示例,怎么用Python判断:
import numpy as np
def is_irreducible(P):
"""检查转移矩阵P是否不可约"""
n = P.shape[0]
# 计算可达矩阵 (P^k 的非零元素)
reachable = np.eye(n, dtype=bool)
P_power = np.eye(n)
for _ in range(n):
P_power = P_power @ P
reachable = reachable | (P_power > 1e-10)
# 检查是否所有状态互相可达
return np.all(reachable)
def is_aperiodic(P):
"""检查是否非周期性"""
n = P.shape[0]
for i in range(n):
# 计算返回步数的最大公约数
periods = []
P_power = np.eye(n)
for k in range(1, 2*n+1):
P_power = P_power @ P
if P_power[i, i] > 1e-10:
periods.append(k)
if len(periods) == 0:
return False
# 计算最大公约数
gcd = periods[0]
for p in periods[1:]:
gcd = np.gcd(gcd, p)
if gcd > 1:
return False
return True
def stationary_distribution(P):
"""计算平稳分布"""
n = P.shape[0]
# 解 πP = π, 即 π(P - I) = 0
A = P.T - np.eye(n)
# 添加归一化条件
A = np.vstack([A, np.ones(n)])
b = np.zeros(n+1)
b[-1] = 1
# 最小二乘解
pi, _, _, _ = np.linalg.lstsq(A, b, rcond=None)
return pi
# 示例:一个简单的3状态链
P = np.array([
[0.7, 0.2, 0.1],
[0.1, 0.8, 0.1],
[0.2, 0.3, 0.5]
])
print("不可约:", is_irreducible(P))
print("非周期:", is_aperiodic(P))
print("平稳分布:", stationary_distribution(P))
最后总结一下:
- 常返态:能回来的状态,是策略长期有效的基础
- 瞬态:一去不返的状态,要小心别被历史数据迷惑
- 周期性:步长规律性,非周期才是常态
- 遍历性:不可约+非周期,保证平稳分布存在且唯一
- 平稳分布:长期概率分布,是策略参数优化的依据
嗯,这一节内容不少。你消化一下,下一节咱们会把这些概念用到实际的趋势跟踪策略中去。