3、明池路由基础:交易所连接、FIX协议入门、订单生命周期
好,咱们进入正题。
明池路由,说白了就是你的订单怎么光明正大地走到交易所去。暗池是黑箱,明池就是透明柜台。你想想看,一个订单从你敲下回车,到最终成交,中间经历了什么?这背后就是交易所连接、FIX协议、还有订单生命周期这三件事。
3.1 交易所连接:不只是TCP长连接
很多人以为连交易所就是开个socket发数据。嗯,没那么简单。
我个人习惯把交易所连接分成三层:
- 传输层:TCP长连接,心跳保活,断线重连
- 会话层:登录认证,序列号管理,消息确认
- 业务层:订单收发,行情订阅,风险控制
我在项目中遇到过最坑的事——某次交易所升级,把心跳间隔从30秒改成了15秒,我们的老代码没跟上,结果每天下午准时断线。排查了三天才发现是心跳超时。
避坑指南:我曾经因为没处理好断线重连的序列号,导致重复下单,被风控部门请去喝茶。记住:重连后一定要做序列号同步。
3.2 FIX协议入门:金融界的HTTP
FIX协议,全称Financial Information eXchange。说白了,就是交易所和交易员之间说好的「黑话」。
一个典型的FIX消息长这样:
8=FIX.4.2|9=78|35=D|49=CLIENT1|56=EXCHANGE|34=1|52=20240101-00:00:00|11=ORD001|55=600519|54=1|38=100|44=200.50|10=123|
看着乱?我拆开给你看:
| 标签 | 含义 | 示例值 |
|---|---|---|
| 8 | 协议版本 | FIX.4.2 |
| 35 | 消息类型 | D(新订单) |
| 55 | 证券代码 | 600519(茅台) |
| 54 | 买卖方向 | 1(买) |
| 38 | 数量 | 100股 |
| 44 | 价格 | 200.50元 |
你可能会问:为什么不用JSON?因为FIX诞生在90年代,那时候带宽金贵,一个字节都不能浪费。现在虽然带宽不是问题,但FIX已经成为行业标准,改不动了。
个人经验:我建议新手先别急着写FIX解析器。直接用现成的库,比如QuickFIX/C++或者Python的simplefix。自己手写?我曾经干过这事,结果被各种边界条件折磨到怀疑人生。
3.3 订单生命周期:从摇篮到坟墓
一个订单从出生到死亡,大概经历这么几个阶段:
- 创建:你填好价格、数量、方向,点击发送
- 验证:交易所检查你的账户余额、风控规则
- 排队:进入订单簿,等待撮合
- 成交:和对手单匹配,部分或全部成交
- 撤销:你主动取消,或者交易所帮你取消
- 过期:当日有效订单收盘后自动失效
这里有个关键点——订单状态机。我见过太多人把状态机画成一条直线,实际上它是带环的图。
核心要点:订单状态转换必须幂等。同一个成交回报收到两次,不能导致重复成交。我曾经因为没处理好这个,让系统多买了1000股,那叫一个酸爽。
下面这张图,是我自己项目里用的订单状态机,你感受一下:
你看,状态之间不是单向的。比如「部分成交」之后,还可以继续成交,也可以撤销剩余部分。我当年第一次画这个图,画成了线性结构,结果上线第一天就出了bug——部分成交后撤销,系统直接崩溃了。
3.4 实战中的那些坑
最后分享几个我踩过的坑:
- 序列号跳跃:FIX协议要求序列号连续,一旦跳跃,交易所会断开连接。我遇到过因为多线程并发发送导致序列号乱序,被交易所踢下线。
- 心跳超时:不同交易所的心跳间隔不一样,有的30秒,有的15秒。我建议统一设为10秒,留足余量。
- 订单重复:网络重传可能导致同一订单发两次。解决方案是每个订单生成唯一ID(ClOrdID),交易所会做去重。
我的习惯:每次上线新交易所,我都会先跑一周的模拟盘。不是不相信文档,是文档经常和实际不一样。你想想看,交易所的文档更新速度,永远赶不上代码改动的速度。
好了,明池路由的基础就这些。记住:连接是骨架,FIX是语言,订单生命周期是灵魂。这三样搞明白了,后面的路由策略才有得玩。
公众号:蓝海资料掘金营,微信deep3321