4. 做市交易系统架构设计
做市交易系统,说白了就是你的「电子化做市大脑」。我见过不少团队,策略很牛,但系统架构一塌糊涂,结果行情一来直接崩掉。嗯,今天我们就来拆一拆,一个合格的CDS做市系统到底该怎么搭。
4.1 核心架构分层
我个人习惯把系统分成四层。你想想看,每一层各司其职,出了问题也好定位。
| 层级 | 职责 | 关键组件 |
|---|---|---|
| 接入层 | 对接交易所/经纪商 | FIX网关、WebSocket适配器 |
| 核心层 | 定价、风控、做市逻辑 | 定价引擎、订单管理、风险计算 |
| 数据层 | 行情、成交、参考数据 | 内存数据库、时序数据库 |
| 监控层 | 实时监控、告警、回测 | Grafana、日志系统、回测框架 |
这里要注意,核心层绝对不能直接依赖外部API。我在项目中遇到过,有人把定价引擎和FIX网关写在一个进程里,结果网关一断,整个定价都挂了。血的教训。
4.2 核心模块设计
4.2.1 定价引擎
定价引擎是系统的「心脏」。它需要实时计算CDS的合理价格。我建议采用微服务架构,把定价逻辑独立部署。
// 伪代码示例:定价引擎接口
public interface PricingEngine {
// 计算CDS spread
double calculateSpread(CDSContract contract, MarketData marketData);
// 计算风险敞口
RiskMetrics calculateRisk(CDSContract contract, MarketData marketData);
// 批量定价(用于做市报价)
Map<String, Double> batchPrice(List<CDSContract> contracts, MarketData marketData);
}
为什么用微服务?因为定价计算很吃CPU。如果和订单处理混在一起,行情剧烈波动时,订单处理会被定价拖慢。我曾经见过一个系统,定价线程把CPU吃满,结果订单超时被交易所罚款。嗯,那笔罚款够买好几台服务器了。
4.2.2 订单管理模块
订单管理模块负责「生命周期管理」。从报价、成交到结算,每一步都要有状态机控制。
关键设计原则:
- 每个订单有唯一ID,全局递增
- 状态变更必须记录日志
- 支持幂等操作(防止重复处理)
我建议用事件溯源模式。说白了,就是把每个订单的「状态变化」都存下来。出了问题,可以回放事件,定位问题。我在项目中就用这个思路,有一次结算对不上账,回放事件后五分钟就找到了原因。
4.2.3 风险计算模块
做市商最怕什么?风险失控。风险计算模块要实时监控你的敞口。
// 风险计算示例
public class RiskCalculator {
// 计算当前组合的Delta、Gamma、Vega
public RiskMetrics calculatePortfolioRisk(Portfolio portfolio) {
double delta = 0;
double gamma = 0;
double vega = 0;
for (Position pos : portfolio.getPositions()) {
delta += pos.getDelta();
gamma += pos.getGamma();
vega += pos.getVega();
}
return new RiskMetrics(delta, gamma, vega);
}
// 检查是否超过风险限额
public boolean checkRiskLimit(RiskMetrics metrics, RiskLimit limit) {
return metrics.getDelta() <= limit.getMaxDelta()
&& metrics.getGamma() <= limit.getMaxGamma()
&& metrics.getVega() <= limit.getMaxVega();
}
}
注意:风险计算不能只算当前值。我建议加上「压力测试」模块,模拟极端行情下的风险变化。比如,信用利差突然跳升100bp,你的组合会亏多少?
4.3 数据流设计
数据流是系统的「血管」。我画了一张图,展示核心数据流向。
你看,数据流是单向的。行情进来,定价引擎算出报价,订单管理处理交易,风险计算实时更新。这样设计的好处是,每个模块可以独立升级、独立部署。
4.4 性能优化要点
做市系统对延迟极其敏感。我总结几个关键优化点:
- 内存数据库:行情数据、订单簿必须放内存。用Redis或自研的内存KV存储。磁盘IO是性能杀手。
- 零拷贝技术:网络数据包从网卡到应用,尽量减少拷贝次数。Linux的mmap和sendfile可以用起来。
- 线程模型:我建议用Reactor模式。一个线程处理网络IO,多个工作线程处理业务逻辑。避免锁竞争。
- 预计算:常用的定价参数、风险指标,提前算好缓存起来。别等行情来了再算。
小技巧:我曾经用「无锁队列」替代了传统的阻塞队列,订单处理延迟从微秒级降到了纳秒级。具体实现可以用Disruptor框架,性能提升非常明显。
4.5 容错与高可用
系统不能挂。挂了就是真金白银的损失。我建议做以下设计:
- 主备切换:核心模块部署双实例,一主一备。主节点挂了,备节点秒级接管。
- 数据持久化:所有订单、成交记录必须落地。用WAL(Write-Ahead Logging)保证数据不丢。
- 熔断机制:如果某个外部依赖(比如行情源)响应变慢,自动熔断,避免雪崩。
- 降级策略:极端情况下,可以关闭非核心功能(比如历史查询),保证交易链路畅通。
嗯,这里要特别强调一下。容错设计不是「锦上添花」,而是「保命符」。我见过一个团队,系统上线半年没出过问题,就觉得容错没必要。结果一次机房断电,数据全丢,损失惨重。从那以后,他们每次上线前都要做「混沌工程」测试。
4.6 监控与告警
系统跑起来之后,你怎么知道它健不健康?监控就是你的眼睛。
| 监控指标 | 告警阈值 | 说明 |
|---|---|---|
| 订单处理延迟 | > 100ms | 超过阈值说明系统有瓶颈 |
| 定价引擎CPU | > 80% | 可能需要扩容 |
| 风险敞口 | 接近限额 | 需要人工干预 |
| 网络丢包率 | > 0.1% | 可能影响行情接收 |
我建议用Grafana搭一个实时仪表盘。把关键指标可视化,一眼就能看出系统状态。告警方式也要多样化:邮件、短信、甚至电话。别问我为什么知道电话告警重要——有一次凌晨三点系统出问题,邮件没人看,短信被忽略,最后还是电话把人叫起来的。
好了,做市交易系统的架构设计就聊到这里。记住,架构没有银弹,关键是要适合你的业务场景。多测试、多复盘,系统才能越来越稳。
公众号:蓝海资料掘金营,微信deep3321