QuantStats · Monte Carlo

QuantStats蒙特卡洛模拟:破产概率与目标概率风险分析

QuantStats 内置蒙特卡洛模拟:qs.stats.montecarlo(returns, sims, bust, goal) 按收益分布随机模拟路径,输出破产概率(bust_probability)与目标达成概率(goal_probability)。它不是对未来收益的确定性预测,而是基于历史收益分布的概率化风险画像。

蒙特卡洛模拟
破产概率
目标概率

QuantStats 蒙特卡洛风险分析示意;基于官方 README,非实测输出。

Parameters

QuantStats 蒙特卡洛有哪些参数?

依据官方 README Monte Carlo Simulations 段落;参数默认值以官方实现为准。

参数 / 属性含义如何取值注意点
returns收益序列(输入)qs.utils.download_returns('META') 或自备 pandas Series需日/周/月收益序列,非原始价格
sims模拟路径次数官方示例 1000;次数越大越稳定次数越大耗时越长,需权衡精度与时间
bust破产阈值(亏损比例)官方示例 -0.20;按可承受亏损设负数阈值越接近 0 越容易触发「破产」
goal目标阈值(盈利比例)官方示例 0.50;按目标收益设正数阈值越高越难达到,概率越低
mc.bust_probability破产概率(输出)直接读属性,返回 0~1 或百分比模拟路径中跌破 bust 阈值的比例
mc.goal_probability / mc.plot()目标概率 / 分布绘图读属性 + 调 mc.plot() 可视化plot() 生成模拟分布图,辅助直观判断
随机种子(不显式出现在签名里)决定随机抽样序列,影响结果能否复现在数据侧固定,如先执行 numpy 的 seed 设定不固定时同一份数据两次运行的概率会有小幅波动,忽高忽低不代表模型变了
Steps

QuantStats 蒙特卡洛怎么一步步跑?

1. 导入库:import quantstats as qs —— 引入 stats/plots/reports 三模块。

2. 取收益序列:stock = qs.utils.download_returns('META') —— 得到 Meta 的日收益序列,也可换自备 Series。

3. 运行模拟:mc = qs.stats.montecarlo(stock, sims=1000, bust=-0.20, goal=0.50) —— 生成 1000 条模拟路径,破产阈值 -20%、目标阈值 +50%。

4. 查看结果:mc.bust_probability、mc.goal_probability 返回两个百分比;mc.plot() 绘制模拟分布。

5. 预期输出核对:bust_probability / goal_probability 是两个 0~1 之间的比例,二者不会同时很高;若两个都是 0 或都是 1,先检查序列是不是收益率、阈值正负号是不是写反。

6. 换一组阈值再跑一次:把 bust 从 -0.20 放宽到 -0.30、goal 从 0.50 下调到 0.30,预期破产概率下降、目标概率上升——这是判断阈值是否设得过严的快捷办法,也是 QuantStats 风险画像里最常用的一次对照实验。

7. 落到同一份记录里:把 sims、bust、goal、样本区间四项和两个概率写在一起,否则过几周回看时无法判断差异来自参数还是来自随机波动。

Related

QuantStats 还有哪些蒙特卡洛相关方法?

除主方法外,stats 与 plots 还提供按指标拆分的蒙特卡洛方法。

方法用途适用场景
montecarlo(主方法)模拟破产/目标概率整体风险画像,看「爆仓 vs 达标」概率
montecarlo_cagr模拟 CAGR(年化复合增长率)分布看长期收益的不确定区间
montecarlo_drawdown模拟最大回撤分布看未来可能遭遇多深的回撤
montecarlo_sharpe模拟夏普比率分布看风险调整收益的稳定性
montecarlo_distribution(plots)绘制模拟分布图直观展示模拟结果分布形态
risk_of_ruin(相关指标,非模拟)按收益分布解析估算破产风险赶时间、只想拿一个破产风险点估计时;注意它与蒙特卡洛的破产概率口径不同,不能直接比大小
Interpretation

QuantStats 蒙特卡洛结果怎么读、sims 怎么选?

