Monte Carlo模拟基础:随机数生成、概率分布、大数定律、中心极限定理

Monte Carlo模拟,说白了就是用随机数去解决那些确定性方法搞不定的问题。我刚开始接触量化金融时,觉得这玩意儿挺玄乎——扔骰子也能做投资组合优化?后来真上手了才发现,这恰恰是处理市场不确定性的利器。

这一章我们先把地基打牢。随机数怎么生成?概率分布怎么选?大数定律和中心极限定理又是什么鬼?搞懂这些,后面的模拟才不会跑偏。

1. 随机数生成:伪随机也够用

真正的随机数很难搞,比如用物理噪声源。但在量化金融里,我们用的是伪随机数——算法生成的、看起来随机的序列。我个人习惯用NumPy的random模块,又快又稳。

核心要点:伪随机数只要通过统计检验,就能用于Monte Carlo模拟。别纠结它是不是“真随机”。

import numpy as np

# 生成均匀分布随机数
np.random.seed(42)  # 固定种子,保证可复现
uniform_samples = np.random.uniform(0, 1, 1000)

# 生成标准正态分布随机数
normal_samples = np.random.normal(0, 1, 1000)

# 生成对数正态分布(常用于股价模拟)
lognormal_samples = np.random.lognormal(0, 0.2, 1000)

我的习惯:每次模拟前都固定种子。不然调试时结果每次都不一样,你会疯掉的。我曾经因为这个bug排查了整整一个下午。

2. 概率分布:选对模型很重要

Monte Carlo模拟的核心,就是假设资产收益服从某种概率分布,然后反复抽样。你想想看,如果分布选错了,再多的模拟也是白搭。

量化金融里最常见的几种分布:

分布类型 适用场景 参数说明
正态分布 短期收益率、风险因子 均值μ,标准差σ
对数正态分布 股票价格、资产价格 μ为漂移率,σ为波动率
均匀分布 参数敏感性分析 最小值a,最大值b
t分布 厚尾风险建模 自由度ν(越小尾部越厚)

避坑指南:我曾经用正态分布模拟美股崩盘,结果完全没捕捉到极端损失。后来改用t分布(自由度3-5),效果才靠谱。记住:金融数据通常有厚尾特征,正态分布只是理想情况。

3. 大数定律:模拟次数越多越准

大数定律说:样本均值会随着样本量增加而趋近于总体均值。说白了,你扔硬币的次数越多,正面比例就越接近50%。

在Monte Carlo模拟里,这意味着:

  • 模拟100次,结果可能偏差很大
  • 模拟10,000次,结果就比较稳定了
  • 模拟1,000,000次,嗯...基本就是精确值了
import numpy as np
import matplotlib.pyplot as plt

# 模拟抛硬币:正面=1,反面=0
np.random.seed(42)
n_trials = 10000
results = np.random.binomial(1, 0.5, n_trials)
cumulative_mean = np.cumsum(results) / np.arange(1, n_trials + 1)

# 看看收敛过程
print(f"前100次均值: {cumulative_mean[99]:.4f}")
print(f"前1000次均值: {cumulative_mean[999]:.4f}")
print(f"全部10000次均值: {cumulative_mean[-1]:.4f}")

经验之谈:我一般至少跑10万次模拟。如果结果波动还大,就加到50万次。别心疼计算资源,这点成本比模型出错低多了。

4. 中心极限定理:为什么正态分布无处不在

中心极限定理说:大量独立同分布随机变量的均值,近似服从正态分布。不管原始分布长什么样,只要样本量够大,均值就变成正态了。

为什么会这样?嗯,你可以理解为“平均的力量”——极端值互相抵消,最终呈现出钟形曲线。

这对Monte Carlo模拟意味着:

  • 我们可以用正态分布来近似模拟结果的分布
  • 计算置信区间变得简单:均值 ± 1.96 × 标准差
  • 但要注意:如果原始分布方差无穷大(比如柯西分布),中心极限定理就不适用了

我的建议:每次模拟完,先画个直方图看看结果分布。如果形状明显不是正态,就要小心了——可能是样本量不够,也可能是模型本身有问题。

5. 知识体系总览

下面这张图把本章的核心逻辑串起来了。你一看就明白:随机数生成是原料,概率分布是配方,大数定律和中心极限定理是质量保证。

Monte Carlo模拟基础 - 知识体系 随机数生成 概率分布选择 模拟参数设定 Monte Carlo 模拟过程 大数定律(收敛性保证) 中心极限定理(分布形态) 模拟结果与置信区间

6. 实战小练习:验证大数定律

光说不练假把式。我们来写个简单代码,看看大数定律是怎么起作用的。

import numpy as np

# 模拟掷骰子:期望值是3.5
np.random.seed(42)

def simulate_dice(n_rolls):
    rolls = np.random.randint(1, 7, n_rolls)
    return np.mean(rolls)

# 不同样本量的结果
for n in [10, 100, 1000, 10000, 100000]:
    mean = simulate_dice(n)
    print(f"掷{n:6d}次,均值={mean:.4f},误差={abs(mean-3.5):.4f}")

输出结果会让你直观感受到:样本量越大,均值越接近3.5。这就是大数定律在说话。

总结一下:Monte Carlo模拟不是魔法,它靠的是大数定律保证收敛,靠中心极限定理帮我们理解误差。随机数生成和概率分布选择,则是模拟的“食材”和“菜谱”。食材不对,菜谱再好也白搭。

最后提醒:别一上来就追求百万次模拟。先跑个几千次看看趋势,调好参数再上量。我见过太多人一跑就是几百万次,结果发现分布选错了——全白干。


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