交易系统核心概念:订单簿、撮合引擎、行情与性能指标
做量化交易这些年,我越来越觉得,不管你的策略多花哨,底层那套东西才是命根子。今天咱们就聊聊交易系统的四个核心概念——订单簿、撮合引擎、市场行情,还有延迟和吞吐量。这些是FPGA异构计算里最常打交道的部分。
一句话总结:订单簿是市场的“账本”,撮合引擎是“裁判”,行情是“广播”,延迟和吞吐量是“成绩单”。
1. 订单簿数据结构
订单簿,说白了就是买卖双方的排队列表。买盘叫Bid,卖盘叫Ask。每一档都记录着价格和对应的挂单量。
我刚开始做交易系统时,觉得订单簿不就是个排序列表嘛。后来发现,在FPGA里实现它,坑多得很。你想想看,每秒几万笔订单进来,你要在几微秒内完成插入、删除、修改——用软件里的红黑树?那延迟直接爆炸。
我个人习惯在FPGA里用跳表(Skip List)或者硬件哈希表来维护订单簿。为什么?因为硬件里做二分查找太费资源,而跳表可以并行比较,延迟可控。
订单簿的核心操作就三个:
- 新增订单:按价格插入到对应档位
- 撤销订单:从指定档位删除
- 成交更新:修改档位上的剩余数量
这里有个关键点——价格档位是固定的。比如沪深交易所的最小价格变动单位是0.01元,那我们就按这个粒度来划分。FPGA里用BRAM存每个档位的总挂单量,用寄存器存最优买卖价。这样查最优价只需要一个时钟周期。
避坑指南:我曾经在项目里直接用链表实现订单簿,结果在极端行情下,链表遍历导致撮合延迟飙升到几十微秒。后来改成固定深度的数组+指针池,延迟直接降到纳秒级。记住:FPGA里不要用动态数据结构,能静态分配就别动态。
2. 撮合引擎逻辑
撮合引擎,就是检查新进来的订单能不能和已有的订单成交。逻辑其实不复杂:
- 新买单进来,看卖一价是否 ≤ 买单价格
- 如果是,按价格优先、时间优先的原则成交
- 如果买单没吃完,剩下的挂到买盘上
但这里有个细节——撮合粒度。是按单笔撮合,还是按批量撮合?我见过一些系统为了降低延迟,把一段时间内的订单攒起来一起撮合。这其实是个陷阱。你想想看,如果攒了10笔订单再撮合,那第1笔和第10笔的延迟差了整整一个批次时间,对高频策略来说这就是灾难。
我个人建议在FPGA里做逐笔撮合,每进来一笔订单就立即处理。FPGA的流水线架构天然适合干这个——订单解析、价格比较、数量扣减、结果输出,每个阶段一拍搞定。
// 伪代码:FPGA撮合流水线
// Stage 1: 解析订单
order_type, price, qty = parse(input_packet)
// Stage 2: 比较价格
if (order_type == BUY) {
can_match = (price >= best_ask_price)
} else {
can_match = (price <= best_bid_price)
}
// Stage 3: 执行撮合
if (can_match) {
match_qty = min(qty, best_level_qty)
update_order_book(best_level, -match_qty)
generate_trade_report(price, match_qty)
}
// Stage 4: 更新最优价
if (best_level_qty == 0) {
update_best_price()
}
嗯,这里要注意:撮合完成后,一定要检查最优买卖价是否变化。如果最优价档位被吃光了,得立即找到下一档。这个查找过程在FPGA里可以用优先级编码器实现,一个时钟周期就能搞定。
3. 市场数据行情
行情数据,就是交易所发出来的“实时广播”。包括逐笔成交、订单簿快照、指数行情等等。对于量化交易来说,行情就是原料。
行情数据有两个关键指标:完整性和实时性。完整性指不能丢包,实时性指延迟要低。这两个指标在FPGA里是矛盾的——你要保证不丢包,就得加缓存和重传机制,这就会增加延迟。
我做过一个项目,客户要求行情延迟小于1微秒,同时丢包率低于10的负9次方。当时我们用了双端口BRAM做环形缓冲区,一个端口写,一个端口读,配合硬件校验和重传。最终延迟控制在800纳秒左右,丢包率几乎为零。
行情解析也是个技术活。交易所的行情协议通常是二进制的,比如STEP、FAST等。FPGA里解析这些协议,说白了就是按位截取、按字段映射。我建议用状态机+移位寄存器的组合,状态机控制解析流程,移位寄存器做位对齐。
警告:行情数据里最容易出问题的是时间戳。交易所发的时间戳是纳秒级的,但FPGA内部时钟可能不同步。我曾经踩过这个坑——行情解析时直接用本地时钟打时间戳,结果和交易所的时间差了十几微秒,导致策略回测和实盘对不上。后来改用交易所自带的时间戳,问题才解决。
4. 延迟与吞吐量指标
做交易系统,这两个指标是绕不开的。延迟就是一笔订单从发出到收到确认的时间,吞吐量是单位时间内能处理的订单数量。
很多人以为延迟越低越好,其实不然。我见过一些团队为了把延迟从1微秒降到0.5微秒,投入了大量资源优化硬件,结果吞吐量反而下降了。为什么?因为流水线深度增加了,处理一笔订单需要的时钟周期变多了。
这里有个权衡:
| 指标 | 含义 | FPGA优化方向 |
|---|---|---|
| 延迟 | 单笔订单处理时间 | 减少流水线级数、使用组合逻辑 |
| 吞吐量 | 每秒处理订单数 | 增加并行度、使用乒乓操作 |
我个人习惯先确定业务需求。如果是做市商策略,延迟更重要,因为你要抢在别人前面成交。如果是套利策略,吞吐量更重要,因为你要同时监控多个品种。
测量延迟也有讲究。不能只看平均延迟,要看尾延迟——就是最慢的那1%的订单花了多长时间。我遇到过系统平均延迟只有500纳秒,但尾延迟到了10微秒。一查,原来是某个订单触发了BRAM的写冲突,导致流水线停顿。后来加了写仲裁逻辑,尾延迟才降下来。
小技巧:FPGA里测量延迟,可以用时间数字转换器(TDC)。在订单入口打一个时间戳,出口再打一个,差值就是延迟。TDC的精度可以做到几十皮秒,比用系统时钟打戳准得多。
知识体系总览
下面这张图是我自己画的,把今天讲的四个概念串起来了。你可以看到,订单簿是核心数据结构,撮合引擎是处理逻辑,行情是输入输出,延迟和吞吐量是衡量标准。FPGA异构计算就是在这四个维度上做优化。
好了,这一章的内容就这些。订单簿、撮合引擎、行情、延迟吞吐量——这四个概念你吃透了,后面讲FPGA实现的时候就能跟上节奏。记住,做交易系统,数据结构和性能指标是地基,地基不稳,上面盖什么都是白搭。
公众号:蓝海资料掘金营,微信deep3321