用Python和NumPy手把手教你模拟股市预测:从状态转移矩阵到稳态分布
用Python和NumPy手把手教你模拟股市预测:从状态转移矩阵到稳态分布
金融市场的波动总是让人捉摸不透,但数学却能为我们提供一种独特的视角。想象一下,如果能够用代码模拟股市的牛熊转换,预测长期趋势,那该有多酷?今天我们就用Python和NumPy,从零开始构建一个马尔可夫链模型,带你体验量化金融的奇妙世界。
1. 环境准备与基础概念
在开始编写代码前,我们需要明确几个关键概念。马尔可夫链的核心思想是"未来只取决于现在",这种特性在金融时间序列分析中尤为重要。我们将股市简化为三种状态:
- 牛市(Bull Market):股价持续上涨
- 熊市(Bear Market):股价持续下跌
- 横盘(Stagnant Market):股价波动较小
安装必要的Python库非常简单:
pip install numpy matplotlib马尔可夫链的数学本质可以用转移概率矩阵表示。假设当前是牛市,那么下个周期:
- 保持牛市的概率:0.9
- 转为熊市的概率:0.075
- 转为横盘的概率:0.025
这种关系可以用矩阵表示为:
| 当前\下一状态 | 牛市 | 熊市 | 横盘 |
|---|---|---|---|
| 牛市 | 0.9 | 0.075 | 0.025 |
| 熊市 | 0.15 | 0.8 | 0.05 |
| 横盘 | 0.25 | 0.25 | 0.5 |
注意:矩阵每行概率之和必须严格等于1,这是马尔可夫链的基本要求。
2. 构建状态转移模型
让我们用NumPy来实现这个转移矩阵。首先导入必要的库:
import numpy as np import matplotlib.pyplot as plt # 定义状态转移矩阵 transition_matrix = np.array([ [0.9, 0.075, 0.025], # 牛市转移概率 [0.15, 0.8, 0.05], # 熊市转移概率 [0.25, 0.25, 0.5] # 横盘转移概率 ]) # 验证每行概率和为1 assert np.allclose(transition_matrix.sum(axis=1), 1.0), "概率矩阵行和不为1"为了直观理解状态转移,我们可以模拟几个周期:
def simulate_markov_chain(initial_state, matrix, steps): states = ['牛市', '熊市', '横盘'] current_state = initial_state print(f"初始状态: {states[current_state]}") for i in range(steps): current_state = np.random.choice( len(states), p=matrix[current_state] ) print(f"第{i+1}步后状态: {states[current_state]}")运行模拟:
simulate_markov_chain(0, transition_matrix, 10)典型输出可能如下:
初始状态: 牛市 第1步后状态: 牛市 第2步后状态: 牛市 第3步后状态: 熊市 第4步后状态: 熊市 第5步后状态: 牛市 ...3. 计算稳态分布
马尔可夫链最迷人的特性之一是最终会收敛到一个稳态分布,无论初始状态如何。数学上,稳态分布π满足:
π = πP
我们可以通过矩阵幂次法来求解:
def find_steady_state(matrix, tolerance=1e-8): n = matrix.shape[0] pi = np.ones(n) / n # 初始猜测 while True: new_pi = pi @ matrix if np.linalg.norm(new_pi - pi) < tolerance: break pi = new_pi return pi steady_state = find_steady_state(transition_matrix) print(f"稳态分布: {steady_state}")对于我们的股市模型,输出应该是:
稳态分布: [0.625 0.3125 0.0625]这意味着长期来看:
- 62.5%的时间处于牛市
- 31.25%的时间处于熊市
- 6.25%的时间处于横盘
4. 可视化收敛过程
为了更直观地理解收敛过程,我们可以绘制状态概率随时间变化的曲线:
def plot_convergence(initial_dist, matrix, steps=20): history = [initial_dist] current = initial_dist for _ in range(steps): current = current @ matrix history.append(current) history = np.array(history) plt.figure(figsize=(10, 6)) plt.plot(history[:, 0], label='牛市概率') plt.plot(history[:, 1], label='熊市概率') plt.plot(history[:, 2], label='横盘概率') plt.xlabel('时间步') plt.ylabel('概率') plt.title('状态概率收敛过程') plt.legend() plt.grid(True) plt.show() # 假设初始分布为[0.3, 0.4, 0.3] plot_convergence(np.array([0.3, 0.4, 0.3]), transition_matrix)图表会清晰地展示不同状态概率如何随时间收敛到稳态值。这种可视化对于理解马尔可夫链的长期行为非常有帮助。
5. 实际应用与扩展
理解了基本原理后,我们可以将这个模型应用到更实际的场景中。例如,基于历史数据估计转移概率:
def estimate_transition_matrix(data): """ 根据历史状态序列估计转移矩阵 data: 状态序列,如[0,0,1,2,0,...] """ n_states = len(set(data)) matrix = np.zeros((n_states, n_states)) for (i, j) in zip(data[:-1], data[1:]): matrix[i][j] += 1 # 归一化 row_sums = matrix.sum(axis=1, keepdims=True) return matrix / row_sums # 示例历史数据:0=牛市,1=熊市,2=横盘 historical_data = [0,0,1,1,0,2,0,1,1,1,0,0,2,2,0] estimated_matrix = estimate_transition_matrix(historical_data) print("估计的转移矩阵:\n", estimated_matrix)对于更复杂的金融应用,我们可以考虑:
- 加入更多市场状态(如暴涨、暴跌)
- 考虑非平稳性(转移概率随时间变化)
- 结合其他金融指标构建多维马尔可夫模型
提示:在实际交易策略中使用此类模型时,务必进行充分的回溯测试和风险评估。
马尔可夫链为金融建模提供了简洁而强大的框架。通过这个Python实现,我们不仅理解了理论概念,还获得了可以直接应用于实际数据分析的工具。
