你刚刚重新跑了 BTC 永续策略,发现净 Sharpe 下降了三分之一。信号完全相同,成交也完全相同。你只改了一件事:现在手续费方案按账户过去 30 天的交易量计算,而测试开始时的账户等级低于你在实盘中达到的等级。
在重写信号之前,先把两个问题分开:这套策略按固定费率交易要支付多少手续费?这个账户在每个时点实际适用的费率又是多少?这是两种不同的实验。把它们混在一起,可能会让策略显得更好,因为它交易量足够大,拿到了折扣;随后又把这项折扣当成了理所当然。
从费率表开始,而不是只看一个费率
多数交易所的手续费页面都会列出一张表:按交易量等级划分的 maker 和 taker 费率,有时现货和衍生品还适用不同规则。回测需要用到实际费率方案,以及决定账户等级的规则。交易量按过去 30 天计算吗?按自然月计算吗?交易所会把现货和期货交易量合并吗?持有代币带来的折扣能否叠加在交易量等级优惠上?
把这些规则记录为带日期的输入。举个简化例子,假设某交易平台根据此前 30 天的期货成交量,决定次日适用的费率:
| 过去 30 天交易量 | Maker 费率 | Taker 费率 |
|---|---|---|
| 低于 $1 million | 0.020% | 0.050% |
| $1 million 至 $10 million | 0.016% | 0.040% |
| 高于 $10 million | 0.012% | 0.035% |
以上数字仅作示例;交易所的费率表和资格规则都可能变化。关键在于生效时间:昨天的成交可能影响明天的费率,但今天的成交不能追溯享受今天的折扣。
回测账户需要有交易量历史
假设你的策略每天换手 $80,000,且全部是 taker 成交。在入门等级下,一次 $100,000 的完整往返交易成本约为 $50:进场和平仓的名义成交额合计 $100,000,再乘以 0.050%。中间等级下则是 $40。每次相差 $10 看起来不多,但如果你做了 800 次往返交易呢?那么整个测试期间就相差 $8,000,而且费率等级可能正是被这些交易带来的交易量改变的。
这种反馈确实存在,但也容易造成建模陷阱。如果因为策略在回测结束时达到了中间等级,就把回测账户初始化为该等级,你就把未来的账户活动泄漏到了过去。应先声明一项初始历史交易量,在每笔符合条件的成交后更新滚动窗口,并且只在交易所规则规定的生效时间应用等级变化。
把以下三项分开记录:策略名义交易额、符合等级计算条件的账户交易量,以及每笔成交实际收取的手续费。如果交易所排除某些产品、对某些交易只计一侧交易量,或根据你尚未纳入模型的余额提供折扣,这些数值可能并不相同。
在账户感知回测旁边跑一组固定费率测试
你需要两组结果。第一组,用一个偏保守的固定 taker 费率重跑完整策略。这样可以衡量策略对执行成本有多敏感,同时避免策略自身的换手改变比较基准。第二组,按有记录的初始余额和交易量历史运行账户感知费率方案,估算这个特定账户在所述规则下可能经历的变化路径。
然后比较手续费总额、换手、净 P&L 和回撤。如果只有账户感知测试有所改善,就要追问:改善中有多少来自合理的等级变更,又有多少依赖初始历史、跨产品交易量,或账户可能无资格享受的折扣?如果两组测试的优势都消失了,费率等级大概不是核心问题。
也别让 maker 成交套用最优惠费率,同时你的成交模型却悄悄假设每笔被动挂单都能成交。手续费方案可以算得一清二楚,成交假设却仍然脱离实际。这两项审查应分开进行。
让结果可复现
将费率方案版本、等级回溯周期、重置时间、符合条件的产品和初始交易量一并保存到回测记录中。再附上一份简短的每日台账:滚动交易量期初值、新增成交、适用等级和已收手续费。交易所调整费率后,如果回测结果发生变化,你就能判断究竟是策略变了、账户路径变了,还是假设变了。
你要回答的是一个范围明确且有用的问题:在一套你能清楚说明、并且账户历史真实可信的手续费规则下,这个策略实际支付了多少手续费?如果你无法还原某一天适用的等级,就还无法确定回测净结果意味着什么。
← 全部文章


