第三章 系统架构设计:量化交易系统的整体架构、数据层、策略层、执行层、风控层的职责划分

做量化交易系统,说白了就是在搭一座精密的大楼。

我见过太多人一上来就写策略代码,结果数据源一换、接口一改,整个系统就崩了。嗯,这里要强调一下:架构设计不是花架子,它是你系统能跑多久、跑多稳的根基。

3.1 整体架构:四层模型

我个人习惯把量化交易系统拆成四层:数据层、策略层、执行层、风控层。每一层各司其职,层与层之间通过标准接口通信。

核心原则:每一层只关心自己的事。数据层不管策略怎么算,策略层不管订单怎么发,执行层不管风控怎么拦。耦合度越低,系统越稳。

先看一张整体架构图,方便你理解各层的关系:

量化交易系统四层架构图 数据层 (Data Layer) 行情数据 · 历史数据 · 清洗与存储 · 实时推送 策略层 (Strategy Layer) 信号生成 · 策略引擎 · 参数管理 · 回测框架 执行层 (Execution Layer) 订单管理 · 路由算法 · 交易所接口 · 成交回报 风控层 (Risk Control Layer) 事前检查 · 事中监控 · 事后分析 · 熔断机制 数据流 信号流 订单流 风控流 层间接口标准化

3.2 数据层:系统的血液

数据层是量化交易系统的起点。没有干净的数据,再牛的策略也是白搭。

数据层主要干三件事:

  • 数据采集:从交易所、数据商那里拉行情。包括 tick 级、1 分钟、日线等不同粒度。
  • 数据清洗:去重、补全、对齐时间戳。我曾经遇到过某数据商凌晨 3 点会漏发几笔 tick,导致策略在回测时多赚了 2%。
  • 数据存储:历史数据用列式存储(比如 Parquet),实时数据用内存数据库(比如 Redis)。

避坑指南:我曾经在数据对齐上栽过跟头。不同交易所的时间戳精度不一样,有的到毫秒,有的到微秒。不统一对齐,策略信号就会错位。建议统一转成 UTC 纳秒时间戳。

3.3 策略层:大脑所在

策略层是量化系统的核心。它接收数据层的清洗数据,输出交易信号。

策略层包含几个关键模块:

模块 职责 我踩过的坑
信号生成器 根据指标计算买卖信号 指标参数写死在代码里,改一次要重新编译
策略引擎 管理多个策略的生命周期 策略之间互相干扰,一个崩了全崩
参数管理器 动态调整策略参数 参数没做版本管理,回测结果对不上
回测框架 模拟历史行情验证策略 滑点设置太理想,实盘直接亏

你想想看,策略层最怕什么?最怕「回测猛如虎,实盘亏成狗」。原因往往出在数据偏差和过拟合上。

3.4 执行层:手脚要快

执行层负责把策略层的信号变成真实的订单,发到交易所。

执行层的核心能力就两个字:

  • 订单管理:维护订单状态机(新建→已报→部分成交→全部成交→已撤单)。
  • 路由算法:选择最优的交易所或流动性池。比如做市策略需要把大单拆成小单,减少市场冲击。
  • 交易所接口:FIX 协议或 REST API。我个人习惯用 FIX,虽然配置麻烦,但延迟低、稳定性高。
  • 成交回报处理:收到交易所的成交确认后,更新本地状态。

注意:执行层最容易出问题的地方是「订单状态不一致」。比如你发了撤单指令,但交易所还没处理完,结果又发了一笔新订单。我曾经因为这个原因,在实盘中多开了一倍仓位。

3.5 风控层:最后的防线

风控层是量化系统的安全网。它不产生利润,但能防止你亏光。

风控层分三个阶段:

  1. 事前检查:下单前检查账户余额、持仓限制、单笔最大金额。比如你策略要开 100 手 BTC,风控先看看账户够不够保证金。
  2. 事中监控:实时监控持仓盈亏、波动率、敞口。如果浮亏超过阈值,自动减仓或平仓。
  3. 事后分析:每天收盘后跑风控报告,检查是否有异常交易、违规操作。

说白了,风控层就是你的「刹车系统」。你可以开得快,但刹车必须灵。

核心原则:风控层必须独立于其他三层。不能因为策略层挂了,风控也跟着挂。我见过有人把风控逻辑写在策略代码里,结果策略死循环,风控也跟着失效了。

3.6 层间通信:接口设计

四层之间怎么通信?我个人建议用消息队列(比如 Kafka 或 RabbitMQ)。

举个例子,数据层到策略层的接口:

// 数据层推送行情
message MarketData {
    string symbol = 1;      // 合约代码
    double price = 2;       // 最新价
    double volume = 3;      // 成交量
    int64 timestamp = 4;    // 时间戳(纳秒)
}

// 策略层输出信号
message Signal {
    string strategy_id = 1; // 策略ID
    string symbol = 2;      // 合约代码
    string action = 3;      // BUY / SELL
    double quantity = 4;    // 数量
    double price = 5;       // 目标价格
}

这样做的好处是:每一层都可以独立升级、独立部署。数据层换数据源,策略层不用改一行代码。

3.7 架构设计的几个坑

最后分享几个我亲身踩过的坑:

  • 坑一:所有层跑在同一个进程里。一个模块 OOM,整个系统挂掉。后来我改成每层独立进程,用 IPC 通信。
  • 坑二:风控层放在执行层后面。结果订单都发出去了,风控才说不行。正确的做法是风控层拦截在策略层和执行层之间。
  • 坑三:日志打得太少。系统出问题时,根本不知道是哪一层出了问题。我现在每层都打关键日志,并且带上时间戳和请求 ID。

嗯,架构设计没有银弹。但记住一点:分层清晰、接口稳定、风控独立,你的系统至少不会在第一天就崩掉。