策略做到了什么,没做到什么
在 2016-09-07 至 2026-09-04 的 2,513 个交易日里,20/100 双均线策略累计收益为 152.51%,年化 9.73%,Sharpe 为 0.809,最大回撤为 -21.99%。同期 SPY 买入持有累计收益为 312.85%,年化 15.28%,Sharpe 为 0.882,最大回撤为 -33.72%。 [[1]]
策略共发生 21 次交易,持仓比例为 76.88%。空仓并没有让策略远离所有下跌,例如 2022 年策略收益为 -17.62%,但相比基准的 -18.18% 只取得了有限改善;它更像是一个趋势过滤器,而不是严格的危机对冲。 [[1]]
研究口径:先把“回测”说清楚
标的使用 SPY 的复权收盘价。SPY 是可交易的标普 500 投资代理,不是标普 500 指数本身,也不是标普 500 全收益指数。数据来自 Yahoo Finance Chart API,实际样本为 2016-09-07 至 2026-09-04,共 2,513 条日频记录。 [[1]]
- 信号
- SMA(20) 大于 SMA(100) 时生成多头信号。
- 执行
- 信号在收盘生成,转化为次一交易日的多头仓位,避免同收盘价的理想化成交。
- 成本
- 默认每单位 turnover 收取 5 bps,成本随仓位变化计入策略收益。
- 年化
- 252 个交易日;无风险利率 rf = 0;Sharpe 按日收益年化。
- 价格字段
- indicators.adjclose.adjclose,用于将拆分与分红影响纳入价格序列。
- 复现命令
- python -m backtest.run --ticker SPY --years 10 --output-dir results
页面图表中的交互资产路径与回撤曲线使用 daily_20_100.csv 中的真实日期点做轻量采样,完整高分辨率曲线同时保留原始 PNG。热力图、年度收益和成本情景则直接对应各自 CSV 的全部记录。
资产路径:少回撤,但在强趋势中落后
下面的资产路径以 $1 初始资本归一化。交互线图采用 daily_20_100.csv 的真实采样点,悬停可查看日期、策略净值、基准净值;静态 PNG 是回测目录中的完整曲线版本。两者共同呈现出相同的结论:策略曲线更平缓,但在长期上行区间明显落后。
hover 查看数值
风险画像:回撤改善是真实的,收益牺牲更大
策略年化波动率为 12.45%,低于基准的 17.97%;最大回撤为 -21.99%,低于基准的 -33.72%。但 Sharpe 仅从基准的 0.882 降至 0.809,说明减少波动并未带来更好的单位风险收益。Calmar 也略低于基准,分别为 0.443 与 0.453。 [[1]]
| 指标 | 20/100 策略 | SPY 买入持有 | 解读 |
|---|---|---|---|
| 累计收益 | 152.51% | 312.85% | 策略少 160.34 个百分点 |
| 年化收益 | 9.73% | 15.28% | 策略少 5.55 个百分点 |
| 年化波动率 | 12.45% | 17.97% | 策略低 5.52 个百分点 |
| Sharpe | 0.809 | 0.882 | 基准更高 |
| 最大回撤 | -21.99% | -33.72% | 策略改善 11.73 个百分点 |
| Calmar | 0.443 | 0.453 | 基准略高 |
| 交易次数 | 21 | 0 | 策略有换仓摩擦 |
参数敏感性:10/100 是样本内 Sharpe 峰值
敏感性网格固定成本为 5 bps,遍历短均线 2、5、10、15、20、30、40、50 与长均线 50、75、100、120、150、180、200、250。网格中最高 Sharpe 为 10/100 的 1.037;20/100 的 Sharpe 为 0.809。最大回撤最浅的代表参数是 10/50,为 -15.11%,但其累计收益仅 146.71%。 [[1]]
| 参数 | 成本 | 累计收益 | 年化收益 | Sharpe | 最大回撤 | 交易次数 |
|---|---|---|---|---|---|---|
| 20 / 100 | 5 bps | 152.51% | 9.73% | 0.809 | -21.99% | 21 |
| 10 / 100,最高 Sharpe | 5 bps | 210.72% | 12.04% | 1.037 | -21.93% | 27 |
| 10 / 50,最浅回撤 | 5 bps | 146.71% | 9.48% | 0.866 | -15.11% | 57 |
| 2 / 120,代表高收益 | 5 bps | 175.59% | 10.70% | 0.954 | -18.56% | 55 |
敏感性结果是同一历史样本上的 in-sample 比较,不应被解释为未来可实现的最优参数。尤其是 10/100 的优异表现,仍可能包含数据挖掘与参数选择偏差。
成本情景:5 bps 不是主要矛盾,但方向一致
在 20/100 固定参数下,将单位 turnover 成本从 0、5、10 提高到 20 bps,累计收益从 155.17% 降至 144.68%,Sharpe 从 0.817 降至 0.784,最大回撤由 -21.92% 加深至 -22.23%。成本对收益有单调侵蚀,但没有改变结论的主方向:策略仍显著落后买入持有。 [[1]]
| 成本 | 累计收益 | 年化收益 | Sharpe | 最大回撤 | 终值 |
|---|---|---|---|---|---|
| 0 bps | 155.17% | 9.85% | 0.817 | -21.92% | 2.5517 |
| 5 bps | 152.51% | 9.73% | 0.809 | -21.99% | 2.5251 |
| 10 bps | 149.87% | 9.62% | 0.800 | -22.07% | 2.4987 |
| 20 bps | 144.68% | 9.39% | 0.784 | -22.23% | 2.4468 |
局限与数据挖掘风险
这是一个历史样本内的日频回测,不是交易承诺。收盘信号与次日生效已经避免了最直接的未来函数,但仍不能代表真实成交。原始结果明确提示,真实买卖中的成交价、点差、税费、市场冲击与融资成本没有建模,日内价格路径也没有被使用。 [[1]]
- SPY 只是 ETF 代理,不等同于指数本身;其费用、跟踪误差与分红处理可能与指数基准不同。
- 单一十年窗口包含特定市场状态。结论没有经过滚动样本外、跨资产或不同市场的验证。
- 敏感性网格会放大样本内选择偏差。最高 Sharpe 参数是“在这段历史上最好”,不等于未来最好。
- 策略为 long-only,空仓期间的现金收益按 rf=0 处理,未模拟现金管理收益。
- 交易次数不高,但均线交叉在震荡市可能产生连续反复换仓,成本与滑点会侵蚀实际结果。
图表实现说明:共享工作区未提供可复用的离线 ECharts 构建,且本报告被要求无 CDN、本地直接打开。因此页面使用内联 SVG 交互降级实现,提供 tooltip、指标切换与响应式布局;数据仍来自真实回测产物,不使用示意值。
参考文献与可复现信息
- [[1]]、Yahoo Finance Chart API,SPY historical chart data。访问口径对应 2016-09-07 至 2026-09-07 的请求窗口,实际有效数据至 2026-09-04。
本报告使用的本地真实产物包括 metadata.json、metrics.json、README.md、daily_20_100.csv、sensitivity.csv、cost_scenarios.csv、annual_returns.csv 与 equity_curve.png。复现命令为:
python -m backtest.run --ticker SPY --years 10 --output-dir results