bust_probability / goal_probability

前者是模拟路径中跌破 bust 阈值的比例,后者是达到 goal 阈值的比例。它们反映的是「在历史收益分布假设下」的风险暴露,不是对未来的确定性预言;分布一旦变化,结果可能明显偏移。

sims 次数的权衡

sims 越大,模拟结果越稳定(方差越小),但耗时线性上升。官方示例取 1000;对长收益序列或需要更精细尾部概率时,可适当提高,但要接受更长计算时间。

两个概率要合起来看

bust_probability 低不代表策略安全——如果 goal_probability 同样很低,说明多数模拟路径既不破产也到不了目标,策略更像「原地打转」。QuantStats 给的是两端概率,中间那段「什么都没发生」的区域要靠分布图或 montecarlo_cagr 才能看清。

样本区间决定可信度

同一份策略收益,截取 2020 年与截取 2023 年做 QuantStats 蒙特卡洛,得到的破产概率可能完全不同。原因不是方法不稳定,而是重采样完全继承样本的涨跌结构;因此汇报时必须写明样本起止与频率,否则数字无法被复核。

关键局限:蒙特卡洛基于「历史收益分布」随机重采样,隐含假设未来分布与历史相似。若未来出现分布漂移、结构性突变或尾部事件(黑天鹅),模拟概率可能低估真实风险,不构成收益保证或投资建议。
Compare

蒙特卡洛和确定性指标有什么区别?什么时候用哪个

两类指标回答不同的问题:确定性指标描述「历史发生了什么」,蒙特卡洛描述「在假设分布下未来可能发生什么」。

维度确定性指标(历史最大回撤等)蒙特卡洛模拟
回答的问题历史最大回撤是多少未来回撤超过某阈值的概率多大
输出形态单一数值(点估计)概率分布 / 百分比
依赖假设仅历史数据历史收益分布 + 随机模拟
适用场景复盘历史、对比策略前瞻风险画像、仓位压力测试
计算成本遍历一次收益序列,基本瞬间返回与 sims 成正比,sims 越大越慢
可复现性同一份数据结果完全一致未固定随机种子时会有小幅波动,需固定种子才能逐位复现
建议:两者配合使用——用历史指标做复盘基准,用蒙特卡洛补充「如果未来按历史分布重演」的概率视角;不把模拟概率当成保证。
Misuse check

QuantStats 蒙特卡洛最容易怎么被误用?

下面这些坑官方 README 不会写,但几乎每个第一次拿蒙特卡洛数字去汇报的人都会踩。逐条对照一遍,比换更复杂的模型有用。

误用方式典型表征会得出什么错结论怎么改
把 bust_probability 当真实破产概率报告里直接写「本策略破产概率 3%」读者以为这是客观概率,据此做仓位决策改成「在历史收益分布重采样下,3% 的模拟路径跌破阈值」,并附样本区间
sims 太小就下结论同一份数据反复跑,概率在两个值之间来回跳把一次抽样的结果当成稳定结论写进材料先小 sims 试跑,再放大并固定种子,两档结果差到能接受为止
收益序列太短只拿几十个交易日的数据就做模拟分布被少数极端日主导,尾部概率虚高或虚低尽量覆盖完整涨跌周期(数年以上日频),并在结论里注明样本长度
忽略收益序列的频率月频序列却按日频理解 -0.20 的含义阈值的时间尺度被放大或缩小,概率解释全错先确认序列频率,阈值与频率一起说明:月频阈值就按月理解
忽略资金流与复利假设模拟结果与真实账户曲线对不上判定「模型算错了」,转而怀疑代码明确模拟是否按固定比例复利、是否假设无出入金;真实账户有加减仓时不可直接套用
goal 设成不可能达成的值goal_probability 长期为 0,就断言策略没用错误否定一个本身正常的策略先看历史年化收益的量级再设 goal,或改读 montecarlo_cagr 的分布区间
只看概率不看分布材料里只有一个破产概率数字忽略「亏多少」的量级差异:同样是 5%,亏两成和亏一半完全不同配 mc.plot() 看分布形态,并与 montecarlo_drawdown 一起读
拿模拟概率直接反推仓位按 5% 破产概率倒推出一个仓位上限把假设当成已知风险,分布一旦漂移仓位就不再安全把概率当输入而非结论,同时保留止损或最大回撤上限这类硬约束
把一次模拟当成压力测试只跑一个阈值就宣称「已做压力测试」极端行情下的连续亏损根本没被覆盖至少同时看两档阈值与回撤分布,针对历史最差区间单独复跑
通用判断:凡是「用重采样得到的概率」做决策的地方都要过一遍这张表——概率本身没问题,问题在于它继承的是样本的分布结构。QuantStats 只负责算,不负责替你确认样本是否代表未来;样本假设不成立时,数字再稳也不代表风险可控。
汇报前自查五条:①样本区间与频率写清楚了吗;②sims 与随机种子记下来了吗;③阈值的时间尺度与序列频率对得上吗;④有没有第二个指标(回撤分布、年化收益区间)互相印证;⑤材料里区分了「模拟结果」与「历史事实」两种表述吗。这五条都过了再看数字本身;过不了的话,数字精度再高也没意义。
Sims & cost

