1. 回测标签口径概述
1.1 什么是回测标签口径
在量化回测中,标签口径(Label Caliber)是指对交易信号、价格行为或时间窗口进行标准化定义的规则集合。它决定了回测引擎如何理解“买入”“卖出”“持仓”“止损”等动作的触发条件与生效边界。
简单来说,标签口径就是回测系统内部使用的统一语言。如果策略代码使用一种口径,而回测框架(如 Backtrader)默认使用另一种口径,就会产生信号错位,导致回测结果失真。
核心观点:标签口径是回测可信度的基石。口径不一致,回测结果就是“垃圾进,垃圾出”。
1.2 为什么需要校准
回测标签口径校准的必要性体现在以下三个层面:
| 层面 | 问题描述 | 后果 |
|---|---|---|
| 时间对齐 | 策略信号生成时刻与订单执行时刻存在延迟 | 滑点估计错误,胜率虚高 |
| 价格匹配 | 信号使用收盘价,但成交使用开盘价或均价 | 盈亏计算偏差,夏普比率失真 |
| 信号语义 | 不同策略对“买入”的定义不同(如突破 vs 回调) | 多策略组合时信号冲突,无法统一评估 |
常见误区:很多初学者认为“只要回测结果漂亮就行”,忽略了口径校准。这会导致实盘时策略表现与回测结果出现巨大落差。
1.3 常见口径类型
回测标签口径主要分为三大类:时间口径、价格口径和信号口径。下面通过一张结构图展示它们之间的关系:
1.4 三种口径详解
1.4.1 时间口径
时间口径定义了信号生成时刻与订单执行时刻之间的映射关系。Backtrader 中常见的时间口径问题包括:
- K线闭合时刻:信号是在 K 线收盘时生成,还是在 K 线运行过程中生成?
- 信号延迟窗口:从信号生成到订单提交,是否允许跨 K 线延迟?
- 回测时间戳:使用交易所时间还是本地时间?是否考虑时区差异?
Backtrader 默认行为:信号在 next() 方法中被触发时,默认使用当前 K 线的收盘价作为成交价。这属于“收盘时刻成交”口径,与实盘中的“信号触发后立即成交”存在差异。
1.4.2 价格口径
价格口径决定了回测中以什么价格成交。不同价格口径会导致完全不同的回测结果:
| 价格口径 | 描述 | 适用场景 | 风险 |
|---|---|---|---|
| 收盘价口径 | 以 K 线收盘价作为成交价 | 日线级别、低频策略 | 忽略盘中滑点 |
| 开盘价口径 | 以下一根 K 线开盘价成交 | 隔夜策略、跳空敏感策略 | 跳空风险被放大 |
| 均价口径 | 以 K 线 VWAP 或 TWAP 成交 | 大资金、算法交易 | 计算复杂度高 |
| 滑点模拟口径 | 在基准价上加减固定滑点或百分比滑点 | 高频率、小资金策略 | 滑点参数需校准 |
1.4.3 信号口径
信号口径定义了策略信号的语义和触发规则。在 Backtrader 中,信号口径主要涉及:
- 触发条件:是“价格突破均线”还是“MACD 金叉”?不同条件对应不同的信号口径。
- 信号优先级:当多个信号同时出现时,哪个信号优先执行?
- 信号过滤:是否允许信号重复触发?是否需要在信号触发后设置冷却期?
校准示例:假设策略逻辑是“收盘价上穿 20 日均线买入”。如果回测使用收盘价口径,但实盘使用盘中实时价格,那么回测中的“上穿”时刻与实盘中的“上穿”时刻可能相差数小时,导致买入价格完全不同。
1.5 口径校准的核心流程
在 Backtrader 中进行标签口径校准,通常遵循以下步骤:
- 明确策略逻辑:写出策略的完整交易规则,包括信号生成条件、成交价格、时间点。
- 识别默认口径:了解 Backtrader 的默认行为(如 next() 中的成交机制)。
- 对比差异:将策略逻辑与 Backtrader 默认口径进行逐项对比,找出不一致之处。
- 编写校准代码:通过重写
notify_order()、notify_trade()等方法,或使用Cheat-On-Open/Cheat-On-Close模式进行校准。 - 验证结果:使用已知数据集进行回测,检查成交记录是否与预期一致。
重要提醒:口径校准不是一次性工作。当策略逻辑、交易品种或时间周期发生变化时,需要重新审视并调整口径设置。