2 秒粒度下的盘口陷阱
回测里最常见的三个「假收益」,全部来自把看到的价格当成了能成交的价格。
一、数据是 2 秒一条,不是逐笔
本站采集粒度为约 2 秒。你看到的 yes_ask = 0.75 是
某一瞬间的报价快照,不是「接下来 2 秒内你一定能成交的价格」。
实测中最危险的一类信号是「现货跳动瞬间触发的因子」:市场还没来得及重新报价, 那一刻的 ask 看起来非常便宜,回测里胜率漂亮得不像真的 —— 实际上那个价在成交前就消失了。
本站采集器对这一点做了显式统计:订单记录里带
ask_sz(对手盘挂单量)
与 fill_ok(挂单量是否 ≥ 想要的份数)。
真实数据里「记下来但那一侧挂单量不够」的订单数以万计 ——
它们全是纸面成交。
二、买价要用 ask,不是 mid
盘口校验通过时,两腿的 mid 之和约为 1.0。很容易顺手用 mid 当买价 —— 这是错的。 真实的一笔(本站模拟盘):
信号腿 mid = 0.66
实际成交价 ask = 0.67 ← 差 1 分(约 1.5%)
每股收益 = 1 − 0.67 − fee(0.67) = 0.3069
若误用 mid:1 − 0.66 − fee(0.66) = 0.3138 ← 凭空多出 2.2% 的收益
单笔 2% 看起来小,但它是系统性同向的偏差 —— 每一笔都偏,累计起来足以把 一个「看起来赚钱」的策略变成亏钱的。
三、手续费口径:0.07 × min(价格, 1−价格)
taker 手续费按成交价的两端距离计价,所以越接近 0.5 越贵:
| 买入价 | 每股手续费 | 盈亏平衡胜率 |
|---|---|---|
| 0.50 | 0.0350 | 53.5% |
| 0.70 | 0.0210 | 72.1% |
| 0.80 | 0.0140 | 81.4% |
| 0.90 | 0.0070 | 90.7% |
盈亏平衡胜率 = 价格 + 手续费。买得越贵,需要的胜率越高 ——
「高价位高胜率」并不自动等于赚钱。
本站自己的算例:同一策略同一批窗口,不算手续费时每股 EV 是正的,
算上手续费后直接变成 −0.0052(基本打平)。
手续费不是「最后再减一下」的修饰项,它经常就是结论本身。
四、盘口校验:脏盘口要整拍丢掉
数据里有一个 book_one_sided 标记。判据是:
两腿 mid 之和偏离 1.0 超过 0.05,或某一侧缺边(只有 bid 没有 ask)。
- 缺边时不要 fail-open(不要「缺一边就按另一边算」)—— 直接不做这一拍;
- 窗口末尾尤其常见:市场已经定了,做市商撤单,盘口变空 ——
这时你会看到
yes_bid = null之类的字段。
五、回测自查清单
- 买价是否用了 ask(而不是 mid / last)?
- 是否扣了 taker 手续费,且按
0.07×min(p,1−p)逐笔算? - 是否按
ask_sz过滤了成交不了的那些单? - 是否丢弃了
book_one_sided的拍? - 是否把「窗口里最后一秒的价」当成了可成交价?(撤单高发时段)
- 胜率是否高于盈亏平衡胜率?高多少?样本量够不够(看 t 值,不看胜率本身)?