2.4 双均线策略回测全程复盘:一条漂亮净值的证伪现场


2.4 双均线策略回测全程复盘:一条漂亮净值的证伪现场

本节摘要:本节是第二章主线案例的现场记录。一个最普通的双均线策略,样本内年化表现惊艳、回撤温顺;随后在参数曲面、扰动测试与滚动前推验证的三重审讯下原形毕露。案例完整走过"背景—操作—结果—解读—变式"五步,所有数字用于演示方法而非暗示任何真实标的的未来表现。

一、案发背景:一句话假设与它的第一版实现

主角是那句流传最广的口诀:短期均线上穿长期均线(金叉)买入,下穿(死叉)卖出。研究者的起手式标准得不能再标准:拉一段十年日频数据,二十日均线对六十日均线,复权收盘价,次日开盘成交,双边成本按千分之一计入。回测跑完,屏幕上出现一条台阶式上行的净值曲线,最大回撤温和,交易次数不到两百笔——每一个单项指标都像在说"这个策略值得加钱"。

策略的状态机实现很干净,这也是复盘能顺利推进的前提:

对应的最小回测代码骨架如下,为教学做了精简:

import numpy as np def dual_ma_backtest(px, fast=20, slow=60, cost=0.001): """双均线回测骨架: 信号次日开盘成交, 成本按比例扣减. px: 收盘价序列; 返回净值序列与交易日志""" pos = 0 equity, log = [1.0], [] fast_ma = np.convolve(px, np.ones(fast) / fast, "valid") slow_ma = np.convolve(px, np.ones(slow) / slow, "valid") fast_ma = fast_ma[-len(slow_ma):] # 对齐两均线起点 prices = px[-len(slow_ma):] for t in range(len(slow_ma) - 1): ret = prices[t + 1] / prices[t] - 1.0 # 用次日价格结算 golden = fast_ma[t] > slow_ma[t] and fast_ma[t - 1] <= slow_ma[t - 1] dead = fast_ma[t] < slow_ma[t] and fast_ma[t - 1] >= slow_ma[t - 1] if golden: pos = 1 elif dead: pos = 0 log.append(("平仓", t)) daily = pos * ret - (abs(pos) * cost if golden or dead else 0.0) equity.append(equity[-1] * (1 + daily)) return np.array(equity), log

二、操作:三道审讯依次上场

第一道,参数曲面。把快线从五扫到四十、慢线从三十扫到二百,共约两千组组合,每组记录夏普比率。结果让研究者心里一紧:表现最好的区域极其狭窄——快线三十、慢线一百七十附近孤峰突起,夏普比周围邻域高出一大截;而被口诀寄予厚望的二十对六十,表现平平。孤峰不是高原,按上一节的判别标准,这已经是黄色警报。

第二道,扰动测试。把最优参数上下各挪一档,夏普立刻腰斩;把快线改成三十一(仅仅加一),成绩明显劣化。逻辑如果真实存在,不该脆弱到经不起参数挪一格。

第三道,滚动前推验证。训练五年、测试一年,窗口逐年前推,得到十段样本外成绩。这才是判决书。

图 2-3:同一条净值曲线的两个视角

图 2-3:同一条净值曲线的两个视角

三、结果与解读:判决书怎么写

十段滚动考试里,只有三段勉强为正;把十段样本外净值拼接,整条曲线围绕起点震荡走低。与此同时,样本内那条台阶式曲线依然挂在报告第一页——两图对照,就是本次复盘最值得收藏的教学画面。解读分三层:

层一,过拟合成立。孤峰参数 + 扰动脆弱 + 样本外失效,三项证据互相咬合。样本内的优势被判定为"两千次抽奖的最高奖",而非可复制的能力。这是最常见的一种证伪,也是 2.3 节全部方法论的落地。

层二,但逻辑未必全错。趋势跟踪作为策略族有深厚的经济学根基(第三章 3.1 节)。样本外失效说明"这个参数化的双均线在它没见过的时段没有稳定优势",不等于"趋势效应不存在"。判决要精确到被证伪的对象:死的是这个具体实现,不是整个族谱。

层三,验证流程自身也要被怀疑。复盘的最后一问是:有没有可能是我的验证流程错杀了它?逐项检查后确认:成交时点对齐、成本计入、样本窗口互不重叠、参数只从训练段产生。流程无罪,判决成立。

四、教训清单与变式

这次复盘留下的教训可以直接抄进任何团队的研发规范:

  1. 先看参数曲面,再看最优值——孤峰直接终止评审,省得后面浪费感情;
  2. 利润集中度是必查项——如果收益主要来自两三段行情,先问自己样本外还能不能等到那种行情;
  3. 样本外成绩拼接图必须出现在报告第一页,与样本内曲线同框;
  4. 证伪对象要写精确——是"该参数化实现"还是"整个策略族",措辞决定后续研究的起点;
  5. 失败案例归档留痕,防止半年后有人用同样的思路再踩一遍。

变式练习留给读者:把快慢均线换成唐奇安通道突破,重跑同一套三道审讯,观察参数高原是否更宽;给双均线加一个波动率目标仓位,看样本外分布的宽度是否收窄;在多个不相关的标的上重复整个流程,检验结论的跨市场一致性。每一步都在加深同一个认知:证伪不是否定研究,证伪本身就是研究

复盘还有一条容易被忽略的支线:研究者本人的记录习惯。本次案例之所以能在两周内走完全部流程,是因为每一步的中间产物都被留存——参数曲面的原始数据、扰动测试的每组成绩、十段滚动验证的逐段明细。没有这些留痕,"孤峰"就只是一句口头描述,复核者无法判断判定是否可靠;有了留痕,任何同事都可以在半天内重放全部审讯。研究流程的可信度最终落在可复现性上,而可复现性的成本极低:一个规范的目录结构,加上"每跑一次实验就存一次输入与输出"的纪律。这条支线与主线同等重要——方法会过时,留痕的习惯不会。

本节要点回顾

  • 漂亮净值只是嫌疑犯不是结论:两千年参数里选出的最好成绩,几乎必然过拟合嫌疑;
  • 三道审讯各有分工:参数曲面看连片性,扰动测试看脆弱性,滚动验证看定型后表现;
  • 判决对象要精确:被证伪的是具体实现,策略族层面的判断需要更多跨市场证据;
  • 流程自检是最后一环:错杀与漏放都源于验证流程自身的漏洞,判决前先自证清白;
  • 证伪产出规范:教训清单与失败归档,是团队最便宜的复利。

⚠️ 常见坑:复盘结束后顺手把参数改成"样本外表现最好"的那组——恭喜,你刚刚把测试集用成了训练集,整个流程需要推倒重来。

单个案例的证伪经验如何推广?下一章把四大策略门派放上同一张桌子,先认族谱再谈存活。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U