3. 量化实盘服务架构
量化实盘服务不是“把回测代码搬到服务器上跑”这么简单。回测里一次buy()调用只是账本上的一行记录,而实盘中它意味着:行情可能延迟、订单可能被拒、持仓可能与预期不符、网络可能中断、程序可能崩溃。因此,一个可上线的量化实盘服务,必须把行情接入、策略引擎、风控模块、订单执行、监控告警五个部分拆成职责清晰的模块,并用统一的数据契约把它们串起来。本节先建立整体架构认知,后续章节再逐个深入。
一、核心原理:五模块的职责边界
这五个模块的关系可以概括为“一条主链路 + 两条旁路”。主链路是:行情接入 → 策略引擎 → 风控模块 → 订单执行。两条旁路分别是:监控告警贯穿全链路采集指标,风控模块同时旁路监听行情与持仓状态。理解这个结构,比记住模块名字更重要。
- 行情接入:负责把交易所或数据商的原始行情(WebSocket/TCP/FIX)转换为内部统一的
Tick或Bar结构,处理断线重连、心跳、时间戳对齐、去重与乱序。 - 策略引擎:消费标准化行情,按策略逻辑计算目标仓位或信号,输出“意图订单”(Intent Order),而不是直接下单。
- 风控模块:对意图订单做前置校验——资金、持仓、单笔限额、频率、价格偏离、黑名单等,通过后才生成可执行订单。
- 订单执行:负责报单、撤单、查询、成交回报处理,维护本地订单状态机,并与交易所状态对账。
- 监控告警:采集延迟、吞吐、PnL、持仓、订单成功率等指标,异常时通过钉钉、邮件、电话等方式通知。
关键设计原则是单向数据流 + 状态可重建。策略引擎不直接触碰交易接口,风控不修改策略逻辑,执行层不判断策略对错。每个模块只做自己的事,通过消息队列或内存总线传递结构化事件。这样当出现问题时,可以快速定位是行情、策略、风控还是执行层的问题。
二、方法流程:从行情到成交的完整链路
下面以一段简化的伪代码展示主链路的事件流转。真实系统中每个环节都会异步化,但数据契约保持一致。
# 1. 行情接入层:标准化 Tick
tick = {
"symbol": "BTCUSDT",
"price": 64250.5,
"volume": 0.12,
"ts_exchange": 1718000000123,
"ts_local": 1718000000135
}
bus.publish("market.tick", tick)
# 2. 策略引擎:消费行情,输出意图订单
def on_tick(tick):
signal = strategy.compute(tick)
if signal.action != "HOLD":
intent = {
"symbol": tick.symbol,
"side": signal.action,
"qty": signal.qty,
"price": tick.price,
"strategy_id": "ma_cross_01"
}
bus.publish("strategy.intent", intent)
# 3. 风控模块:前置校验
def on_intent(intent):
if not risk.check(intent):
log.warning("risk rejected: %s", intent)
return
order = build_order(intent)
bus.publish("order.new", order)
# 4. 订单执行:报单并维护状态机
def on_order(order):
resp = exchange.place_order(order)
order.status = resp.status
store.save(order)
bus.publish("order.update", order)
这条链路中有三个容易被忽视的细节:第一,时间戳必须双记录,交易所时间和本地时间都要保留,否则无法计算端到端延迟;第二,意图订单与执行订单要分离,风控可能修改数量或拒绝,策略层不应感知执行细节;第三,所有事件必须可持久化,崩溃后能从消息总线或数据库中重建状态。
三、案例场景:一次行情断线引发的连锁反应
某实盘服务在运行中遇到交易所 WebSocket 断线 8 秒。由于行情接入层没有做重连后的快照对齐,策略引擎在恢复后收到了一批乱序 Tick,误判为趋势反转,连续发出 5 笔买入意图。风控模块只检查了单笔限额,没有检查“短时间内同方向累计仓位”,全部放行。订单执行层正常报单,最终持仓超出策略上限 3 倍。监控告警只在 PnL 回撤超过阈值时才触发,此时已经亏损。
复盘后做了三处改进:行情接入层增加断线重连后的快照同步与乱序丢弃;风控模块增加时间窗口内的累计仓位与频率限制;监控告警增加行情延迟与订单频率的实时指标。这个案例说明,五个模块不是孤立存在的,任何一个模块的薄弱都会让整条链路失效。
四、模块职责与关键指标清单
下表总结了五个模块的核心职责、关键输出和必须监控的指标,可作为架构设计时的检查清单。
| 模块 | 核心职责 | 关键输出 | 必须监控的指标 |
|---|---|---|---|
| 行情接入 | 连接交易所、标准化数据、断线重连 | 标准化 Tick/Bar 事件 | 行情延迟、丢包率、重连次数 |
| 策略引擎 | 计算信号、生成意图订单 | 意图订单事件 | 信号频率、计算耗时、异常次数 |
| 风控模块 | 前置校验、限额、频率、持仓检查 | 通过/拒绝的订单 | 拒绝率、触发规则分布、累计仓位 |
| 订单执行 | 报单、撤单、成交回报、状态对账 | 订单状态更新事件 | 报单成功率、成交延迟、状态不一致数 |
| 监控告警 | 采集指标、异常检测、通知 | 告警事件、仪表盘 | 告警响应时间、误报率、漏报率 |
最后强调一点:架构设计的目标不是“模块越多越好”,而是每个模块的失败边界清晰、可观测、可恢复。行情断了,策略不应收到脏数据;风控拒了,策略应能收到明确原因;执行层状态不一致,监控应能立即发现。把这五块拼成一个整体,量化实盘服务才具备长期稳定运行的基础。