2、多交易所架构设计:统一网关层、路由层、执行层三层架构详解
做量化交易的朋友都知道,同时对接多个交易所是个大坑。每个交易所的API格式不一样,限频规则不一样,甚至网络延迟都不一样。我刚开始做这套系统的时候,就吃过这个亏——代码写了一大堆,结果换个交易所就得重写一半逻辑。
后来我总结出一套三层架构,说白了就是:统一网关层、路由层、执行层。这套架构帮我省了不少事,今天咱们就好好聊聊。
2.1 为什么需要三层架构?
你想想看,如果每个交易所都单独写一套代码,会是什么后果?
- 代码重复率极高,维护成本爆炸
- 新增交易所时,改动范围太大
- 订单路由逻辑和交易执行逻辑混在一起,调试起来想死的心都有
我在项目中遇到过最惨的一次:因为某个交易所改了API版本,我花了整整两天去排查到底是哪段代码出了问题。后来发现,订单路由和交易所适配代码写在了同一个文件里……嗯,从那以后我就下定决心,必须分层。
2.2 统一网关层:你的"翻译官"
统一网关层,说白了就是给所有交易所套上一层"马甲"。不管底层是币安、OKX还是火币,上层看到的接口都是一样的。
我个人习惯的做法是:定义一个抽象基类,里面包含所有交易所共有的操作——比如下单、撤单、查询持仓、获取行情。然后每个交易所实现这个基类。
// 伪代码示例
abstract class ExchangeGateway {
// 统一的下单接口
abstract Order placeOrder(OrderRequest request);
// 统一的撤单接口
abstract boolean cancelOrder(String orderId);
// 统一的持仓查询
abstract Position getPosition(String symbol);
}
// 币安实现
class BinanceGateway extends ExchangeGateway {
@Override
Order placeOrder(OrderRequest request) {
// 将统一请求转换为币安格式
// 调用币安API
// 返回统一格式的Order对象
}
}
// OKX实现
class OkxGateway extends ExchangeGateway {
@Override
Order placeOrder(OrderRequest request) {
// 将统一请求转换为OKX格式
// 调用OKXAPI
// 返回统一格式的Order对象
}
}
2.3 路由层:你的"交通指挥"
路由层是三层架构里最核心的一层。它的职责很简单:决定这笔订单该发到哪个交易所。
为什么需要路由层?因为不同交易所的流动性、手续费、延迟都不一样。比如某个币种在币安深度最好,但OKX的手续费更低。这时候路由层就要根据策略需求,做出最优选择。
我常用的路由策略有几种:
| 策略名称 | 适用场景 | 优缺点 |
|---|---|---|
| 最优价格路由 | 大单交易,追求最优成交价 | 成交价好,但可能延迟较高 |
| 最低延迟路由 | 高频交易,追求速度 | 速度快,但可能牺牲价格 |
| 负载均衡路由 | 多交易所同时交易 | 分散风险,但管理复杂 |
| 智能路由 | 综合多种因素 | 灵活,但实现复杂 |
路由层的实现其实不复杂,核心就是一个策略引擎:
// 路由策略接口
interface RoutingStrategy {
Exchange selectExchange(OrderRequest request);
}
// 最优价格路由实现
class BestPriceRouting implements RoutingStrategy {
@Override
Exchange selectExchange(OrderRequest request) {
// 查询各交易所当前深度
// 选择最优价格的交易所
// 返回选中的交易所
}
}
2.4 执行层:你的"操盘手"
执行层是三层架构里最"接地气"的一层。它负责把路由层选定的订单,真正发到交易所去执行。
执行层要处理的事情其实挺多的:
- 订单拆分:大单要拆成小单,避免影响市场
- 重试机制:网络超时了怎么办?要不要重试?
- 状态管理:订单是已提交、部分成交还是完全成交?
- 异常处理:交易所返回错误码了,怎么处理?
我个人习惯在执行层里维护一个"订单状态机",这样能清晰地管理每个订单的生命周期:
// 订单状态枚举
enum OrderStatus {
PENDING, // 待提交
SUBMITTED, // 已提交
PARTIAL_FILLED, // 部分成交
FILLED, // 完全成交
CANCELLED, // 已撤销
FAILED // 失败
}
// 执行层核心逻辑
class ExecutionEngine {
void execute(OrderRequest request, Exchange exchange) {
// 1. 检查订单状态
// 2. 如果需要,拆分订单
// 3. 调用网关层发单
// 4. 监听成交回报
// 5. 更新订单状态
}
}
2.5 三层架构的协作流程
说了这么多,这三层到底是怎么配合的?我画了一张图,你看完就明白了:
你看,整个流程非常清晰:策略层生成信号 → 路由层选交易所 → 执行层处理细节 → 网关层发到交易所。每一层各司其职,互不干扰。
2.6 这套架构的好处
最后说说这套架构给我带来的实际好处:
- 扩展性强:新增交易所时,只需要在网关层加一个实现类,路由和执行层完全不用动
- 维护方便:哪层出问题就查哪层,不用翻遍整个代码库
- 复用性高:路由策略可以复用,执行逻辑可以复用,网关适配也可以复用
- 测试简单:每层都可以单独写单元测试,不用启动整个系统