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) {
        // 查询各交易所当前深度
        // 选择最优价格的交易所
        // 返回选中的交易所
    }
}
注意:路由层不要直接调用交易所API。它只负责"选交易所",具体怎么发单,那是执行层的事。我曾经见过有人把路由和执行写在一起,结果想换路由策略时,执行代码也得跟着改,非常痛苦。

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 三层架构的协作流程

说了这么多,这三层到底是怎么配合的?我画了一张图,你看完就明白了:

三层架构协作流程图 策略层(策略引擎) 生成交易信号,决定买卖方向、数量、价格 路由层(路由引擎) 根据策略选择最优交易所,决定订单去向 执行层(执行引擎) 拆分订单、管理状态、处理异常、调用网关 统一网关层(协议转换) 将统一请求转换为各交易所API格式,处理网络通信

你看,整个流程非常清晰:策略层生成信号 → 路由层选交易所 → 执行层处理细节 → 网关层发到交易所。每一层各司其职,互不干扰。

2.6 这套架构的好处

最后说说这套架构给我带来的实际好处:

  • 扩展性强:新增交易所时,只需要在网关层加一个实现类,路由和执行层完全不用动
  • 维护方便:哪层出问题就查哪层,不用翻遍整个代码库
  • 复用性高:路由策略可以复用,执行逻辑可以复用,网关适配也可以复用
  • 测试简单:每层都可以单独写单元测试,不用启动整个系统
总结一下:三层架构不是什么高深的技术,但它能帮你把复杂的问题拆解成简单的模块。我做了这么多年量化系统,这套架构一直是我最推荐的做法。如果你现在还在用"一锅烩"的方式写代码,不妨试试这个思路,相信我,你会回来感谢我的。

专注资料整理