模拟次数和耗时怎么权衡?

sims 每加一个量级,结果更稳、时间更长;下面按量级给出用途与代价,用来排序而不是当承诺——实际耗时取决于收益序列长度与本机性能。

sims 量级适合的用途代价与表现建议
100~500试探阈值是否合理、排查代码是否跑通概率跳动明显,只能看数量级只用于起草,结论不要写进汇报材料
1000日常风险画像(官方示例量级)通常秒级到十几秒量级单策略汇报的默认选择
5000需要更稳的尾部概率(例如 1% 附近)耗时约为 1000 档的数倍先与 1000 档对比波动,稳定后再采用
10000 及以上精细尾部估计、多阈值扫描耗时明显上升,单机串行较慢先锁定种子与阈值,只放大这一次
多策略批量组合层面的风险横向对比总耗时 = 策略数 × 单次耗时先小 sims 粗筛,再对入围策略放大
参数搜索循环内把风险约束加进调参大部分时间会被模拟吃掉把模拟放到筛选之后一步,不要放进每轮迭代

1. 先小规模试跑:mc = qs.stats.montecarlo(stock, sims=200, bust=-0.20, goal=0.50) —— 确认参数能被接受(阈值正负号、序列是收益率而非价格)。预期秒级返回两个概率,而不是报错或全 0。

2. 固定随机种子再放大:import numpy as np; np.random.seed(42) 之后重跑 sims=5000 —— 预期同样输入两次运行得到一致结果,便于把数字写进材料后能被复核。

3. 对比两档 sims 的稳定性 —— 记录 1000 与 5000 两档的 bust_probability / goal_probability,当两者差距小于你的汇报精度时即可停止放大,继续加次数只涨耗时。

4. 出图确认分布:mc.plot() —— 预期得到模拟结果的分布图;如果出现异常长尾或几乎所有路径同向,先回头检查样本区间是否只覆盖了单边行情。

并行提示:耗时主要来自 sims 与收益序列长度,与阈值个数无关——想同时看 -10%/-20%/-30% 三档破产线,可以一次模拟后用同一批路径分别统计,而不是跑三次蒙特卡洛。QuantStats 的具体性能表现以本机实测与官方实现为准。
小技巧:如果只是想比较两个阈值的相对高低,小 sims 往往就够;只有要把具体数值(例如 1.8%)写进对外材料时,才值得把 sims 加上去并固定种子重跑一遍,并把两次结果的差距写在备注里。如果机器较慢,可以先固定阈值再逐步放大 sims,而不是一上来就直接跑大次数。
Data first

国内跑量化蒙特卡洛,数据从哪来?

QuantStats 本身不做数据抓取,也不内置 A 股数据源:无论指标、模拟还是报告,吃到的都是「收益率序列」这一层。所以第一步是先解决「序列从哪来」。

