第20章:风控系统架构

做市商的风控系统,说白了就是你的「交易刹车系统」。

我见过太多团队,策略赚钱时觉得风控是累赘,等爆仓了才后悔没装刹车。嗯,今天我们就来聊聊,一套完整的做市商风控系统到底该怎么搭。

一、实时风控引擎:你的第一道防线

实时风控引擎,就是盯着每一笔交易、每一个订单的「哨兵」。它必须在毫秒级做出判断——这个订单能不能发?这个仓位有没有超限?

核心指标:延迟必须控制在 1ms 以内,否则你的策略可能已经亏完了,风控才反应过来。

我个人习惯把实时风控拆成三层:

  • 订单级风控:检查单笔订单的金额、数量、价格是否合理。比如,你设置的卖单价格不能偏离市场中间价超过 5%。
  • 账户级风控:监控总敞口、总保证金、总盈亏。一旦某个指标触线,立即熔断。
  • 策略级风控:每个策略单独设限。我记得有一次,一个策略因为 bug 疯狂下单,幸好策略级风控先拦住了,没让整个账户出事。

代码实现上,我推荐用事件驱动架构:

// 伪代码示例:实时风控引擎核心逻辑
class RealtimeRiskEngine {
    async onOrder(order) {
        // 1. 订单级检查
        if (order.price > this.getMaxPrice()) {
            return { pass: false, reason: '价格超限' };
        }
        // 2. 账户级检查
        if (this.account.exposure + order.amount > this.maxExposure) {
            return { pass: false, reason: '敞口超限' };
        }
        // 3. 策略级检查
        if (this.strategy.dailyLoss > this.strategy.maxDailyLoss) {
            return { pass: false, reason: '策略日亏损超限' };
        }
        return { pass: true };
    }
}

注意:实时风控引擎不能依赖数据库查询。我曾经见过一个团队,每次风控检查都去查 MySQL,结果延迟飙到 50ms,直接导致策略失效。正确的做法是用内存缓存 + 流式计算。

二、离线风控分析:事后复盘才是真功夫

实时风控管的是「当下」,离线风控管的是「过去和未来」。

说白了,离线分析就是把你一天、一周、一个月的交易数据拉出来,看看风控规则有没有漏掉什么,有没有误杀什么。

我一般会做这几件事:

  • 回测风控规则:用历史数据跑一遍,看看哪些规则触发了,哪些没触发。有没有该触发却没触发的情况?
  • 压力测试:模拟极端行情,比如 2010 年闪电崩盘,看看你的风控系统扛不扛得住。
  • 归因分析:每一笔亏损,是策略问题还是风控问题?我曾经发现,某个策略的亏损其实是因为风控规则太严,导致该赚的钱没赚到。

小技巧:离线分析的结果,要能自动生成报告,推送到你的手机或邮箱。我习惯每天早上看一份「昨日风控简报」,心里才有底。

三、风控数据管道:让数据流动起来

风控系统离不开数据。订单数据、成交数据、行情数据、账户数据……这些数据必须实时、准确地流到风控引擎里。

我推荐用 Kafka 作为数据总线:

# 数据管道拓扑示例
# 行情数据 -> Kafka -> 实时风控引擎
# 订单数据 -> Kafka -> 实时风控引擎
# 成交数据 -> Kafka -> 离线分析系统
# 账户数据 -> Kafka -> 实时风控引擎 + 离线分析系统

为什么要用 Kafka?因为它能保证数据不丢、不重复,而且吞吐量极高。我见过用 RabbitMQ 做风控数据管道的,结果行情一爆发,队列直接堵死,风控系统就瞎了。

避坑指南:我曾经犯过一个错误——把风控数据和交易数据混在同一个 Kafka 集群里。结果交易数据量太大,把风控数据的 topic 给挤爆了。后来我强制要求:风控数据必须用独立的 Kafka 集群,物理隔离。

四、风控API设计:对外暴露的「安全门」

风控系统不能只是一个黑盒子,它需要对外提供 API,让其他系统(比如交易系统、监控系统、报表系统)能调用。

我设计风控 API 时,遵循几个原则:

  • 简单:每个 API 只做一件事。比如 /risk/check-order 只检查订单,/risk/check-account 只检查账户。
  • 快速:API 响应时间必须小于 1ms。如果做不到,那就用异步方式,先返回一个 token,等结果出来再回调。
  • 可观测:每个 API 调用都要有日志、有监控。我习惯给每个 API 加上 trace ID,方便排查问题。

举个例子:

// 风控 API 示例
POST /risk/v1/check-order
{
    "order_id": "12345",
    "symbol": "BTC/USDT",
    "side": "sell",
    "price": 50000,
    "amount": 1.0
}

// 返回结果
{
    "pass": true,
    "risk_id": "risk_abc123",
    "checks": [
        {"name": "price_limit", "pass": true},
        {"name": "exposure_limit", "pass": true},
        {"name": "strategy_loss_limit", "pass": true}
    ]
}

个人经验:API 的返回结果一定要包含「检查明细」。这样当风控拒绝了一个订单,交易员能立刻知道是哪个规则触发了,而不是一脸懵逼地来问你。

五、整体架构图

下面这张图,是我做风控系统时最常用的架构。你想想看,数据从行情、订单、账户三个方向流入,经过 Kafka 分发,实时风控引擎和离线分析系统各司其职,最后通过 API 对外提供服务。

做市商风控系统架构图 行情数据 订单数据 账户数据 Kafka 数据总线 实时风控引擎 订单级 / 账户级 / 策略级 离线风控分析 回测 / 压力测试 / 归因分析 风控 API 服务 数据源 消息队列 处理层 服务层

这张图看起来简单,但每个模块背后都有大量细节。比如实时风控引擎里,我用了 Redis 做状态缓存,用 Lua 脚本做原子性检查,确保在高并发下不会出现竞态条件。

总结一下:实时风控引擎负责「快」,离线风控分析负责「全」,数据管道负责「稳」,API 负责「通」。四者缺一不可。

嗯,这套架构我用了三年,经历过几次极端行情,也扛过几次系统故障。不能说它完美,但至少让我睡得着觉。

交易系统化学习资料 微信Strategy888888