7.8 KiB
实验 008:信号执行延迟对策略收益的影响
实验日期:2026-06-15
实验目标:量化信号触发后延迟执行对策略收益的影响,评估策略的执行容错度
实验结论:卖出必须立即执行;买入延迟 1 天可接受(-1.7pp),延迟 2 天以上策略失效
一、问题背景
1.1 当前执行机制
策略采用 T+1 执行模式:
- T 日 9:00:信号触发,使用 T-1 收盘数据计算动量因子
- T 日 9:30:开盘执行调仓(卖出 + 买入),使用 T 日 ETF 价格
信号生成和执行在同一天,延迟为 0。
1.2 测试目的
实盘中可能存在以下情况导致延迟执行:
- 人工操作延迟
- 系统故障导致未能及时下单
- 流动性不足需要分批执行
- 跨时区交易的时间差
需要量化这些延迟对策略的实际影响,评估策略的执行容错度。
1.3 两种延迟模式
调仓包含两个动作:卖出和买入。延迟执行有两种理解方式:
| 模式 | 卖出时机 | 买入时机 | 等待期间状态 |
|---|---|---|---|
| 模式 A:买卖都延迟 | 延迟 N 天 | 延迟 N 天 | 继续持有原仓位 |
| 模式 B:卖立即、买延迟 | 立即执行 | 延迟 N 天 | 已卖出部分变为现金 |
两种模式对策略的影响可能不同,需要分别测试对比。
二、实验设计
2.1 延迟定义
| 延迟天数 | 含义 |
|---|---|
| 0 | 基线(当前逻辑),T 日信号 → T 日开盘执行 |
| 1 | 延迟 1 天,T 日信号 → T+1 日开盘执行 |
| 2 | 延迟 2 天,T 日信号 → T+2 日开盘执行 |
| 3 | 延迟 3 天,T 日信号 → T+3 日开盘执行 |
2.2 实验配置
- 配置文件:
rotation/config_simple.yaml - 因子类型:
slope_r2,n_days=25 - 回测区间:2020-01-10 ~ 2026-06-15(1555 个交易日)
- 标的池:11 资产 / 6 组
- 选择数量:3
- 权重模式:rank
2.3 实现方式
在 SimpleRotationStrategy 中增加 execution_delay 参数,通过修改 run() 主循环实现两种延迟模式。
三、实验 A:买卖都延迟
3.1 逻辑说明
信号变化后,整个调仓(卖出 + 买入)延迟 N 天执行。等待期间继续持有原仓位。
3.2 实验结果
| 延迟天数 | 总收益 | 年化收益 | 最大回撤 | Sharpe | Calmar | 胜率 | 调仓次数 |
|---|---|---|---|---|---|---|---|
| 0 | 305.02% | 25.44% | -16.27% | 1.20 | 1.56 | 53.83% | 365 |
| 1 | 207.29% | 19.95% | -22.29% | 0.97 | 0.90 | 53.99% | 340 |
| 2 | 101.57% | 12.03% | -24.53% | 0.65 | 0.49 | 53.57% | 314 |
| 3 | 141.29% | 15.34% | -29.03% | 0.77 | 0.53 | 53.80% | 275 |
3.3 NAV 走势对比(关键节点)
| 交易日 | delay=0 | delay=1 | delay=2 | delay=3 |
|---|---|---|---|---|
| 100 | 1.0785 | 1.0205 | 1.0287 | 1.1477 |
| 300 | 1.2462 | 1.1517 | 1.1148 | 1.3979 |
| 500 | 1.3847 | 1.2552 | 1.1666 | 1.4580 |
| 700 | 1.7195 | 1.4321 | 1.2339 | 1.4492 |
| 1000 | 1.8482 | 1.5281 | 1.3189 | 1.5750 |
| 1200 | 2.0596 | 1.7315 | 1.3590 | 1.7015 |
| 1555 | 4.0563 | 3.0775 | 2.0187 | 2.4165 |
3.4 分析
收益衰减规律:
delay 0 → 1:年化 -5.5pp(-21.6%)
delay 1 → 2:年化 -7.9pp(-39.7%)
delay 2 → 3:年化 +3.3pp(+27.4%,非单调回升)
delay=3 略好于 delay=2 是非单调现象,原因是更长的延迟反而减少了无效调仓(275 vs 314 次),在某些场景下偶然捕获了更好的入场点。
胜率不变,幅度衰减:
胜率在各延迟下几乎恒定(53.6% ~ 54.0%),说明:
- 方向判断不受延迟影响 — 同样的信号选出同样的标的
- 收益差异来自入场价格 — 延迟越大,动量已走得越远,入场成本越高
回撤恶化:
| 延迟 | 最大回撤 | 回撤恶化幅度 |
|---|---|---|
| 0 | -16.27% | 基线 |
| 1 | -22.29% | +6.0pp |
| 2 | -24.53% | +8.3pp |
| 3 | -29.03% | +12.8pp |
延迟导致错过最佳出场时机,风险敞口增大。
四、实验 B:卖立即、买延迟
4.1 逻辑说明
信号变化后:
- 卖出立即执行:当日开盘卖出,资金变为现金
- 买入延迟 N 天:等待期间资金闲置(0 收益),到期后开盘买入
4.2 实验结果
| 延迟天数 | 总收益 | 年化收益 | 最大回撤 | Sharpe | Calmar | 胜率 | 调仓次数 |
|---|---|---|---|---|---|---|---|
| 0 | 305.02% | 25.44% | -16.27% | 1.20 | 1.56 | 53.83% | 365 |
| 1 | 271.78% | 23.71% | -15.60% | 1.15 | 1.52 | 53.06% | 365 |
| 2 | 96.92% | 11.61% | -21.40% | 0.66 | 0.54 | 50.87% | 653 |
| 3 | 4.30% | 0.68% | -35.67% | 0.13 | 0.02 | 48.93% | 890 |
4.3 分析
延迟 1 天影响很小:年化仅损失 1.7pp(25.44% → 23.71%),最大回撤甚至略好(-15.60% vs -16.27%)。因为卖出及时执行,止损不受影响。
延迟 2-3 天急剧恶化:调仓次数从 365 飙升到 653/890,说明策略在频繁卖出又买入之间空转。等待期间仓位不满,资金闲置。
五、两种模式对比
5.1 关键指标对比
| 延迟 | 模式 A(买卖都延迟) | 模式 B(卖立即、买延迟) | 差异 |
|---|---|---|---|
| 1 天 | 年化 19.95%,回撤 -22.29% | 年化 23.71%,回撤 -15.60% | 模式 B 好 +3.8pp,回撤少 6.7pp |
| 2 天 | 年化 12.03%,回撤 -24.53% | 年化 11.61%,回撤 -21.40% | 基本持平 |
| 3 天 | 年化 15.34%,回撤 -29.03% | 年化 0.68%,回撤 -35.67% | 模式 A 好 +14.7pp |
5.2 核心差异
延迟 1 天时:模式 B 明显优于模式 A
- 模式 B 年化高 3.8pp,回撤少 6.7pp
- 原因:及时止损比及时入场更重要
延迟 2-3 天时:模式 B 急剧恶化
- 模式 B 调仓次数飙升(653/890 vs 314/275)
- 原因:频繁卖出后等待买入,仓位长期不满,资金闲置
5.3 根因分析
策略的 alpha 来源是 25 天窗口内的短期动量。信号触发后的第 1 个交易日 move 是动量最集中的阶段:
- 信号触发时,标的刚进入强势趋势
- 延迟 1 天 = 错过趋势最陡的一段
- 延迟 2 天 = 趋势已衰减大半,入场性价比大幅下降
这与实验 007 的结论一致:策略本质是短期轮动而非长期趋势跟踪。
六、结论
6.1 核心结论
- 卖出必须立即执行 — 及时止损比及时入场更重要
- 买入延迟 1 天可接受 — 年化仅损失 1.7pp,回撤略好
- 买入延迟 2 天以上策略失效 — 频繁空转,资金闲置
- 胜率不受延迟影响 — 衰减完全来自入场价格劣化
6.2 对实盘的要求
| 场景 | 可行性 | 预期影响 |
|---|---|---|
| T+1 完整执行(买卖同日) | 最佳 | 基线(年化 25.4%) |
| T+1 卖出,T+2 买入 | 可接受 | 年化约 23.7%(-1.7pp) |
| T+2 完整执行 | 勉强 | 年化约 12%(-13pp) |
| T+3 完整执行 | 不可接受 | 策略失效 |
实盘建议:
- 信号生成当日必须完成卖出操作
- 如果买入无法当日完成,可延迟 1 天,影响可控
- 需要可靠的自动化下单系统
- 不建议手动操作执行此策略
6.3 与实验 007 的关联
实验 007 证明策略的 alpha 来自 25 天短期动量(而非长期趋势)。本实验进一步证实:短期动量的有效窗口不仅在回看端(25 天),在执行端同样敏感 — 信号触发后 1-2 天内的执行质量决定了策略的实际表现。
七、代码变更
rotation/simple_rotation.py:__init__增加execution_delay参数run()主循环支持两种延迟模式:- 模式 A:
pending_holdings存储完整调仓,等待期间持有原仓位 - 模式 B:
pending_buys仅存储买入,卖出立即执行,等待期间资金闲置
- 模式 A: