社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

量化投资必修课:用 Python 手搓蒙特卡洛模拟,10000 个"平行宇宙"看清股价风险

数据科学实战 • 5 天前 • 38 次点击  


 

 用 Python 揭秘均值回归策略:你的收益从何而来?



 

 

 

 

 


 

2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 500 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!

引言

如果只能对一年后的股价给出一个预测数字,那这个数字大概率是错的。但如果能生成 10000 种可能的未来,再从中统计出"亏损超过 20% 的概率是多少",这就是完全不同层次的答案了。

这正是蒙特卡洛模拟(Monte Carlo Simulation)在量化金融中的核心价值:期权定价、风险度量(VaR)、组合压力测试,背后都离不开它。本文将拆解蒙特卡洛模拟的运行机制,并用不到 40 行的 NumPy 代码,带你完整跑通一次股价模拟。

一、蒙特卡洛模拟的"四步骨架"

抛开金融背景,所有蒙特卡洛模拟都遵循同一套流程:

  1. 1. 定义不确定变量及其统计行为:确定什么是随机的(股票收益率、利率、违约事件),并用均值、波动率、相关性等统计特征来描述它。
  2. 2. 生成随机样本:按照上一步定义的统计特性,为每个不确定变量抽取随机值。
  3. 3. 向前推演场景:把随机值代入金融模型(期权收益公式、组合收益计算等),记录结果。
  4. 4. 重复成千上万次:每次重复都是一个可能的"未来版本",汇总起来就得到了结果的分布,而不是单一猜测。

蒙特卡洛方法看似复杂,其实真正的门道几乎都在第 1 步和第 3 步——其余的只是重复。

二、实战案例:模拟一只股票一年后的价格

建模:几何布朗运动(GBM)

股价通常用几何布朗运动来建模,它假设收益由两部分驱动:稳定的期望漂移(平均收益)和随机的波动(围绕均值的噪声)。每一步的价格更新公式为:

其中:

  • • S(t):当前时刻的股价
  • • μ:期望年化收益率(漂移项)
  • • σ:年化波动率
  • • Δt:时间步长(按日模拟时通常取 1/252,即一个交易日)
  • • Z:从标准正态分布中抽取的随机数,每一步都要抽一个新的

易错点提醒:公式中的 (μ - 0.5σ²) 是一个小而关键的修正项。它把平均漂移略微下调,因为"复利叠加随机收益"并不等于"复利叠加平滑的平均收益"。漏掉这个修正,模拟结果会系统性高估股票的长期增长。

Python 完整实现

只用 NumPy,每一步都清晰可见:

import numpy as np

# --- 输入参数 ---

S0 = 100        # 当前股价
mu = 0.08       # 期望年化收益率(8%)
sigma = 0.20    # 年化波动率(20%)
T = 1.0         # 时间跨度(年)
n_steps = 252   # 一年的交易日数
n_paths = 10000 # 模拟路径数量

dt = T / n_steps   # 每步的时间长度

# --- 开始模拟 ---

np.random.seed(42)  # 固定随机种子,保证结果可复现
Z = np.random.standard_normal((n_paths, n_steps))  # 随机冲击矩阵

# 计算每日的对数收益率,再累加得到完整价格路径

daily_returns = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * Z
log_paths = np.cumsum(daily_returns, axis=1)
price_paths = S0 * np.exp(log_paths)

# 一年后的最终模拟价格

final_prices = price_paths[:, -1]

# --- 分析结果分布 ---

expected_price = final_prices.mean()                    # 期望价格
p5, p95 = np.percentile(final_prices, [5, 95])          # 5% 和 95% 分位数
prob_loss_20pct = np.mean(final_prices < S0 * 0.8)      # 亏损超 20% 的概率

print
(f"一年后的期望价格:{expected_price:.2f}")
print
(f"5%–95% 分位区间:{p5:.2f} –  {p95:.2f}")
print
(f"亏损超过 20% 的概率:{prob_loss_20pct:.2%}")

代码中值得注意的三个细节

  • • Z 是一个完整的随机数矩阵(每条路径、每一天各一个),通过向量化一次性生成,而不是写循环。这就是 10000 条路径能在毫秒级跑完的原因。
  • • np.cumsum 负责"路径推演":把每日对数收益累加成完整的价格轨迹。相比直接对价格连乘,对数收益累加在数值上更稳定。
  • • 末尾的分位数和概率计算才是方法的全部意义:单点预测在这里变成了真正的风险陈述。其中 p5(第 5 百分位的价格)就是实践中风险价值(VaR,Value at Risk)的简化版本——它回答的是"最差的 5% 情形下,我的资产值多少"。

三、真正考验功力的环节:相关性

真实世界里,金融变量很少相互独立:组合内的股票收益会一定程度同涨同跌,利率和违约率在经济周期中也倾向于同步起落。如果对每个变量独立模拟、忽略这些关系,模拟会严重低估风险——因为它错过了"坏结果往往扎堆出现"这一事实。

