:root{--brand-1:#18794e;--brand-2:#3dd68c;--brand-3:#2bb673;--brand-soft:#3dd68c22;} .hero .kicker{color:var(--brand-2)} .nav .ep{color:var(--brand-2)} .sec h2 .num{color:var(--brand-2)} .quote::before{background:var(--brand-1)} .quote .q-text .em{color:var(--brand-2)} .quote .q-water .pg{color:var(--brand-2)} .widget .w-title{color:var(--brand-2)} .takeaway h3{color:var(--brand-2)} .takeaway ol li::marker{color:var(--brand-2)} .next .nx-label{color:var(--brand-2)} .formula .eq{color:var(--brand-2)} a{color:var(--brand-2)} .comp.c1 .tag{background:var(--brand-soft);color:var(--brand-2)} /* 置信区间演示 */ .montecarlo .controls{display:flex;gap:10px;flex-wrap:wrap;margin:12px 0} .montecarlo .controls button{font-size:12.5px} .montecarlo .controls button.on{background:var(--brand-soft);color:var(--brand-2);border-color:var(--brand-1)} .montecarlo .controls .info{font-size:12px;color:var(--t3);align-self:center;margin-left:auto} .montecarlo .chart{width:100%;height:260px;display:block;margin:12px 0} .montecarlo .stats{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:12px} .montecarlo .stats .sc{background:var(--bg-mute);border:1px solid var(--divider);border-radius:8px;padding:10px;text-align:center} .montecarlo .stats .sc .sl{font-size:11px;color:var(--t3);margin-bottom:3px} .montecarlo .stats .sc .sv{font-size:17px;font-weight:700;font-family:var(--mono)} .montecarlo .stats .sc.obs .sv{color:var(--yellow-1)} .montecarlo .stats .sc.mean .sv{color:var(--brand-2)} .montecarlo .stats .sc.lo .sv{color:var(--red-1)} .montecarlo .stats .sc.hi .sv{color:var(--green-1)} .montecarlo .verdict{margin-top:12px;padding:13px;border-radius:8px;font-size:13px;text-align:center} .montecarlo .verdict.ok{background:var(--green-soft);color:var(--green-1);border:1px solid var(--green-1)} .montecarlo .verdict.bad{background:var(--red-soft);color:var(--red-1);border:1px solid var(--red-1)} .montecarlo .verdict.warn{background:var(--yellow-soft);color:var(--yellow-1);border:1px solid var(--yellow-1)}
量化交易实战 · 第 17 期 · 第二季

回测夏普 2.0——是真的还是运气?

蒙特卡洛回测 · monte carlo bootstrap backtest

普通回测只给你一个夏普 2.0——但这只是"历史恰好这样走"的一条路径。换个交易顺序,夏普可能 1.5 也可能 2.5。蒙特卡洛把交易打乱重采样,跑几千次,得到夏普的分布和置信区间。如果 95% 置信区间是 [1.2, 2.8],你的 2.0 大概率是真的;如果是 [0.3, 3.7],那 2.0 可能只是运气。一个数字不如一个区间可信。
⏱ 约 9 分钟 🎯 想知道回测结果可不可信的人 📦 源:whale-quant

01为什么一条路径不够

回测的本质是:拿历史交易序列,按时间顺序累加收益,算夏普。问题是——历史只有一种顺序。但未来的交易顺序是随机的,同样的交易换个顺序,夏普可能差很多。

举个极端例子:你的策略有 100 笔交易,其中 10 笔大赚、10 笔大亏、80 笔小赚。如果大赚集中在前期,资金曲线一路向上,夏普 2.5;如果大亏集中在前期,资金曲线先腰斩再爬回来,夏普可能 0.5。同样的交易,不同顺序,夏普差 2 倍。哪个才是"真实"的夏普?

答案是:都不是。真实的夏普是一个分布。蒙特卡洛就是生成这个分布:把交易序列随机打乱重排,算每次的夏普,重复几千次,得到夏普的分布和置信区间。这才是策略"稳健性"的真实写照。

一个数字不如
一个区间可信。
灏天文库 · 量化交易实战 P.51

02置信区间演示:你的 2.0 可信吗

下面模拟一个策略,原始回测夏普 2.0。点"重采样"看蒙特卡洛把交易打乱后的夏普分布——直方图越窄说明策略越稳,越宽说明越靠运气。看 95% 置信区间和你的 2.0 的关系。

🎲 蒙特卡洛置信区间演示
点重采样,看夏普分布和 95% 置信区间。
未运行
原始夏普
2.00
蒙特卡洛均值
—
95% 下限
—
95% 上限
—
点"重采样"开始模拟。

03两种蒙特卡洛:打乱顺序 vs 重采样

蒙特卡洛回测有两种主要做法,回答不同问题:

方法1

交易顺序打乱

把回测的交易序列随机重排,算每次夏普。回答:"同样的交易换个顺序,夏普会变多少?"——测路径依赖。

方法2

交易 bootstrap

从交易分布里有放回抽样,组成新序列。回答:"如果交易分布不变但样本变了,夏普会变多少?"——测样本稳定性。

方法3

收益 bootstrap

直接对每日收益做 bootstrap。更简单,但忽略了交易结构。

方法4

块 bootstrap

按块(如 5 天一块)抽样,保留自相关。金融收益有自相关,普通 bootstrap 会低估方差。

实战建议:用块 bootstrap。金融收益有自相关(今天涨明天可能还涨),普通 bootstrap 假设独立,会低估方差、高估置信度。块 bootstrap 保留块内自相关,置信区间更真实。块长度一般取 5-10 天。

另一个关键:置信区间窄 ≠ 策略好。窄只说明"结果稳定",但稳定的可能是稳定地亏。还要看均值的符号和大小——均值正且区间下限也正,才是真稳健。

窄区间 + 正均值,
才是真稳健。
灏天文库 · 量化交易实战 P.52

04带走这套清单

✅ 蒙特卡洛回测 6 条可执行规则

  1. 别只看一个夏普:一条路径的夏普是随机样本,要看分布和置信区间。
  2. 用块 bootstrap:保留自相关,普通 bootstrap 会低估方差、高估置信度。
  3. 跑够次数:至少 1000 次,10000 次更稳,分布才收敛。
  4. 看 95% 区间下限:下限>0 才说明"最坏情况也赚",下限<0 说明可能亏。
  5. 窄区间+正均值才稳健:窄但负的,是稳定地亏,没用。
  6. 对比策略用置信区间:两个策略夏普接近时,看谁的区间下限更高、更窄。
回测给你一个数,
蒙特卡洛给你一个区间。
灏天文库 · 量化交易实战 P.53