Pricing Engine Integration
ODTS-69: 定价引擎集成架构——ACP 三件套如何对话
目标读者:需要理解”交易录入后,价格是怎么算出来的、系统之间怎么传”的 BA/PM
基于真实代码证据:本文架构取自
odts1三个仓库的实际代码结构——hedging-as 的ProtoBufServer/ProtoBufClient(MINA+TCP+Protobuf)、eds-web-app 的EdsAppServer+HedgingRpcService+ hedgingAs 的 protobuf 消息类、以及 hedging-as 的com/cicc/pricingengine/*PRICING*.java。
1. 为什么定价引擎是”独立的”
定价引擎 (Pricing Engine) 不能嵌在 Web 应用里,原因(基于 51 文档单体天花板教训):
- 算力隔离:蒙特卡洛、曲线构建吃 CPU。和 Web 应用抢资源 = 用户点个按钮卡 5 秒。
- 稳定性隔离:定价崩了不能把交易录入也带崩。
- 复用:一个引擎服务所有前端(交易员、风险、客户终端,见 37/41/42 文档)。
所以 ODTS 把定价抽成独立服务。问题来了:独立服务之间怎么通信?
2. ACP 三件套:独立进程的”应用集群”
ODTS 把一个大型应用拆成三个独立可部署的进程(基于 hedging-as 的 com/cicc/odts 与 eds-web-app 的 HedgingRpcService 命名线索):
┌─────────────────┐ MINA + TCP + Protobuf ┌──────────────────┐
│ eds-web-app │ ◄─────────────────────────────► │ hedging-as │
│ (Web/业务/簿记) │ ProtoBufServer / Client │ (对冲/风控/AS) │
│ EdsAppServer │ │ ProtoBufServer │
└─────────────────┘ └────────┬─────────┘
│ 同进程内调用
▼
┌──────────────────┐
│ pricing engine │
│ FICCIRSPRICING │
│ FICCOPTION... │
└──────────────────┘
- eds-web-app:面向用户的 Web 层 + 簿记 (booking) + 业务编排。它持有交易数据,但不算价格。
- hedging-as(Hedging Application Server):对冲/风控服务,它调用定价引擎。
- pricing engine:纯计算,输出价格/greeks/敏感度(喂给 67 文档的 SIMM)。
ACP = Application Cluster Process:把原本一个巨型
eds-web-app(见 34 文档,36,275 次提交、单体十年)按”算力/稳定性/复用”切成三个进程,用 MINA 这个 NIO 框架做 TCP 长连接通信。
3. 通信机制:MINA + Protobuf 是什么,为什么这么选
3.1 Protobuf(协议缓冲区)
- 不是 JSON,是二进制序列化。同样一条”报价消息”,Protobuf 比 JSON 小 3-10 倍、解析快一个数量级。
- 证据:eds-web-app 里
com/framework/protobuf/hedgingAs/quotation/BeanQuotation.java、MsgQuotationUpdateAction.java等——CSA/报价通过 Protobuf 消息在系统间传。
3.2 MINA(Apache MINA,NIO 框架)
- 传统 Socket 一个连接一个线程,几千并发就崩。MINA 用事件驱动 (Reactor),少量线程撑上万连接。
- 证据:hedging-as 的
ProtoBufServer/ProtoBufClient/ProtoBufServerHandler—— 服务端监听、客户端连接、消息 handler,典型的 MINA 模式。 - 还带
HeartbeatFactory/ClientKeepAliveFactoryImp/ReconnectionTimerTask—— 心跳保活 + 断线重连,这是长连接服务的标配(断了交易员的报价就没了)。
3.3 消息模式:请求-响应 + 推送
- 交易录入后,eds-web-app 发一条
MsgQuotationUpdateAction给 hedging-as → hedging-as 调定价引擎 → 回BeanQuotation给 eds-web-app。 - 市场行情变动时,hedging-as 主动推
MsgQuotationUpdateAction给所有订阅的客户端(交易员终端实时刷新)。
4. 集成模式图谱(给 PM 的四种选型)
| 模式 | 例子 | 优点 | 缺点 |
|---|---|---|---|
| 进程内调用 | hedging-as → pricing engine | 最快、最简单 | 无隔离 |
| TCP 长连接 (MINA) | eds-web-app ↔ hedging-as | 低延迟、支持推送 | 自己管连接/心跳 |
| REST/HTTP | 对外报送 (见 19/70) | 松耦合、易调试 | 慢、无推送 |
| 消息队列 (ActiveMQ) | 异步批处理 | 削峰、解耦 | 延迟高、难追踪 |
ODTS 的选法是:对延迟敏感的(报价、风控)用 TCP 长连接;对可靠性敏感的(报送、对账)用消息队列或批处理文件。
5. PM/BA 的三条工程启示(基于代码证据)
- 定价是”服务”,不是”函数”:改定价引擎的接口 = 改 Protobuf 契约 = 所有调用方(eds-web-app、终端)都要重新对接(见 10 文档”5 层字段链”的跨进程版)。
- 心跳/重连不是可选项:
ReconnectionTimerTask的存在说明断线在生产是常态。没有自动重连,一个网络闪断 = 交易员半天看不到报价。 - 算力隔离是单体拆分的真正动机(呼应 51 文档):不是”架构好看”,是”定价把 Web 拖垮了,必须物理隔离”。
一句话总结: ODTS 的定价集成 = 把计算抽成独立进程,用 MINA 长连接 + Protobuf 二进制做低延迟对话。对 BA 来说,理解”哪个系统持有数据、哪个系统算价格、它们之间用什么传”,是画对系统架构图(见 25 文档)的前提。