· 量化交易 · 第 3 / 6 讲

二、回测方法论

前视偏差、数据泄露、过拟合、幸存者偏差、Walk-forward、滑点与容量——识别一个回测结果是否可信。

回测(Backtesting)是用历史数据模拟策略执行、评估其过去是否有效的核心工具。它的价值在于:在不花真钱的前提下,初步筛除明显无效的策略,并为进一步优化提供方向。然而,回测本质上是一种统计推断——从过去的样本推断未来的表现——因此天然带有各种偏差和陷阱。一个没有正确处理这些问题的回测,不但没有参考价值,还会因为虚假的信心让人在实盘中亏损。

本章按「偏差 → 统计诊断 → 建模细节 → 加密市场陷阱」的脉络展开,目标不是教你如何得到一个漂亮的回测结果,而是教你识别一个回测结果是否可信


前视偏差(Look-ahead Bias)

定义

前视偏差是指在信号计算中使用了在该时间点尚不可知的未来数据,导致回测结果优于实盘中理论上能实现的结果。它是最常见、也最隐蔽的回测错误。

典型案例

案例一:以当根 K 线收盘价作为入场价。

错误逻辑:当 MA 在当前 K 线内出现金叉 → 以本根 K 线收盘价买入。

问题所在:K 线收盘前无法确认收盘价。回测中用 60,000 USDT 买入,但实盘只能在下一根开盘时以 60,200 成交,回测与实盘之间系统性存在价格滑移。

正确做法:信号在 T 根 K 线收盘后确认,T+1 开盘时成交(或使用 T+1 的开盘价作为入场价格)。

案例二:用全样本数据做特征标准化。

错误逻辑:将整段历史数据的最大值/最小值用于标准化某特征(如归一化到 [0,1])。

问题所在:这等同于在回测开始时就已知了「未来的最大值」,回测初期的信号实际上借用了未来信息。

正确做法:每个时间点 t 只用 t 时刻之前的数据做滚动标准化,如用 rolling(window).min/max 代替全样本 min/max。

案例三:财务数据的报告延迟。

在传统市场中,季报通常在季末后 30~60 天发布。使用季末时间戳的财务数据,实际上在回测中提前用到了尚未发布的数字。这在加密市场的链上数据中同样存在——部分链上指标(如 TVL、协议收入)有索引延迟,用到的时间戳可能比实际数据可得时刻早数小时。

系统性检测方法

虽然无法穷举所有前视偏差的来源,但有一个通用检验:在信号列和实际用于计算信号的数据列之间,显式标记每一步数据的「可得时间」(Event Time vs. Knowledge Time),并在每个时间点 t 验证所有输入数据的可得时间均 < t。

加密市场陷阱

加密市场在几个地方比传统市场更容易引入前视偏差:


数据泄露(Data Leakage)

定义与和前视偏差的区别

数据泄露是前视偏差的广义延伸,但更多发生在特征工程和模型训练阶段,而非单纯的时间错位。两者的区别在于:前视偏差通常是「用了未来的价格/信号」,而数据泄露可能发生在标签构造、特征选择、数据预处理的任何环节,且往往更隐蔽,连有经验的研究者也容易中招。

典型案例

案例一:用未来收益构造训练标签,但特征包含当期收益的衍生量。

例如:标签 = 未来 5 日收益是否为正;特征之一 = 当日 RSI(RSI 依赖当日收盘价计算)。

如果当日收盘价已经包含了「今日涨跌」的信息,而标签是「未来 5 日」,表面上没有前视,但当日 RSI 与未来 5 日收益之间的相关性部分来自于「今日强势行情的短期延续效应」这一真实规律,也部分来自于特征和标签共同依赖「今日收盘价」的泄露。这类泄露很难靠直觉识别,需要严格的特征-标签时间对齐审查。

案例二:在整个数据集上做特征选择,再划分训练/测试集。

错误流程:先对全量数据计算各特征与标签的相关性 → 筛选出相关性最高的 20 个特征 → 再划分训练集/测试集 → 在训练集上训练 → 在测试集上评估。

问题所在:特征选择阶段已经「看到」了测试集的数据,被选中的特征在测试集上的相关性被系统性高估。正确做法是特征选择必须在训练集内部完成,测试集对特征选择过程完全不可见。

案例三:跨标的的信息泄露。

在多标的策略中,若用「全市场」的统计数据(如当日所有代币的平均收益)作为某标的的特征,而该标的本身是全市场的组成部分,则该特征隐含了标的自身的当日信息,构成循环泄露。正确做法是用排除目标标的之外的其他标的计算市场均值。

检测与防范

最有效的防范是严格的 Pipeline 化:将数据划分放在特征工程之前,确保所有 fit(拟合)操作只在训练集上发生,transform(变换)才应用于测试集。以 sklearn 为例,Pipeline + cross_val_score 的组合强制保证了这一点——任何在 Pipeline 外部发生的 fit 都应被视为潜在泄露风险。

另一个实用检验:训练集与测试集的性能差距。如果训练集 Sharpe 为 3.5 而测试集为 0.2,除过拟合外,数据泄露是首要怀疑对象。


过拟合(Overfitting)与数据窥探(Data Snooping)

过拟合的定义

过拟合是指策略参数在历史数据上被调整得过于精细,以至于「记住」了历史噪声而非捕捉到真实规律,导致样本内(In-Sample)表现优异、样本外(Out-of-Sample)表现大幅下滑。

成因:多重假设检验(Multiple Hypothesis Testing)

每一次「改参数 → 重跑回测」的操作,在统计上相当于做一次假设检验:H₀「该参数组合无效」,若回测 Sharpe 高于某阈值则拒绝 H₀。

当你做了 N 次这样的检验,在显著性水平 α = 0.05 下,即使所有策略均无效,期望会有 N × 0.05 次「随机」通过检验。回测 100 组参数,平均有 5 组纯靠运气看起来有效。

这意味着:回测的「最优参数」总是被选择偏差系统性抬高了,Sharpe 越高、试验的参数组越多,选择偏差越严重。

Data Snooping(数据窥探)

Data Snooping 是过拟合在研究流程层面的对应概念,描述的是一种更宏观的偏差:研究者反复使用同一批数据验证不同假设,导致最终「发现」的规律实际上是对这批特定数据的记忆,而非可泛化的市场规律。

与单次回测的过拟合不同,Data Snooping 的危险在于它往往横跨多个策略、多个研究者、甚至多篇学术论文。学术界有一个著名现象叫**「因子动物园」(Factor Zoo)**:金融学文献中记录了数百个能预测股票收益的因子,但其中大量因子被认为是对同一批历史数据反复挖掘的产物,而非真实的风险溢价来源。

在量化交易实践中,Data Snooping 的具体表现包括:

防范 Data Snooping 的核心原则:在开始任何数据分析之前,**预先注册(Pre-registration)**研究假设和测试方案。将测试集封存,直到策略开发完全结束才解封使用一次。这在学术界已逐渐成为规范,在量化实践中也应当贯彻。

量化诊断

① 参数敏感性分析(Robustness Check)

在核心参数的合理范围内逐步变化,绘制「参数 → 样本外 Sharpe」曲线:

示例:MA 周期 = 20 时样本外 Sharpe = 2.5,但在 18 或 22 时 Sharpe < 0.3,则极大可能是历史噪声拟合,而非真实信号。

② 样本外 / 样本内收益比(OOS/IS Ratio)

OOS Sharpe / IS Sharpe。比值接近 1.0 说明策略泛化能力强;< 0.5 存在明显过拟合;比值为负则策略只对历史数据有效。该比值受样本长度影响,样本外数据越长、比值越有参考价值。

③ Deflated Sharpe Ratio(DSR)

Bailey & López de Prado 给出了在做了 N 次独立试验后、纯靠运气能达到的期望最大 Sharpe 的解析估计(近似服从极值分布):

SRexpected(1γe)Z1 ⁣(11N)+γeZ1 ⁣(11Ne)SR^*_{expected} \approx (1 - \gamma_e) \cdot Z^{-1}\!\left(1 - \frac{1}{N}\right) + \gamma_e \cdot Z^{-1}\!\left(1 - \frac{1}{Ne}\right)

其中 γe0.5772\gamma_e \approx 0.5772 为 Euler–Mascheroni 常数,Z1Z^{-1} 为标准正态分位函数,N 为试验次数。将这个「及格线 SR*」代入 PSR 公式,得到 DSR:DSR > 0.95 才认为扛得住多重检验。回测试验次数越多、及格线越高,这迫使策略开发者保持对试验次数的记录与节制。

实践建议:从开始研究起就记录每一次参数试验(哪怕是「随手试了一下」),最终用总试验次数 N 计算 DSR,而不是只用「正式」的试验次数。

常见的过拟合来源


幸存者偏差(Survivorship Bias)

定义

