四、技术系统要求:低延迟交易系统架构、API对接规范、行情数据订阅、订单管理系统的搭建
做市商资格申请,技术系统这块是硬骨头。我见过不少团队,策略再牛,系统一上实盘就崩,原因就是技术底子没打牢。说白了,交易所看你的技术系统,核心就四个字:稳、快、准、全。
下面我按四个模块拆开讲,都是我在项目中踩过的坑和积累的经验。
4.1 低延迟交易系统架构
低延迟,不是玄学。我习惯把延迟拆成三部分:网络延迟、系统处理延迟、交易所撮合延迟。我们能控制的,主要是前两个。
核心目标:从行情到达 -> 策略计算 -> 订单发出,全程控制在 100 微秒以内。
4.1.1 架构选型
我个人推荐 事件驱动 + 异步非阻塞 架构。别用传统的线程池轮询,那玩意儿延迟抖动太大。
举个例子,我早期用 Java 的 Netty 做底层通信,后来发现 GC 停顿是个大问题。现在团队主力用 C++ 配合 DPDK,用户态协议栈,绕过内核,延迟能降一个数量级。
我的经验:如果团队 C++ 能力一般,可以考虑用 Rust。内存安全,性能接近 C++,开发效率高不少。我在一个中型项目里试过,效果不错。
4.1.2 硬件与部署
- 服务器:尽量托管在交易所机房,或者同城同一数据中心。物理距离每增加 100 公里,延迟大约增加 1 毫秒。
- 网卡:Solarflare 或 Mellanox 的智能网卡,支持硬件时间戳和 TCP 卸载。
- CPU:关闭超线程、关闭节能模式、绑核运行。我习惯把网络中断和业务线程绑在不同的物理核上。
避坑指南:我曾经遇到过服务器 BIOS 设置没优化,导致延迟忽高忽低。后来发现是 C-State 没关,CPU 频繁进入休眠状态。嗯,这个细节很容易被忽略。
4.1.3 架构图
下面这张图是我自己项目里用的简化版架构,你可以参考一下:
4.2 API对接规范
API 对接,看着简单,但细节决定成败。我见过太多团队因为 API 对接不规范,上线后出各种幺蛾子。
4.2.1 接口类型
| 接口类型 | 用途 | 延迟要求 | 备注 |
|---|---|---|---|
| REST API | 账户查询、历史数据、参数设置 | 毫秒级 | 非核心交易路径 |
| WebSocket | 实时行情、成交回报 | 毫秒级 | 需要心跳保活 |
| FIX 协议 | 订单收发 | 微秒级 | 做市商首选 |
| UDP 组播 | 深度行情 | 微秒级 | 需要自行处理丢包 |
4.2.2 对接规范要点
- 重连机制:WebSocket 断线后,必须在 1 秒内自动重连。我习惯用指数退避策略,避免雪崩。
- 序列号校验:每个消息带递增序列号,发现跳号立即报警。我曾经因为没做这个,漏了一笔成交回报,导致仓位对不上。
- 心跳超时:设置 3 秒超时,超过 5 秒无响应就断开重连。别问我为什么是 5 秒,血泪教训。
核心原则:所有 API 调用必须有超时、有重试、有熔断。别让一个接口卡死整个系统。
4.3 行情数据订阅
行情是做市商的命根子。数据慢了、丢了、错了,策略全白搭。
4.3.1 订阅策略
我建议采用 全量快照 + 增量更新 的模式。别每次都拉全量,那延迟受不了。
举个例子,币安的交易对深度,每秒推送 10 次增量,每 100 毫秒一次。我们本地维护一个 order book,增量来了就更新,同时定期用快照做校验。
我的习惯:本地维护两个 order book,一个用于策略计算,一个用于校验。每 10 秒用快照同步一次,发现不一致立刻报警并重建。
4.3.2 数据质量保障
- 去重:同一个序列号的消息只处理一次。
- 排序:按时间戳严格排序,乱序消息缓存后重排。
- 校验:快照的 checksum 必须和交易所一致。我遇到过交易所快照和增量对不上的情况,全靠 checksum 发现。
避坑指南:我曾经在某个交易所发现,他们的增量更新偶尔会漏掉几笔。后来我们加了一层「自愈机制」——如果发现本地 order book 和快照差异超过阈值,自动请求全量快照重建。这个机制救了我们好几次。
4.4 订单管理系统搭建
订单管理系统(OMS),说白了就是管好每一笔订单的「生老病死」。我见过最惨的案例,OMS 没做好,订单状态混乱,导致仓位计算错误,一天亏了几十万。
4.4.1 核心功能
| 功能模块 | 说明 | 关键指标 |
|---|---|---|
| 订单生成 | 策略信号转为订单 | 延迟 < 10μs |
| 订单路由 | 选择最优交易所/通道 | 延迟 < 50μs |
| 状态管理 | 跟踪订单全生命周期 | 准确率 100% |
| 风控检查 | 下单前校验 | 延迟 < 20μs |
| 成交回报 | 处理成交、部分成交、撤单 | 延迟 < 100μs |
4.4.2 状态机设计
订单状态必须用有限状态机管理,不能有歧义。我习惯用以下状态:
状态流转:
NEW -> ACK (已接收)
NEW -> REJECT (被拒)
ACK -> PARTIAL_FILL (部分成交)
ACK -> FILLED (全部成交)
ACK -> CANCELED (已撤单)
PARTIAL_FILL -> FILLED (剩余部分成交)
PARTIAL_FILL -> CANCELED (剩余部分撤单)
注意:每个状态变更都必须记录时间戳和原因。出了问题,这是唯一的排查依据。
4.4.3 风控前置
订单发出前,必须经过风控检查。我建议至少检查以下几项:
- 价格检查:订单价格不能偏离当前市价超过 X%。
- 数量检查:单笔数量不能超过最大限制。
- 频率检查:每秒下单次数不能超过阈值。
- 仓位检查:下单后总仓位不能超过风控上限。
我的经验:风控模块最好独立部署,和交易进程分开。这样即使交易进程挂了,风控还能继续拦截异常订单。我曾经见过风控和交易耦合在一起,结果交易进程内存泄漏,风控也跟着挂了,订单满天飞。
4.4.4 日志与监控
每一笔订单的完整生命周期都要记录。我习惯用 环形缓冲区 记录高频日志,避免磁盘 I/O 影响性能。同时,关键指标要实时监控:
- 订单延迟(从生成到交易所确认)
- 订单成功率
- 撤单率
- 风控拦截率
避坑指南:我曾经遇到过日志写太多,磁盘写满导致系统崩溃。后来我们做了日志分级,核心日志保留 7 天,调试日志只保留 24 小时。嗯,这个教训花了我一个通宵才搞定。
好了,技术系统这块就这些。记住,系统是策略的载体,稳比快更重要。先把基础打牢,再追求极致性能。