4. 统一交易接口设计原则
多Broker适配层最核心的资产不是某个具体Broker的对接代码,而是那层稳定、可演进、可被信任的统一交易接口。如果接口设计得随意,适配层就会退化成“把多个SDK堆在一起”的胶水代码:每接一家Broker,上层策略就要改一次;每次Broker升级,风控和账务就要跟着返工。本节围绕五条设计原则展开,帮助你把接口从“能用”做到“可长期演进”。
一、核心原理:接口是契约,不是函数集合
统一交易接口的本质,是上层业务与下层Broker之间的契约。它约定了“调用方需要提供什么”“适配层承诺返回什么”“异常如何表达”“状态如何查询”。接口抽象负责屏蔽差异,契约优先负责固化承诺,幂等性负责保证重试安全,可扩展性负责容纳新Broker与新业务,向后兼容负责让老调用方不被新版本伤害。五者不是并列的技巧,而是同一条演进链上的五个约束点。
关键判断:当你发现某个字段只有一家Broker需要、某个方法只有一种业务场景会调用、某个异常只有对接方自己看得懂时,说明接口正在被具体实现“反向塑造”。此时应回到契约层重新抽象,而不是在实现里打补丁。
二、方法流程:从契约到实现的落地步骤
- 定义领域模型:先确定订单、成交、持仓、资金、行情快照等核心对象,字段命名与语义必须与Broker无关。
- 编写接口契约:用接口定义文件或代码接口描述方法签名、参数约束、返回结构、错误码枚举。
- 设计幂等键:下单、撤单、改单等写操作必须携带客户端生成的唯一请求ID,适配层据此去重。
- 实现适配器:每个Broker一个适配器,负责协议转换、字段映射、异常归一、重试策略。
- 建立兼容性测试:用契约测试验证所有适配器行为一致,用回归用例验证老版本调用方不受影响。
其中幂等键的设计是实战中最容易被忽略的一环。推荐使用“业务类型+账户+客户端订单ID”组合,并在适配层维护短期去重表:
POST /trade/order
{
"clientOrderId": "ORD-20240612-0001",
"symbol": "BTCUSDT",
"side": "BUY",
"type": "LIMIT",
"price": "68000.00",
"qty": "0.50",
"idempotencyKey": "ORDER:acct_88:BTCUSDT:ORD-20240612-0001"
}
// 适配层去重逻辑(伪代码)
if (idempotencyStore.exists(key)) {
return idempotencyStore.get(key); // 返回首次结果,不重复下单
}
result = brokerAdapter.placeOrder(request);
idempotencyStore.save(key, result, ttl=24h);
return result;
三、案例场景:新增Broker时接口如何不返工
假设平台已接入Broker A和Broker B,现在要接入Broker C。Broker C的撤单接口要求传入“交易所订单号”而非“客户端订单号”,且返回结构与其他两家不同。如果接口设计得当,上层策略代码一行都不用改:适配层在内部完成订单号映射,并把Broker C的返回结构转换为统一撤单结果。
| 设计维度 | 反面做法 | 推荐做法 |
|---|---|---|
| 接口抽象 | 方法名带Broker前缀,如placeOrderA | 统一方法placeOrder,Broker差异下沉到适配器 |
| 契约优先 | 先写实现,再补接口文档 | 先定接口与错误码,再并行开发适配器 |
| 幂等性 | 依赖Broker自身去重 | 客户端生成幂等键,适配层统一去重 |
| 可扩展性 | 新增字段直接改公共模型 | 用扩展字段或元数据承载Broker特有信息 |
| 向后兼容 | 直接删除或重命名旧字段 | 新增字段可选,旧字段保留并标注废弃 |
四、误区与复盘:兼容性不是“以后再说”
常见误区一:把Broker特有字段直接塞进统一模型,导致模型越来越臃肿,最终无法区分哪些字段是公共契约、哪些是某家私有。
常见误区二:认为幂等性只在下单时需要。实际上撤单、改单、资金划转同样需要幂等,否则网络抖动会导致重复撤单或重复划转。
常见误区三:用“版本号”代替兼容策略。版本号只是标识,真正的兼容要靠字段可选、默认值、废弃周期和契约测试来保证。
复盘建议:每次接入新Broker后,回看三件事——上层策略是否零改动、契约测试是否全部通过、幂等去重是否覆盖所有写操作。如果三者都满足,说明接口设计经受住了扩展性考验;否则应优先重构接口,而不是继续堆适配代码。
向后兼容策略可以归纳为四条可执行规则:新增字段必须可选并有默认值;删除字段必须先标记废弃并保留至少一个发布周期;方法签名变更优先新增重载而非修改原方法;错误码只增不改,新增错误码必须归入已有分类。把这四条写进代码评审清单,统一交易接口才能在30个章节所覆盖的长期演进中保持稳定。