工程与管理量化交易系统架构

稀疏交易信号如何做 A/B:可观测、可回溯、可实验的量化系统

本文讨论量化交易系统的工程实验机制,不构成具体投资建议。

量化系统需要实验,但真实交易信号往往很少。一个月只有几十次有效机会,再拆成 6 个 Live 实验组,每组可能只成交几笔。此时 Profit Factor、Max Drawdown、Sharpe 都会剧烈波动,某次极端行情落到哪个组,哪个组就可能“假胜出”。

所以,稀疏信号不是不能做 A/B,而是不能照搬互联网的小流量、多分组 Live A/B

目标也不只是选出一个局部胜率更高的参数,而是建立一套长期生产机制:

  • 高质量:信号、决策、成交、收益都能解释;
  • 高流量:不浪费任何一次真实信号的实验价值;
  • 高收益:只让经过证据筛选的策略承担真实风险。

什么是量化实验系统

它不是多加一个 experiment_id,也不是把订单随机分流。

完整的实验系统至少包含四层:

Market Event

Candidate Signal

Decision Intent

Live Execution

Matured Outcome

每一层都要回答三个问题:

  1. 可观测:系统当时看见了什么,做了什么?
  2. 可回溯:为什么做出这个决策,能否用原版本重放?
  3. 可实验:同一个机会,不同策略会做出什么选择?

没有这三点,所谓 A/B 只是把不确定性随机分组,并没有产生可信证据。


为什么不能直接做六组 Live A/B

传统 A/B 默认三个条件:

  • 流量足够大;
  • 样本相互独立;
  • 单次决策很快得到结果。

交易系统恰好相反。

信号稀疏,持仓跨越时间,订单之间还共享账户资金、风险预算、锁仓和对冲状态。一笔交易可能占用后续机会,一个实验组的动作会改变另一个实验组能看到的账户状态。

如果把 60 个信号平均拆给 6 组,每组只有 10 个候选;再经过 Gate、滑点和成交过滤,可能只剩 3~5 笔成熟交易。此时:

一次止损 → Profit Factor 大幅变化
一次尾部盈利 → Sharpe 突然胜出
一次极端行情 → MaxDD 只落到某一组

去掉实验系统的代价,不是“少一个报表”,而是系统只能凭短期 PnL 和个人直觉上线策略。直接做六组 Live 的代价,则是用真实资金制造统计噪声


第一层:六组全量 Shadow,不切碎稀疏信号

稀疏场景的关键不是分配流量,而是复用流量。

每一次真实信号到来时,Control 和全部 Challenger 都并行计算,但只有线上版本真实执行:

同一次 Signal
   ├─ Control:决策 + 真实执行
   ├─ Arm B:Shadow 决策
   ├─ Arm C:Shadow 决策
   ├─ Arm D:Shadow 决策
   ├─ Arm E:Shadow 决策
   └─ Arm F:Shadow 决策

六组都必须记录:

  • 是否入场;
  • 被哪个 Gate 阻断;
  • sizing 与多腿计划;
  • fallback 候选;
  • 预期入场价、止损、止盈;
  • MAE、MFE、TTT;
  • 候选、意图、成交各层的 precision/recall;
  • 策略版本、参数版本、数据版本和市场 regime。

这样 60 个信号对每一组仍然是 60 个观察样本,而不是 10 个。Shadow 的价值不是“零风险试运行”,而是把一次稀缺机会转化为多组可比较证据

这和广告检索系统的召回漏斗相同:一次请求可以让多个模型并行打分,但最终只让线上模型参与竞价。实验流量不应在召回层就被切碎。


第二层:可观测不是日志多,而是决策链完整

交易实验最常见的问题是只记录最终订单:

BUY BTC 0.1 @ 68000

这无法解释为什么买、为什么是 0.1、其他实验组为什么没买。

正确做法是给同一次机会一个稳定的 signal_id,贯穿全链路:

signal_id
├─ candidate_event
├─ feature_snapshot
├─ gate_decision[]
├─ strategy_intent[]
├─ sizing_plan
├─ order_attempt[]
├─ fill_event[]
└─ matured_outcome

观测指标也要分层:

层级核心问题指标
候选层有没有发现机会Recall、候选量、数据完整率
Gate 层为什么被过滤Kill Rate、误杀率、各 Gate 漏斗
意图层打算如何交易通过率、fallback、sizing 分布
成交层是否真实执行成交率、滑点、延迟、拒单率
收益层结果是否成熟Expectancy、PF、MAE/MFE/TTT
组合层系统能否长期生存MaxDD、Active MTM、净值曲线

可观测性的本质不是看见结果,而是看见结果形成的路径。


第三层:可回溯依赖不可变版本