只用当前仍在交易的标的做回测,忽略了已退市、归零或被交易所下架的标的,导致结果被系统性高估。

偏差量级的直觉估算

幸存者偏差的影响往往被低估。一个粗略的量化方法是对比两组回测:一组使用「当前活跃标的的完整历史」,另一组使用「该历史起点时存在的所有标的(含后来退市者)」,两组 Sharpe 之差即为幸存者偏差的近似量级。

在学术研究中,有人估算美国股市幸存者偏差导致年化收益率高估约 1~2 个百分点。加密市场的情况更严峻:

幸存者偏差与前视偏差的叠加

山寨币轮动策略中,幸存者偏差和前视偏差往往同时出现:只对「还在线的主流山寨」回测,等同于默认事先知道了哪些币会活下来(幸存者偏差)且隐含地知道了它们未来的走势(前视偏差)。两者叠加,策略的样本内 Sharpe 可以被虚高到完全不可信的程度。

处理方法

理想情况:使用包含已退市标的的完整历史数据集。部分数据供应商(如 Kaiko、CryptoCompare 的历史档案)提供了已下架代币的历史行情,但覆盖率和质量参差不齐,使用前需仔细核查。

退而求其次:若无法获取退市数据,至少要在策略假设中明确说明结果被幸存者偏差高估,根据历史退市率(可通过样本起点时的标的总数估算)对预期收益做保守折扣,并对策略结论保持克制。


样本划分与 Walk-forward Test

样本划分原则

将历史数据划分为三个不重叠的集合:

最常见的错误是:开发过程中反复查看测试集结果、据此修改策略——这等同于用测试集做了隐性调参,样本外已形同样本内。

Walk-forward Test(前进测试)

Walk-forward 用滚动窗口模拟「以历史调参 → 在下一段验证 → 向前滚动」的过程,是获得多段真实样本外结果的标准方法。

具体步骤(以 24 个月历史数据、每步滚动 1 个月为例):

  1. 用月 1~12 做样本内调参,在月 13 做样本外测试;
  2. 用月 2~13 做样本内调参,在月 14 做样本外测试;
  3. 依此滚动,共产生 12 个月的样本外收益序列。

将 12 段拼接的样本外净值曲线作为策略的最终评估依据,计算其 Sharpe、MDD 等指标。

稳健性要求:12 段中应有 ≥ 8 段盈利,且盈利不高度集中于某一特定市场状态(如全部盈利来自牛市、熊市下全部亏损,则策略本质上只是 beta 暴露,而非 alpha)。

定点法 vs. 滑动法

Walk-forward 有两种变体:

加密市场由于市场结构变化快(监管、机构入场、衍生品成熟),通常优先使用滑动法,避免过早期结构截然不同的数据主导模型。


手续费与滑点建模

手续费分层

以 Binance 永续合约为例(实际费率以官网为准):

等级MakerTaker
普通0.020%0.050%
VIP10.016%0.040%
VIP9-0.005%0.017%

回测时应按实际所在等级双边计入手续费,而非使用最高费率或忽略。对于高频策略(日内交易数百次),手续费往往是策略正负的决定性因素;对于低频策略(每月数笔),影响相对较小但仍需计入。

滑点建模方法

① 固定滑点:每笔成交额外加减固定 bps(如 2 bps = 0.02%)。简单、保守,适合低频策略粗估,但无法反映市场深度和成交规模的关系。

② 比例滑点(深度模型)

滑点成交量当档挂单量×档位间距\text{滑点} \approx \frac{\text{成交量}}{\text{当档挂单量}} \times \text{档位间距}

适用于有订单簿快照数据的回测,能更真实模拟大单穿透多个档位的冲击。需要注意订单簿数据本身的质量问题(见「流动性幻觉」)。

③ 平方根冲击成本模型(Square-root Impact Model)

市场冲击σQADV\text{市场冲击} \approx \sigma \cdot \sqrt{\frac{Q}{ADV}}

其中 σ\sigma 为日波动率,QQ 为单笔成交量,ADVADV 为标的日均成交量。该模型来自传统市场的大量实证研究(Almgren et al.),核心假设是市场冲击与成交量占比的平方根成正比,而非线性正比——直觉上,大单冲击存在「规模不经济」,越大的单子对市场的单位冲击越大。

假设与适用边界

示例:策略单笔成交 50 万 USDT,BTC 当日 ADV = 5 亿 USDT,日波动率 2%。

市场冲击2%×505亿2%×0.0320.064%\text{市场冲击} \approx 2\% \times \sqrt{\frac{50\text{万}}{5\text{亿}}} \approx 2\% \times 0.032 \approx 0.064\%

叠加 Taker 手续费(约 0.05%),合计单边成本约 0.114%,双边约 0.23%

加密市场陷阱


策略容量(Strategy Capacity)

定义

策略容量是指在不显著损害策略收益的前提下,策略所能承载的最大资金规模。容量是从研究到实盘最常被忽视的断层:一个在 1 万 USDT 上年化 80% 的策略,放大到 100 万 USDT 可能年化只剩 15%,放大到 1000 万可能直接亏损——因为自身的成交行为已经成为价格移动的主要原因。

容量限制的来源

① 市场冲击(Market Impact):成交规模增大,滑点非线性上升(见平方根模型)。单笔成交占 ADV 的比例越高,自身对价格的推动越不可忽视。

② 信号的可扩展性(Signal Scalability):部分信号本身依赖于「在别人发现之前入场」,一旦资金规模大到自身即是市场的一部分,信号优势天然消失。这在统计套利、跨期价差、小市值山寨轮动等策略中尤为明显。

③ 流动性时段的集中度:策略若集中在特定时段成交(如开盘或收盘),大资金在该时段的单边成交压力会进一步推高冲击成本。

容量的估算方法

粗略估算:通常认为单笔成交量不应超过目标标的同时段 ADV 的 1%~5%,超过这一比例后市场冲击开始显著。据此可反推策略在单次信号下能部署的最大资金:

Qmax1% 5%×ADVQ_{\max} \approx 1\%~5\% \times ADV

结合策略的日均信号频率和持仓周期,可以估算出总体可承载的资金规模上限。

精细估算:在回测框架中对不同资金规模分别建模滑点,绘制「资金规模 → 年化 Sharpe」的衰减曲线,找到 Sharpe 开始显著下滑的拐点,该点对应的资金规模即为实际容量上限的参考值。

加密市场陷阱


市场制度变迁(Regime Change)

定义

市场制度(Market Regime)是指驱动价格行为的底层结构——包括参与者构成、流动性水平、波动率特征、宏观关联性等。制度变迁是指这些底层结构发生了足够大的改变,使得在旧制度下有效的策略在新制度下不再有效,甚至产生系统性亏损。

回测中使用过长的历史数据,看似增加了样本量,实际上可能把来自截然不同的市场制度的数据混在一起训练,导致策略学到的是「两种制度的平均」——在任何单一制度下都表现平庸。

加密市场的主要制度转折点

加密市场由于历史短、演化快,制度变迁比传统市场更频繁和剧烈:

对回测的直接影响

① 用 2017~2019 年的数据做 Walk-forward,在 2023 年之后应用,等同于在一个不存在的市场结构上过拟合。 市场结构的变化不只是波动率的变化,而是价格发现机制、参与者行为、宏观联动方式的根本变化。

② 跨制度的长回测会掩盖策略的真实脆弱性。 一个策略在 2019~2023 年综合 Sharpe = 1.8,但如果拆开来看:牛市 Sharpe = 3.5,熊市 Sharpe = -0.5——这个策略实际上只是 beta 暴露,综合数字掩盖了真正的风险。

制度识别与应对方法

① 分制度单独评估:在 Walk-forward 的结果分析中,明确标注每段样本外区间对应的市场制度(牛市/熊市/震荡/极端事件),要求策略在多种制度下均有正收益,而非只在某一制度下表现优秀。

② 滚动相关性监控:将策略收益与 BTC 收益的滚动相关系数作为制度切换的实时信号。若相关系数从接近 0 突然跳升到 0.8,说明策略退化为 beta 暴露,需重新评估。

③ 设定数据有效期:在策略部署后设置「数据有效期」——超过某一历史时间点的数据不再纳入参数更新。加密市场建议将训练数据的起点不早于 2020 年(DeFi Summer 之后),以确保数据代表当前市场结构。

④ 制度感知模型(Regime-aware Model):将市场制度作为显式特征输入模型(如用波动率均值、BTC-纳斯达克相关性等指标识别当前制度),对不同制度分别训练子策略,或在制度切换时动态调整仓位比例。这是从「一个模型走天下」到「因势而变」的关键工程升级。


数据质量检查

在开始任何回测前,原始数据的质量问题会直接影响结论可信度,且往往比策略逻辑问题更难发现。

基础检查清单


加密市场特有的回测陷阱(汇总)


回测可信度自查清单