数据来源覆盖市场前置条件拿到后怎么用
qs.utils 内置取数美股等海外行情能访问外网行情源直接得到收益率序列,示例写法 download_returns('META')
yfinance(独立安装)美股行情、历史K线外网可达;通常无需密钥自取收盘价后算收益率序列,再喂给 QuantStats
akshareA 股、期货、期权、基金、指数等公开数据能访问公开财经站点A 股研究常见取数路线,取价后同样先转收益率序列
tushareA 股、港股、美股等接口需要 Tushare Token适合批量、可重复的取数场景
自有数据导出的 CSV取决于数据源本身整理成「日期 + 收益」两列用 pandas 读入并设日期索引,再交给 QuantStats
组合权重与再平衡记录多标的组合先算组合层收益做组合风险模拟前先确认权重口径与再平衡假设
券商客户端导出自己的真实持仓或历史成交导出后需清洗为收益序列适合复盘自己的账户,但要注意分红送股与手续费是否已计入

1. 取 A 股日线:df = ak.stock_zh_a_hist(symbol="600519", period="daily", adjust="qfq") —— 预期返回含日期与收盘价的表;接口名与列名会随 akshare 版本变化,以官方文档为准。

2. 转成收益率序列:r = df.set_index("日期")["收盘"].pct_change().dropna() —— 预期得到一条日频 Series,首行 NaN 已剔除,可直接喂给 QuantStats。

3. 跑模拟:mc = qs.stats.montecarlo(r, sims=1000, bust=-0.20, goal=0.50) —— 预期返回破产/目标两个概率;若取数失败,先排查网络与数据源可用性,再考虑换源。

注意边界:海外行情源在国内网络下可能取数失败或超时,此时换 akshare / tushare / 本地 CSV 通常更稳;数据源可用性与字段以各自官方说明为准。另外,A 股的涨跌停与停牌会让「日收益序列」天然带上截断特征,做蒙特卡洛时要把这一点写进假设,而不是当成普通分布处理。
取数失败怎么办:先确认库本身装没装对,再确认网络能否访问对应站点,最后才怀疑代码。A 股日线常见的两个坑是复权方式选错(不复权会把除权跳空算成大跌)和停牌日缺行(需要补齐或直接按实际交易日序列处理),这两点会直接影响波动率与回撤口径。另外,同一策略在不同数据源上得到的序列长度与复权口径可能不同,模拟结果也会跟着变——换源或换复权方式后必须重跑,不要在旧数字上继续解读;跨源对比时先把样本区间对齐,再谈差异。
FAQ

常见问题有哪些?

蒙特卡洛模拟是什么?

按收益序列的历史分布随机生成大量路径,估算达到破产/目标阈值的概率,做概率化风险分析。具体算法与默认参数以官方 README/实现为准。

sims 设多少合适?

官方示例用 sims=1000;次数越多越稳定但越慢,需权衡精度与耗时,以官方文档为准。

破产/目标阈值怎么定?

按你的风险偏好设 bust(亏损比例,负数)与 goal(盈利比例,正数),官方示例用 -0.20 / 0.50;阈值设定会直接影响概率结果。

结果能预测未来吗?

不能。它基于历史收益分布模拟,隐含「未来分布与历史相似」的假设,不构成收益保证或投资建议。

为什么两次跑出来的破产概率不一样?

蒙特卡洛是随机抽样:未固定随机种子时,每次模拟走的是不同的路径集合,概率会有小幅波动,sims 越小波动越明显。要复现结果就固定种子,并在记录里同时写下 sims、bust、goal 与样本区间。具体随机数处理以 QuantStats 官方实现为准。

不想自己写代码,有没有更省事的路子?

QuantStats 与 EasyClaw 无已证实集成,两者是相互独立的路线:本机已核验的 quant-analyst 技能也涉及回测与风险指标,但实现方式、参数暴露程度与输出形式都不同,适合的场合也不同,选择前以各自官方说明为准。

概率算完了,接下来看什么

风险画像只能说明「可能多楠」,要把收益、回撤、相对基准一起交给别人看,还得回到报告与指标页。