标准解法是 Cholesky 分解:一种矩阵方法,能把一组相互独立的随机数,变换成符合指定相关性结构的随机数。通俗地说,它让你的模拟"知道":当股票 A 崩盘时,股票 B 也更可能跟着崩,而不是把每只股票的命运当成孤立的抛硬币。

双资产相关性示例

# 两个资产之间的相关系数矩阵(相关系数为 0.6)
corr_matrix = np.array([[1.0, 0.6],
                        [0.6, 1.0]])

L = np.linalg.cholesky(corr_matrix)   # Cholesky 分解得到下三角矩阵

# 为两个资产生成相互独立的随机数(每条路径一组)

Z_independent = np.random.standard_normal((n_paths, 2))

# 变换为具有相关性的随机数

Z_correlated = Z_independent @ L.T

变换后的 Z_correlated 有两列随机冲击:每一列单独看仍是标准正态分布,但两列之间的相关系数为 0.6,远比"当作两枚不相干的硬币"更接近现实。把前面模拟中的独立随机数替换成它(按资产分别应用),就得到了一个尊重资产联动关系的双资产组合模拟。

值得强调的是:准确估计相关系数,并随市场关系变化及时更新,往往比你跑多少条路径更能决定模拟的实际价值。

四、计算成本与收敛速度

单条路径很便宜,贵的是"足够多的路径"和"每步模拟的复杂度"。给一个简单期权定价可能只需几千条路径;而机构级的全面压力测试——模拟整个银行组合、数千个相互作用的风险因子、数千种情景——则可能需要大规模计算基础设施,耗时数小时。

这里有一条重要的收敛规律:误差与模拟次数的平方根成反比。也就是说,想把精度提高一倍,路径数大约要变成原来的 4 倍,而不是 2 倍。这种"边际收益递减"正是当前推动业界探索机器学习替代方案的计算瓶颈——训练一个快速模型来近似昂贵模拟的输出结果。

延伸知识:除了堆算力,量化实践中还有一类"方差缩减技术"可以在不增加路径数的前提下提升精度,例如对偶变量法(antithetic variates,对每个随机数 Z 同时模拟 -Z)和准蒙特卡洛(用低差异序列如 Sobol 序列替代伪随机数)。感兴趣的读者可以进一步研究。

五、比代码更重要的事:审视你的假设

一个反直觉的经验是:模拟引擎本身几乎是机械化的,真正决定结果有没有意义的,是随机数生成器的质量相关性假设的准确度

一个技术上完美无缺的模拟,如果建立在估计糟糕的相关系数矩阵或不切实际的波动率假设之上,依然会产出一个漂亮、自信的分布——只不过是"错误答案的漂亮分布"。这类错误的可怕之处在于代码不会报错:它安静地失败,给你一个非常精确的数字,去回答一个从一开始就问错了的问题。

如果要从中提炼一条可以带进任何建模工作的习惯,那就是:花在审视输入假设上的时间,至少要和打磨模拟本身一样多。骰子的诚实程度,取决于装填它的那只手。

总结

  • • 蒙特卡洛模拟的骨架只有四步:定义随机变量、生成随机样本、推演场景、大量重复。
  • • 用几何布朗运动 + NumPy 向量化,几十行代码就能模拟 10000 条股价路径,并计算亏损概率和 VaR。
  • • 别漏掉 (μ - 0.5σ²) 的漂移修正项,否则会系统性高估长期收益。
  • • 多资产模拟必须处理相关性,Cholesky 分解是标准工具;相关性假设的质量往往比路径数量更重要。
  • • 误差按模拟次数的平方根收敛:精度翻倍,计算量约需翻两番。
  • • 最关键的功夫在假设上:精确的错误答案,比模糊的正确方向更危险。

参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。

财经数据与量化投研知识社区

2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:

  1. 1. 双典系统赋能:获赠《财经数据宝典》与《量化投研宝典》完整文档,凝练多年实战经验,构建系统化知识框架;
  2. 2. 量化因子日更教程(2026重磅新增):每日更新「量化因子专题教程」,配套完整可运行代码与实战案例,深度拆解因子构建、回测与优化全流程;
  3. 3. 量化文章专题教程库:500+篇星球独有高质量教程式文章,系统覆盖策略开发、因子研究、风险管理等核心领域,内容基本每日更新,并配套精选学习资料与实战参考;
  4. 4. 量化投研实战课程:赠送《AKQuant-入门及实战》《PyBroker-入门及实战》视频课程,手把手教学,快速掌握量化策略开发技能;
  5. 5. 财经数据支持:定期更新国内外财经数据,为策略研发提供精准、可靠的数据基础;
  6. 6. 顶尖学者与行业专家分享:年度邀请学术界博士与业界资深专家开展前沿论文精讲与实战案例分享,不少于4场,直击研究前沿与产业实践;
    专家直连答疑:与核心开发者及领域专家实时互动,高效解决投研实战难题;
  7. 7. 专业社群与专属福利:加入高质量交流社群,获取课程折扣及更多独家资源。

星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!

 

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/198545