这门课交付什么
同一条规则,四种回测姿势,四个天差地别的结论
一条最普通的 5/20 双均线规则,同一份数据,同一段 21 年。四个人分别拿它跑回测,交上来四张成绩单:
5248.9% 724.5% 552.5% 1.97%
四个人都没撒谎,代码都跑通了,数字都是真算出来的。差别只在于——他们各自"忘了"处理几件事。
这门课要教的就是那几件事。它不教你怎么让第一个数字出现,它教你怎么让第四个数字出现,以及为什么第四个数字才配拿去做决定。
体重秤上的数字取决于你什么时候称:早上空腹穿短裤,和晚饭后穿羽绒服拎着包,能差出五公斤。
两个数字都是秤"真实测出来"的。但只有一个能用来判断你这个月是胖了还是瘦了。
回测就是这台秤。业余和专业的区别不在于谁的秤更贵,而在于谁知道自己刚才是怎么称的。
一、四级阶梯:每一级只修一个错
同一份沪深300 日线(2005-04-08 → 2026-07-29,5177 个交易日),同一条规则「MA5 上穿 MA20 则持仓,下穿则空仓」。我们只改回测的姿势:
| 级别 | 改了什么 | 累计收益 | 年化 | 最大回撤 | 夏普 | 成交次数 |
|---|---|---|---|---|---|---|
| L0 业余版 | 当日信号当日成交 + 零成本 | 5248.9% | 20.54% | -28.2% | 1.21 | 312 |
| L1 | 只修一处:信号次日才生效 | 724.5% | 10.41% | -35.0% | 0.67 | 312 |
| L2 | 再加佣金 0.025% + 滑点 0.05%(单边) | 552.5% | 9.20% | -35.6% | 0.61 | 312 |
| BH | 什么都不做,买入持有 | 358.4% | 7.41% | -72.3% | 0.41 | — |
读三个数:
- 一行代码 5248.9% → 724.5%。L0 用当天的均线关系去吃当天的涨跌——收盘才知道的信号,却按当天全天的收益结算。这就是未来函数,代码上只差一个
.shift(1),结论上差 4524 个百分点。 - 成本吃掉 172 个百分点。单边 0.075% 听起来像四舍五入的零头,乘以 312 次成交,724.5% 变成 552.5%。
- 回撤那一列比收益列更能说明问题。买入持有 21 年最大回撤 -72.3%——意味着 100 万一度只剩 27.7 万。任何跟你谈收益不谈回撤的人,都在给你看半张成绩单。
看到 L2 还是赢了买入持有(552.5% vs 358.4%),是不是说明这策略可以用?
不能。L0–L2 有一个共同的、更隐蔽的问题:5/20 这组参数,是我们在已经知道 2005-2026 全部行情之后写下的。它是"经典参数",而"经典"本身就是全网调参的幸存者。
这个错不修,前面三级全部作废。第四级专门修它。
二、第四级:把「参数是事后挑的」这个错也修掉
规矩很简单:参数只允许在 2005-04-08 → 2015-12-31 这段里挑,挑完锁死,拿到 2016-01-01 → 2026-07-29 这段从没参与过挑选的数据上跑一次。
样本内我们做了一次诚实的网格搜索:快线 3–30、慢线 5–120,一共试了 591 组参数,按年化收益取冠军 —— MA5/MA55,样本内年化 26.08%。
| 累计收益 | 年化 | 最大回撤 | 夏普 | |
|---|---|---|---|---|
| 样本内 2005–2015 MA5/55(冠军) | 1102.4% | 26.08% | -33.3% | 1.28 |
| 样本内 2005–2015 MA5/20(朴素) | 590.8% | 19.74% | -35.6% | 1.00 |
| 样本内 2005–2015 买入持有 | 271.8% | 13.02% | -72.3% | 0.57 |
| 样本外 2016–2026 MA5/55(同一组参数) | 22.8% | 1.97% | -26.0% | 0.22 |
| 样本外 2016–2026 MA5/20(朴素) | 1.7% | 0.16% | -35.3% | 0.08 |
| 样本外 2016–2026 买入持有 | 32.6% | 2.71% | -45.6% | 0.24 |
样本内年化 26.08% 的冠军,到了样本外只剩 1.97%——输给了什么都不做的 2.71%。
这不是我挑了个坏例子。这是在 591 组参数里认认真真挑出来的最好的一组。它样本内的漂亮,大部分不是规律,是噪声——591 次抽奖里最幸运的那一张,拿到新的一轮就不灵了。
为什么「591」这个数字必须一起报出来
如果一组参数真的毫无用处,它在样本内也有大约一半的概率"看起来还行"。试 591 组,几乎必然能挑出一组"看起来非常行"的。
"我调出了一组年化 26% 的参数"这句话本身不携带任何信息——除非你同时说出:你试了多少组,以及你在完全没参与挑选的数据上验证过没有。
这个问题有名字:多重检验、数据窥探偏差。它不是玄学,是可以算的。P3 章第 4 节专门量化它——你试了 N 组之后,那个夏普比率要打多少折才算数。
三、这门课交付三个成品
上面那张表,不是靠调库调出来的,是靠知道要修哪四件事。整门课就围绕"怎么把这些事系统性地修干净"展开,并交付三件你带得走的东西:
配套的还有一份研究报告模板:数据管线 → 因子 → 策略 → 滚动前推 → 成本敏感性 → 置信区间。毕业项目就是用它出一份自己的报告。
四、这门课不教什么(先说清,省你时间)
- 不推荐任何股票、基金、板块。全课示例只用宽基指数或代码占位符。教你怎么自己检验一个因子,不告诉你买什么。
- 不教实盘下单。课程止于模拟撮合与纸上交易(P8 最后一节专门讲为什么停在这里,以及真要往前走会遇到什么)。
- 不给投资计划。不给金额、比例、期限建议。
- 不承诺收益。你在本节已经看到了:样本外跑输躺平的结果,我们照实放在第一节。
五、你需要什么
| 前置 | 站内落点 | 硬要求吗 |
|---|---|---|
| Python 基础(函数、pandas 会用) | 站内编程课 | 是 |
| 量化认知(回测为什么会骗你) | 免费课《看懂 AI 量化》Q0 章 | 建议 |
| LLM API 基础 | 站内《DeepSeek 快上手》 | P7 章之前补上即可 |
如果你上过免费课的 q1.9,L0 与 L1 这两级你见过。这门课的重点从第三级(成本)和第四级(参数偏差)开始——那两级才是把"能跑通"变成"算得对"的地方。
🔧 动手做:把四级阶梯亲手降一遍(6 分钟)
跑 ladder_demo.py,盯住同一条 MA5/20 规则在四级下的年化:
L0 业余版(未来函数+零成本) 20.54%
L1 修掉未来函数 10.41% ← 一个 .shift(1),砍掉 10 个百分点
L2 再加佣金+滑点 9.20%
BH 买入持有(躺平) 7.41%
动手改三处,每改一处重跑一次,看数字怎么塌:
- 把
.shift(1)删掉 —— 看年化怎么从 10.41% 弹回 20.54%。这 10 个百分点全是偷看未来换来的,而代码跑起来一点错都不报。 - 把单边成本从 0.075% 改成 0(第 3 行的
COST)—— 看 L2 怎么变回 L1。再改成 0.3%,看它掉到哪。 - 把样本内区间从 2015 年底改成 2018 年底,重跑 L3 —— 591 组参数选出来的"最优"还是 MA5/55 吗?换个截止日期就换一组最优参数,这件事本身就是答案。
✅ 做到这里你应该看见:同一条规则,四个年化(20.54 / 10.41 / 9.20 / 7.41),以及样本外那两行——样本内年化 26.08% 的"最优参数",样本外只剩 1.97%,还不如躺平的 2.71%。
为什么:这一节不要求你懂策略,只要求你亲手把数字降下来一次。降下来的那 13 个百分点,就是这门课要教的全部东西的价格标签。
📌 免责:本课为技术教学,所有回测数字均为历史模拟(本节多为反面示范),不构成任何投资建议;指数不可直接交易,文中仅作宽基标的的代理;投资有风险,盈亏自负。
这一节你看到了同一条规则的四张面孔:5248.9%(未来函数)→ 724.5%(修掉它)→ 552.5%(加上成本)→ 样本外年化 1.97%(累计仅 22.8%,修掉参数偏差,年化输给躺平 2.71%)。四个数字都是真跑出来的,只有最后一个能拿去做判断。
你也知道了这门课要交付什么:自研回测引擎、因子评价体系、模拟交易系统,以及不教什么(不荐标的、不教下单、不给计划、不承诺收益)。
下一节把标准写死:专业和业余的七个判据——对账、PIT、样本外、成本、容量、多重检验、可复现。这七条既是本课每一节的验收清单,也是你以后拿到任何一份回测报告时的照妖镜。
🔎 来源与核验· 3 条,点开核对
