做加密回测最常踩的几个坑:look-ahead、流动性失真、fee 错算到底怎么避
写策略的人多,写靠谱回测的人少。我见过太多"夏普 4 以上"的曲线在实盘第一周就把回撤打到 -30%,原因几乎都不是策略本身的 alpha 消失了,而是回测撒了谎。撒谎的方式高度雷同——绕来绕去就是三类:前视偏差、流动性失真、手续费错算。这一篇把这三类坑掰开讲清楚,并配一份我自己每写完一份回测就要走一遍的自检清单。

坑一:look-ahead bias,最隐蔽也最致命
**前视偏差(look-ahead bias)**指策略在 t 时刻使用了 t 时刻之后才能拿到的信息。它隐蔽在于:你回测代码里没有任何一行写"用未来",但数据结构本身就泄露了未来。
最经典的几种泄露方式:
- K 线收盘价信号、收盘价成交:用一根 5 分钟 K 线的 close 计算指标后,立刻按这根 K 线的 close 下单。实盘里 close 形成那一瞬间你已经错过了,下一个 tick 才能下单,价格通常已经偏离。
- 未来 fill 的指数/价格:用 CoinGecko 之类的"日聚合价"做日线策略,但这些聚合价的统计口径可能横跨次日 UTC 边界。
- 截至当前的 universe:用 2026 年的"市值前 50 名"列表去回测 2022 年——幸存者偏差,已经把死掉的币剔除了。
- 未来的资金费率:永续策略里,资金费率每 8 小时结算一次,但很多接口返回的是"该 8 小时区间的最终值",落进 t 时刻就等于你提前知道了 t+8 小时的事实。
识别方法只有一个原则:对每一个进入信号的字段,问"这个值在 t 时刻真的能拿到吗"。如果该字段的来源是"按区间聚合后的统计量",几乎都要怀疑。我推荐的做法是回测引擎里加一个 lag 参数,把所有指标计算结果默认推迟一根 bar 再生效,等你确认数据无泄露后再单独开启即时模式。
关于回测工具与方法论,我之前写过一篇 加密回测入门 可以作为前置阅读。
坑二:流动性失真,回测里你永远是市场之外的人
这是更隐蔽的一类,因为它不是"用错数据",而是"用对了数据,但忽略了你自己也是市场的一部分"。
回测里你按 mid price 或 last price 成交、不计 slippage、不考虑 orderbook 深度,于是策略在小盘币上跑出诱人收益。但是在实盘里:
| 情景 | 回测假设 | 实盘真实情况 |
|---|---|---|
| 小盘币 10 万美金市价单 | 按 mid 成交 | 吃掉 5 档卖盘,平均价上滑 0.8% |
| 大单分批 TWAP | 假设无影响 | 自己把价格打高,后续买价更差 |
| 流动性骤降时段(亚洲早 8 点) | 与平时一致 | 价差扩大 3 倍、深度减半 |
| 撤单/改单 | 瞬时执行 | 200ms 延迟,可能错过最优价 |
修复思路有两层:
- 简单层:按订单簿前 N 档累计深度模拟成交,超出深度的部分按"加权吃单价"成交;
- 进阶层:录制一段时间的 L2 行情(每 100ms 一次快照),回放时按时间戳推进,下单后查那一刻订单簿做模拟撮合,包括撤单/改单延迟。
对于做资金费率套利或网格这种持仓时间长、单笔影响小的策略,第一层就够了;对于做高频做市或剥头皮,必须做到第二层。可以对比 网格策略教程 里讲到的"持仓时间换深度"思路。
坑三:手续费、资金费率、借币利息——零碎但能吃掉全部利润
第三类坑技术上最简单,但栽倒的人最多,因为大家潜意识里觉得"手续费只是 0.04%,能差多少"。差很多。
来算一笔细账。假设你做一个高频网格,单边手续费 maker -0.005%、taker 0.04%,每天换手 10 次(即一买一卖共 20 笔)。回测里你随手用 0.04% × 20 = 0.8% 当作日手续费,看起来"已经算了费"。但实盘里:
- 你的单子未必全是 maker,假设 maker 命中率 60%、taker 40%;
- maker 成交不一定能拿到返佣(部分交易所阶梯返佣 + 月度结算);
- 资金费率每 8 小时一次,多空两边都要算,正资金费率时空头收到、多头付出;
- 借币做空有借币利率,跨所搬砖还有提币 gas 费、链桥手续费。
一份靠谱的回测,至少要把这些字段独立建模:
maker_fee/taker_fee:按交易所阶梯档位读取,能拿到 VIP 折扣也单独标注;funding_rate:从历史接口读取真实结算值(注意时区与结算窗口),不是凭空填均值;borrow_rate:永续 + 现货做空的借币年化,按持仓时间复利;withdrawal_fee/bridge_fee:搬砖类策略必须按链按币种枚举。
我自己的习惯是回测同时输出"毛收益 / 净收益"两条曲线——毛收益看 alpha,净收益看可执行性。如果两条曲线差距超过 30%,这个策略大概率不能直接上实盘。关于资金费率结算的细节,资金费率永续合约入门 有更系统的拆解。
一份每次回测都要走一遍的自检清单
把上面三类坑落到具体可勾选的项目,下面这份清单我每写完一份回测都会过一遍:
- [ ] 所有指标信号是否至少滞后一根 bar 才生效
- [ ] universe 是否使用"对应回测时间点"的真实成分,而不是当前成分
- [ ] 资金费率/funding 是否使用"已结算值"而不是"区间聚合"
- [ ] 是否按订单簿深度模拟,而不是 mid/last 一口价
- [ ] 撤单/改单是否带 100-300ms 延迟
- [ ] maker/taker 比例是否单独建模,而不是统一 taker
- [ ] 跨所策略是否计入提币/桥接费 + 到账时间
- [ ] 是否输出毛收益、净收益两条曲线,差异在合理区间
- [ ] 是否做过 walk-forward / 不重叠样本外验证,而不是单次切一刀
- [ ] 同一策略换 3 个不同时间段(牛/熊/盘整)是否依然稳定
走完这份清单还能保留 60% 收益的策略,再考虑投入资金。回测不是为了让自己开心,回测是为了把上线那一刻的"惊喜"提前到本地发生。这一步不省,比省下来再被实盘上一课要便宜得多。
把回测当成一面镜子,而不是一份证明
很多人写回测的心态是"证明我的策略能赚钱",所以下意识地会去做对自己有利的设定。换个心态:回测是用来照出策略弱点的镜子——如果一份回测怎么改参数都赚钱,那不是策略好,那是回测有问题。当回测开始让你失望——比如某个时间段彻底跑不通、某个币种完全失效——你才真的看清了策略的边界。守住边界,比追求高夏普重要得多。