一、交易链路概述:从订单生成到交易所撮合的全路径拆解

做量化交易这些年,我见过太多人把精力全花在策略模型上,却忽略了订单从生成到成交这一路上经历的「九九八十一难」。说白了,你策略再牛,如果订单在路上多走了几微秒,可能就吃不到那口肉了。

今天我们就来拆解这条链路。我个人习惯把交易链路分成三段:客户端内部处理网络传输交易所撮合。每一段都有它的坑。

1.1 全路径拆解:订单的「一生」

一个订单从诞生到成交,大致经历以下步骤:

  1. 策略信号生成 — 你的模型算出了买卖信号
  2. 订单组装 — 把信号转成交易所能识别的协议格式
  3. 编码与序列化 — 把订单结构体变成二进制字节流
  4. 内核态网络发送 — 经过协议栈、网卡驱动,把数据发出去
  5. 物理链路传输 — 光纤、交换机、微波塔(如果你够壕)
  6. 交易所前置机接收 — 网卡收包、内核处理、应用层解析
  7. 撮合引擎处理 — 进入订单簿,匹配成交
  8. 回报回传 — 成交确认原路返回

嗯,这里要注意:每一步都有延迟,而且不是简单的加法。我曾经在项目中遇到过,某家券商的订单系统在序列化这一步就耗了 20 微秒,比整个网络传输还长。

核心观点:交易链路的延迟不是均匀分布的。80% 的延迟往往集中在 20% 的环节上。找到那 20%,你就找到了优化的突破口。

1.2 延迟的构成:到底慢在哪?

我把延迟拆成三类,你想想看是不是这个理:

延迟类型 典型来源 量级参考
处理延迟 CPU 计算、内存拷贝、序列化/反序列化 1-50 μs
排队延迟 内核缓冲区、网卡队列、应用层消息队列 1-100 μs(波动大)
传输延迟 光纤传播、交换机转发、微波传输 10 μs - 1 ms(取决于距离)

为什么排队延迟波动大?因为它是「软」的。你想想看,如果系统突然来了个 GC(垃圾回收),或者网卡中断合并策略没调好,排队延迟可能瞬间翻几倍。我建议你在做延迟测量时,别只看平均值,P99 和 P99.9 才是真正要命的

避坑指南:我曾经被 P50 延迟骗过一次。系统平均延迟 5 微秒,看起来很美。结果上线后发现,每 1000 笔订单就有一笔延迟飙到 200 微秒。后来查出来是内核的 netpoll 机制在特定条件下触发了慢路径。从那以后,我所有延迟测试都强制看尾延迟。

1.3 延迟测量:怎么知道到底慢在哪?

测量延迟,说白了就是给每个环节打上时间戳。但这里有个坑——时间戳本身也有开销。你每打一个时间戳,可能就多花几十纳秒。在微秒级的链路里,这可不是小数目。

我个人习惯的做法是:

  • 使用 TSC 寄存器(x86 的 RDTSC 指令)获取高精度时间戳,开销约 20-30 纳秒
  • 在关键路径上埋点,但不要每个函数都埋,只埋「可能出问题」的地方
  • 用环形缓冲区存时间戳,避免打印日志带来的 IO 延迟

下面是一个简单的测量代码示例,我在项目中经常用这种模式:

// 伪代码:在关键路径上打时间戳
uint64_t t1 = rdtsc();
// ... 执行订单组装 ...
uint64_t t2 = rdtsc();
// ... 执行网络发送 ...
uint64_t t3 = rdtsc();

// 计算各阶段耗时(纳秒)
uint64_t assemble_latency = (t2 - t1) * ns_per_cycle;
uint64_t send_latency     = (t3 - t2) * ns_per_cycle;

// 写入环形缓冲区,异步落盘
ring_buffer_push(assemble_latency, send_latency);

注意:RDTSC 在多核 CPU 上可能不准,因为不同核心的 TSC 可能不同步。我建议在程序启动时先校准一下,或者绑定核心运行。否则你测出来的延迟可能是负数——别问我怎么知道的。

1.4 知识体系总览

下面这张图是我自己画的,把交易链路的全貌和延迟构成串在了一起。你看完应该能有个整体印象:

交易链路全路径与延迟构成 客户端内部处理 1. 策略信号生成 2. 订单组装 3. 编码与序列化 4. 内核态网络发送 延迟:1-50 μs(处理+排队) 网络传输 5. 物理链路传输 - 光纤/微波 - 交换机转发 - 协议栈处理 延迟:10 μs - 1 ms(距离决定) 交易所撮合 6. 前置机接收 7. 应用层解析 8. 撮合引擎匹配 9. 回报回传 延迟:5-50 μs(撮合引擎) 延迟构成分析(重点关注) 处理延迟 CPU计算、内存拷贝、序列化 排队延迟 内核缓冲区、网卡队列、GC 传输延迟 光纤传播、交换机转发、微波 ⚠ 尾延迟(P99.9)才是关键 平均值会掩盖问题 ⚠ 时间戳测量本身有开销 使用 RDTSC,避免 gettimeofday ⚠ 多核 TSC 不同步问题 绑定核心或校准后再用

1.5 小结

交易链路这件事,说白了就是跟时间赛跑。你不需要把每个环节都优化到极致,但一定要知道瓶颈在哪。我个人习惯是:先测量,再优化。没有数据支撑的优化,都是瞎忙活。

嗯,这一章就到这里。记住三个关键词:全路径拆解、延迟构成、尾延迟测量。后面我们会一步步深入每个环节,看看怎么把微秒级的延迟一点点抠出来。

一句话总结:交易链路的延迟优化,不是把每个环节都做快,而是把最慢的那个环节找出来,干掉它。


公众号:蓝海资料掘金营,微信deep3321