如果策略参数可以原地修改,历史实验就无法复现。

每个决策必须绑定不可变快照:

experiment_id
arm_id
strategy_version
config_hash
feature_schema_version
market_data_offset
risk_policy_version

原仓位继续使用入场时的版本,不能因为 Challenger 切换上线,就让旧仓位中途更换止损、对冲或退出逻辑。

回放时也不能只喂 K 线。要恢复当时真正可见的数据、账户状态、活跃仓位、风险预算和 Gate 顺序。否则回放得到的是“今天理解的昨天”,不是昨天真实的决策环境。

这和广告系统的索引版本一致:离线复现一次召回,必须知道当时使用的索引快照、特征版本和模型版本。只保留最终曝光日志,无法解释漏召。


第四层:Shadow 淘汰,Live 只保留 Top2

六组 Shadow 的目的不是直接选冠军,而是快速排除明显错误:

  • 数据不完整;
  • Recall 明显下降;
  • Gate Kill Rate 异常;
  • sizing 分布偏离风险预算;
  • fallback 频繁失效;
  • MAE 明显恶化;
  • 收益只由单个尾部样本贡献。

Shadow 排名后只留下两组:

Control
    vs
Challenger

Live 阶段验证的是 Shadow 无法完全模拟的部分:真实成交、滑点、延迟、资金占用、订单拒绝和组合级风险。

因此六臂能力仍然有价值,但主要服务于全量 Shadow 组合筛选,不应该把真实成交平均拆成六份。


单账户为什么要用 Switchback

如果没有相互隔离的账户集群,同账户随机混跑 A/B 会产生状态污染:

  • A 组开仓后占用了 B 组的资金;
  • A 组进入对冲状态后,B 组看到的风险敞口已变化;
  • 两组同时操作同一标的,收益归因失真。

更适合按完整时间块轮换:

Control 7 天
→ Challenger 7 天
→ Control 7 天
→ Challenger 7 天

切换必须满足:

  • 没有实验活跃仓位;
  • 没有 handoff;
  • 对冲、锁仓状态归零;
  • 原仓位继续使用入场版本;
  • 记录并平衡市场 regime;
  • 切换点和原因写入审计日志。

Switchback 也不是简单按日历轮换。趋势、震荡、极端波动可能集中在某个时间块,所以最终比较必须按 regime 分层,避免把行情差异误判为策略差异。


不等固定样本:使用成熟窗口与序贯判断

交易结果不是成交后立即成熟。不同策略持仓周期不同,如果过早统计,长持仓组会天然吃亏。

每个样本需要明确成熟条件:

已平仓

超过最大观察窗口

达到统一的路径评估时点

每次新增成熟样本后更新:

  • effect size;
  • bootstrap 置信区间;
  • Challenger 胜出概率;
  • 风险恶化概率;
  • 数据完整率;
  • 各 regime 的一致性。

样本不足时,组合指标必须显示:

INSUFFICIENT_DATA

不能因为短期领先就自动扩量,也不能把“没有证据表明更差”解释成“已经证明更好”。序贯判断的价值是持续更新证据,不是更早宣布胜利。


三高目标如何落到实验机制

高质量

不是单纯提高 precision,而是从候选到组合收益都能追踪。Gate 误杀、fallback、滑点和仓位路径都能被定位,坏收益不再只归因于“市场不好”。

高流量

不是增加无效交易,而是提高每个真实信号的信息利用率。一次信号供六组 Shadow 并行学习,候选层样本最大化,真实资金只承担 Top2 的验证成本。

这相当于广告检索漏斗:召回层尽量保留信息,粗排快速淘汰,精排只处理高价值候选。过早截断会损失 Recall,过晚全量 Live 会浪费预算。

高收益

收益不是某个实验组短期 PnL 最大,而是:

可信 Alpha
× 可执行流量
× 风险约束下的仓位效率

高质量决定 Alpha 是否真实,高流量决定机会能否被充分利用,风控和实验门禁决定收益能否长期保留。


推荐的完整机制

6 组全量 Shadow
→ 候选 / Gate / 意图 / 路径分层评估
→ 淘汰到 Top2
→ Control vs Challenger 小规模 Live
→ 单账户按无仓状态 Switchback
→ 成熟样本序贯更新
→ metrics.md 生成完整 Diff
→ 人工审核后扩大

实验平台负责生成证据,不负责替人冒险。自动化可以自动降级、自动停止和标记数据不足,但不能因为短期领先自动扩大仓位。

一句话总结:稀疏交易信号不适合传统小流量、多组 Live A/B;正确做法是用全量 Shadow 放大信息,用 Top2 Live 验证执行,用 Switchback 隔离状态,用可回溯版本和序贯统计守住结论。