二、回测方法论
前视偏差、数据泄露、过拟合、幸存者偏差、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。
加密市场陷阱
加密市场在几个地方比传统市场更容易引入前视偏差:
- 逐笔成交(Tick)数据回测:若不区分 bid-initiated 和 ask-initiated,成交方向本身就含有前视信息;
- 永续合约资金费率:资金费率在结算时刻才确定,回测不能提前用「当期最终费率」计算损益;
- 交易所 API 的 K 线修正:部分交易所会在历史数据中修正价格错误,导致「历史」数据与当时可得的实时数据不同。
数据泄露(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 的具体表现包括:
- 看到某策略在 2020~2023 年表现好,就针对这段时间调参,而非事先定义好的样本外区间;
- 读了大量策略文献后,「带着答案」去验证——潜意识中已经知道哪些参数范围「应该有效」;
- 在公开数据集(如 Kaggle 竞赛数据)上开发策略时,公开排行榜本身就构成了对测试集的间接窥探。
防范 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 的解析估计(近似服从极值分布):
其中 为 Euler–Mascheroni 常数, 为标准正态分位函数,N 为试验次数。将这个「及格线 SR*」代入 PSR 公式,得到 DSR:DSR > 0.95 才认为扛得住多重检验。回测试验次数越多、及格线越高,这迫使策略开发者保持对试验次数的记录与节制。
实践建议:从开始研究起就记录每一次参数试验(哪怕是「随手试了一下」),最终用总试验次数 N 计算 DSR,而不是只用「正式」的试验次数。
常见的过拟合来源
- 参数过多:每增加一个自由参数,策略可以「解释」更多历史噪声;
- 优化目标是 IS Sharpe:等同于直接把噪声最大化;
- 人工干预触发信号细节(如「在回撤超过 3.7% 时加仓」而非整数门槛);
- 使用复杂的机器学习模型而样本量不足:参数量与样本量之比是关键。
幸存者偏差(Survivorship Bias)
定义
只用当前仍在交易的标的做回测,忽略了已退市、归零或被交易所下架的标的,导致结果被系统性高估。
偏差量级的直觉估算
幸存者偏差的影响往往被低估。一个粗略的量化方法是对比两组回测:一组使用「当前活跃标的的完整历史」,另一组使用「该历史起点时存在的所有标的(含后来退市者)」,两组 Sharpe 之差即为幸存者偏差的近似量级。
在学术研究中,有人估算美国股市幸存者偏差导致年化收益率高估约 1~2 个百分点。加密市场的情况更严峻:
- 2017~2018 年 ICO 浪潮期间发行的代币,超过 90% 在此后数年内归零或交易量枯竭至无法回测;
- 以「当前 Binance 上架的 Top 100 山寨币」为回测标的池,这 100 个币本身就是从数千个候选者中「活下来」的,等同于事先知道了它们能活到回测结束日;
- 部分交易所会将历史低流动性交易对的数据整体删除,只保留「活跃」交易对的历史——数据源本身已经完成了一次幸存者筛选。
幸存者偏差与前视偏差的叠加
山寨币轮动策略中,幸存者偏差和前视偏差往往同时出现:只对「还在线的主流山寨」回测,等同于默认事先知道了哪些币会活下来(幸存者偏差)且隐含地知道了它们未来的走势(前视偏差)。两者叠加,策略的样本内 Sharpe 可以被虚高到完全不可信的程度。
处理方法
理想情况:使用包含已退市标的的完整历史数据集。部分数据供应商(如 Kaiko、CryptoCompare 的历史档案)提供了已下架代币的历史行情,但覆盖率和质量参差不齐,使用前需仔细核查。
退而求其次:若无法获取退市数据,至少要在策略假设中明确说明结果被幸存者偏差高估,根据历史退市率(可通过样本起点时的标的总数估算)对预期收益做保守折扣,并对策略结论保持克制。
样本划分与 Walk-forward Test
样本划分原则
将历史数据划分为三个不重叠的集合:
- 训练集(Training / IS):用于策略开发和初步调参,通常占 60%~70%;
- 验证集(Validation):在开发中用于超参调整,防止直接在测试集上过拟合,通常占 10%~20%;
- 测试集(Test / OOS):从不参与任何调参决策,只用于最终一次性评估。一旦用测试集看过结果再修改策略,它就变成了另一个验证集,失去了无偏性。
最常见的错误是:开发过程中反复查看测试集结果、据此修改策略——这等同于用测试集做了隐性调参,样本外已形同样本内。
Walk-forward Test(前进测试)
Walk-forward 用滚动窗口模拟「以历史调参 → 在下一段验证 → 向前滚动」的过程,是获得多段真实样本外结果的标准方法。
具体步骤(以 24 个月历史数据、每步滚动 1 个月为例):
- 用月 1~12 做样本内调参,在月 13 做样本外测试;
- 用月 2~13 做样本内调参,在月 14 做样本外测试;
- 依此滚动,共产生 12 个月的样本外收益序列。
将 12 段拼接的样本外净值曲线作为策略的最终评估依据,计算其 Sharpe、MDD 等指标。
稳健性要求:12 段中应有 ≥ 8 段盈利,且盈利不高度集中于某一特定市场状态(如全部盈利来自牛市、熊市下全部亏损,则策略本质上只是 beta 暴露,而非 alpha)。
定点法 vs. 滑动法
Walk-forward 有两种变体:
- 定点法(Anchored):训练集起点固定,每步只延长终点(窗口越来越长)。优点:利用了所有可用历史;缺点:早期数据权重过大,模型可能对旧市场状态过拟合。
- 滑动法(Rolling):训练集长度固定,整体向前滚动(窗口大小不变)。优点:对最近数据更敏感,更贴近策略实际衰减;缺点:丢弃了远期历史数据。
加密市场由于市场结构变化快(监管、机构入场、衍生品成熟),通常优先使用滑动法,避免过早期结构截然不同的数据主导模型。
手续费与滑点建模
手续费分层
以 Binance 永续合约为例(实际费率以官网为准):
| 等级 | Maker | Taker |
|---|---|---|
| 普通 | 0.020% | 0.050% |
| VIP1 | 0.016% | 0.040% |
| VIP9 | -0.005% | 0.017% |
回测时应按实际所在等级双边计入手续费,而非使用最高费率或忽略。对于高频策略(日内交易数百次),手续费往往是策略正负的决定性因素;对于低频策略(每月数笔),影响相对较小但仍需计入。
滑点建模方法
① 固定滑点:每笔成交额外加减固定 bps(如 2 bps = 0.02%)。简单、保守,适合低频策略粗估,但无法反映市场深度和成交规模的关系。
② 比例滑点(深度模型):
适用于有订单簿快照数据的回测,能更真实模拟大单穿透多个档位的冲击。需要注意订单簿数据本身的质量问题(见「流动性幻觉」)。
③ 平方根冲击成本模型(Square-root Impact Model):
其中 为日波动率, 为单笔成交量, 为标的日均成交量。该模型来自传统市场的大量实证研究(Almgren et al.),核心假设是市场冲击与成交量占比的平方根成正比,而非线性正比——直觉上,大单冲击存在「规模不经济」,越大的单子对市场的单位冲击越大。
假设与适用边界:
- 假设市场流动性在成交期间基本稳定,不适用于极端行情(如暴跌时订单簿快速撤单);
- ADV 需使用近期真实数据,不可用含刷量的数字;
- 适合容量估算,即估算策略在多大资金规模下滑点开始显著侵蚀收益,而非精确预测单笔滑点。
示例:策略单笔成交 50 万 USDT,BTC 当日 ADV = 5 亿 USDT,日波动率 2%。
叠加 Taker 手续费(约 0.05%),合计单边成本约 0.114%,双边约 0.23%。
加密市场陷阱
- 流动性幻觉:CEX 订单簿中部分挂单来自做市商,真实大单成交会触发做市商快速调仓,实际滑点高于快照中可见的挂单量计算结果;
- API 延迟:从信号产生到订单到达交易所,中间存在毫秒到秒级的延迟。高频策略回测中不建模延迟,等同于默认无延迟成交,会系统性高估收益;
- 成交量数据水分:部分交易所历史成交量存在刷量,用于估算 ADV 的数据本身不可靠,需使用主流交易所(Binance、OKX)或聚合数据源。
策略容量(Strategy Capacity)
定义
策略容量是指在不显著损害策略收益的前提下,策略所能承载的最大资金规模。容量是从研究到实盘最常被忽视的断层:一个在 1 万 USDT 上年化 80% 的策略,放大到 100 万 USDT 可能年化只剩 15%,放大到 1000 万可能直接亏损——因为自身的成交行为已经成为价格移动的主要原因。
容量限制的来源
① 市场冲击(Market Impact):成交规模增大,滑点非线性上升(见平方根模型)。单笔成交占 ADV 的比例越高,自身对价格的推动越不可忽视。
② 信号的可扩展性(Signal Scalability):部分信号本身依赖于「在别人发现之前入场」,一旦资金规模大到自身即是市场的一部分,信号优势天然消失。这在统计套利、跨期价差、小市值山寨轮动等策略中尤为明显。
③ 流动性时段的集中度:策略若集中在特定时段成交(如开盘或收盘),大资金在该时段的单边成交压力会进一步推高冲击成本。
容量的估算方法
粗略估算:通常认为单笔成交量不应超过目标标的同时段 ADV 的 1%~5%,超过这一比例后市场冲击开始显著。据此可反推策略在单次信号下能部署的最大资金:
结合策略的日均信号频率和持仓周期,可以估算出总体可承载的资金规模上限。
精细估算:在回测框架中对不同资金规模分别建模滑点,绘制「资金规模 → 年化 Sharpe」的衰减曲线,找到 Sharpe 开始显著下滑的拐点,该点对应的资金规模即为实际容量上限的参考值。
加密市场陷阱
- 山寨币容量极小:部分中小市值山寨的日均成交量仅数百万 USDT,策略容量可能只有数万 USDT,回测中看似优秀的 Sharpe 在实盘中根本无法以有效规模复现;
- BTC/ETH 容量相对充裕:主流合约日均成交量达数十亿 USDT,但高频策略仍然会在千万级以上的规模面临容量压力;
- 容量随市场状态变化:熊市流动性收缩,同一策略的实际容量可能仅为牛市期间的 20%~30%,不可用牛市 ADV 估算熊市容量。
市场制度变迁(Regime Change)
定义
市场制度(Market Regime)是指驱动价格行为的底层结构——包括参与者构成、流动性水平、波动率特征、宏观关联性等。制度变迁是指这些底层结构发生了足够大的改变,使得在旧制度下有效的策略在新制度下不再有效,甚至产生系统性亏损。
回测中使用过长的历史数据,看似增加了样本量,实际上可能把来自截然不同的市场制度的数据混在一起训练,导致策略学到的是「两种制度的平均」——在任何单一制度下都表现平庸。
加密市场的主要制度转折点
加密市场由于历史短、演化快,制度变迁比传统市场更频繁和剧烈:
- 2017~2018 年 ICO 浪潮与崩溃:散户投机主导、监管真空、链上基本面几乎无效;
- 2020 年 DeFi Summer 与机构入场:链上流动性大幅提升、机构资金开始系统性配置 BTC,BTC 与纳斯达克的相关性从近零上升到 0.5~0.7;
- 2021 年永续合约衍生品成熟:资金费率套利、期现套利等策略的容量和竞争程度质变;
- 2022 年 LUNA 崩溃与 FTX 破产:极端去杠杆事件,信用风险与流动性危机叠加,与历史任何样本都不同;
- 2024 年比特币 ETF 获批:机构渠道正式开放,BTC 的投资者结构和流动性特征再次发生结构性变化。
对回测的直接影响
① 用 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-纳斯达克相关性等指标识别当前制度),对不同制度分别训练子策略,或在制度切换时动态调整仓位比例。这是从「一个模型走天下」到「因势而变」的关键工程升级。
数据质量检查
在开始任何回测前,原始数据的质量问题会直接影响结论可信度,且往往比策略逻辑问题更难发现。
基础检查清单:
- 时间戳连续性:K 线是否存在意外跳空(非节假日、非主动跳空);
- 价格异常:高低价是否存在明显离群点(如某根 K 线低点远低于相邻 K 线,疑似交易所闪崩或数据错误);
- 成交量异常:是否存在成交量连续为零的时段(数据缺失)或异常高峰(刷量);
- 精度问题:价格精度是否与实际交易精度一致,避免因精度损失引入系统性偏差;
- 来源一致性:历史数据来源与实盘使用的数据源是否相同,不同来源的价格可能存在 0.01%~0.1% 的系统偏差,足以影响高频策略结论。
加密市场特有的回测陷阱(汇总)
- 市场结构突变:参见「市场制度变迁」节;2020 年前后机构入场、永续合约衍生品成熟,使得 2018 年之前的数据参考价值有限。
- 资金费率的非平稳性:永续合约资金费率在不同市场状态下均值差异极大(牛市长期正费率、熊市大幅负费率),含资金费率收入的策略需分市场状态单独评估。
- 流动性的时区性:亚洲交易时段与欧美交易时段的流动性差异显著,依赖特定时段流动性的策略需在回测中按时段建模,而非使用全天均值。
- 链上数据延迟:使用链上指标(如 TVL、巨鲸转账)时,需确认数据可得时间早于信号触发时间,避免前视偏差。
- 山寨币容量陷阱:中小市值标的的容量限制极为严苛,策略在小资金回测中的 Sharpe 无法在实盘规模下复现。
- 幸存者偏差叠加:加密市场退市率极高,不含退市标的的回测结果被系统性高估,且高估幅度远超传统市场。
回测可信度自查清单
- 信号时刻与成交时刻是否对齐(无前视偏差)
- 特征标准化是否使用滚动窗口(无全样本前视)
- 特征选择是否在训练集内部完成(无数据泄露)
- 手续费是否按实际等级双边计入
- 滑点是否合理建模(含 API 延迟)
- 测试集是否严格保留、未被用于任何调参决策
- 参数敏感性是否经过扰动测试
- Walk-forward 的多段样本外结果是否均稳定盈利
- 回测是否覆盖牛市、熊市、震荡多种市场状态
- 是否使用了包含退市标的的完整数据集(幸存者偏差)
- PSR / DSR 是否通过显著性检验(记录总试验次数 N)
- 策略容量是否经过估算,实盘规模是否在容量范围内
- 回测数据是否限定在当前市场制度的有效区间内