一、跨市场交易系统概述
什么是跨市场交易
跨市场交易,说白了就是在一个系统里,同时对接多个交易所的行情和订单。
举个例子。你手里有100手茅台,想卖掉。但A股只有散户接盘,价格上不去。这时候如果系统能同时看到港股通、甚至美股ADR的报价,你就能找到更好的卖价。这就是跨市场交易的核心价值——寻找价差、分散风险、提升流动性。
我2016年参与过一个项目,客户要求同时接入上交所、深交所、中金所、大商所四个市场。当时我心想,不就是多接几个API嘛?后来才发现,事情远没那么简单。
核心挑战:延迟、一致性、容错
这三个词,基本就是跨市场系统的命门。我一个个说。
1. 延迟
做交易的人都知道,时间就是钱。跨市场系统里,延迟问题更棘手。
为什么?因为不同交易所的物理距离不一样。上交所的交易机房在浦东,中金所在北京。你一个订单从上海发到北京,光速也得3毫秒。再加上网络抖动、协议解析、风控检查……10毫秒就出去了。
我遇到过最夸张的情况:某客户的策略是「看到A市场涨了,立刻在B市场买入」。结果A市场行情到了,B市场订单还没发出去,价差已经没了。后来我们做了个优化——把策略引擎直接部署到交易所的托管机房,延迟从12ms降到了0.8ms。效果立竿见影。
2. 一致性
跨市场系统里,一致性是个大坑。
你想想看:A市场成交了,B市场还没确认。这时候你的账户余额该怎么算?如果按A市场算,B市场万一失败了,你就超买了。如果等B市场确认再算,那A市场的资金就冻结着,白白浪费。
我2018年做过一个跨境套利系统,需要同时监控港股和美股。有一次港股那边成交了,美股这边因为网络延迟没收到确认。系统以为没成交,又发了一笔订单。结果两笔都成交了,仓位直接翻倍。那天晚上我加班到凌晨三点,手动平仓。
3. 容错
交易系统最怕什么?怕挂了。
跨市场系统更怕。因为一个市场挂了,其他市场还在跑。你的资金可能被锁在一个市场里,其他市场的订单却还在执行。
我记得有一次,某交易所的API突然返回了错误码。我们的系统没处理这个异常,直接抛了个空指针。结果整个交易进程挂了,其他三个市场的订单全部中断。等我们重启完,已经过去了5分钟。客户损失了大概200万的套利机会。
从那以后,我要求所有跨市场系统必须做到:
- 进程级隔离:每个市场的连接独立进程,一个挂了不影响其他
- 熔断机制:某个市场连续失败3次,自动暂停交易
- 手动干预通道:保留一个「紧急停止」按钮,一键清仓
系统架构演进史
跨市场交易系统不是一天建成的。我把它分成三个阶段。
| 阶段 | 时间 | 特点 | 典型问题 |
|---|---|---|---|
| 单体架构 | 2010年前 | 一个进程处理所有市场 | 耦合度高,一个市场出问题全挂 |
| 分层架构 | 2010-2015 | 行情层、交易层、风控层分离 | 层间通信延迟大,调试困难 |
| 微服务+事件驱动 | 2015至今 | 每个市场独立服务,消息队列解耦 | 一致性保障复杂,运维成本高 |
单体架构时代,我刚开始做交易系统时就是这种。一个Java进程,连三个交易所。代码里全是if-else判断市场类型。好处是简单,坏处是改一个市场就得重启整个系统。有一次升级上交所的协议,不小心把深交所的配置也改了,第二天开盘直接报错。
分层架构时代,大家开始把行情、交易、风控拆开。我记得2013年我们做了一个系统,行情层用C++,交易层用Java,中间用共享内存通信。性能确实上去了,但调试起来简直噩梦。行情层报了个错误码,交易层根本看不懂。每次出问题都得三个团队一起开会。
微服务+事件驱动时代,就是现在的主流做法。每个市场一个独立服务,用Kafka或RabbitMQ传递事件。好处是灵活,坏处是……嗯,一致性真的很难搞。我最近在做一个项目,用了Saga模式来处理跨市场的分布式事务。效果还行,但代码量比之前多了三倍。
这张图展示了三个阶段的演进脉络。你可以看到,架构越来越灵活,但复杂度也在上升。我个人更倾向于「适度演进」——在现有架构上逐步优化,而不是推倒重来。
好了,第一章就到这里。跨市场交易的核心挑战——延迟、一致性、容错——这三个问题会贯穿整个课程。后面的章节里,我会逐一展开讲具体的解决方案。
公众号:蓝海资料掘金营,微信deep3321