第二章:系统架构设计

好,咱们直接进入正题。系统架构设计,说白了就是给整个交易系统画一张「施工蓝图」。我做了这么多年量化,见过太多人一上来就写代码,写到一半发现数据流不通,或者模块之间耦合得死死的,改一个地方崩一片。嗯,这章咱们就把这事彻底理清楚。

2.1 整体架构图:先看全局

我个人习惯,设计任何系统之前,先画一张架构图。不是为了好看,是为了让自己和团队一眼看明白:数据从哪来、经过谁、最终去哪。

核心架构分层(我常用的四层模型):

  • 数据层:行情数据、历史数据、新闻舆情
  • 策略层:信号生成、风险控制、订单管理
  • 执行层:订单路由、交易所对接、滑点控制
  • 监控层:日志、告警、回测、绩效分析

下面这张 SVG 图,是我自己项目里常用的架构简化版。你仔细看,数据流是单向的,但监控层是双向的——这一点很多人会忽略。

金融Agent自动交易系统架构图 数据层 行情数据(WebSocket) 历史数据(数据库) 新闻舆情(API) 数据清洗 → 标准化 → 缓存 策略层 信号生成(技术指标/ML模型) 风险控制(仓位/止损) 订单管理(订单簿) 策略调度 → 信号合并 → 决策输出 执行层 订单路由(最优路径) 交易所对接(REST/WebSocket) 滑点控制(TWAP/VWAP) 执行反馈 → 成交确认 → 状态更新 监控层 日志系统 告警通知 回测引擎 绩效分析 监控反馈(双向)

💡 我的经验: 别把监控层当成事后诸葛亮。我早期一个项目,监控层只记录日志,结果策略跑偏了三天才发现。后来我把监控层做成实时反馈回路,任何异常都能秒级告警。你想想看,这差别有多大。

2.2 数据流设计:钱是怎么流动的

数据流设计,说白了就是回答三个问题:数据从哪来?经过谁?最终去哪?

我习惯把数据流分成两条线:

  • 实时数据流:行情 tick → 策略计算 → 订单生成 → 交易所执行 → 成交回报
  • 离线数据流:历史数据 → 回测引擎 → 策略优化 → 参数更新 → 部署上线

这两条线不能混。我曾经犯过一个错,把回测用的历史数据和实时行情放在同一个管道里,结果回测时误触发了实盘订单。嗯,从那以后我严格隔离了这两条流。

数据流设计的关键原则:

  1. 单向流动:数据只能从上往下流,不能反向
  2. 无状态处理:每个处理节点不保存状态,方便水平扩展
  3. 缓冲机制:每个节点之间加消息队列,防止背压
  4. 幂等性:同一个数据重复处理,结果必须一致

2.3 模块划分:拆得越细,改得越爽

模块划分这事,我踩过不少坑。早期我喜欢搞「大而全」的模块,一个模块管所有。结果呢?改一个 bug 要重启整个系统。后来我学乖了,按职责拆成微服务。

下面是我现在常用的模块划分方案:

模块名称 核心职责 关键技术 我踩过的坑
数据采集模块 对接交易所行情、新闻源 WebSocket、REST API 连接断开后重连逻辑没写好,丢数据
策略引擎模块 信号生成、策略调度 Python、NumPy、Pandas 回测和实盘信号不一致,参数没对齐
风控模块 仓位计算、止损检查 独立进程、高优先级 风控逻辑写在策略里,改策略时误删了
订单执行模块 订单路由、交易所对接 Node.js、Go 并发订单时出现重复下单
监控告警模块 日志、指标、告警 Prometheus、Grafana 告警阈值设得太低,半夜被吵醒
回测模块 历史数据回放、绩效计算 Python、向量化计算 回测结果漂亮,实盘一塌糊涂

⚠️ 特别注意: 风控模块一定要独立部署。我见过有人把风控逻辑写在策略代码里,结果策略出 bug 时风控也跟着失效了。风控模块应该是一个「断头台」——不管策略怎么疯,它都能一刀切下去。

2.4 技术选型:Python vs Node.js vs Go

技术选型这事,没有银弹。我三个语言都用过,说说我的真实感受。

Python:策略开发的首选

Python 在量化领域就是「老大哥」。为什么?生态太强了。NumPy、Pandas、Scikit-learn、TensorFlow,你要啥有啥。我个人习惯用 Python 做策略原型开发和回测,开发效率极高。

但 Python 的短板也很明显:慢。尤其是高频场景,Python 的 GIL 锁会让你抓狂。我曾经用 Python 做 tick 级别的策略,结果计算延迟比行情延迟还大。嗯,后来我把执行层换成了 Go。

Node.js:中间层的瑞士军刀

Node.js 的异步 I/O 模型,特别适合做数据中转和消息处理。我在项目中用 Node.js 做数据采集和 WebSocket 服务,性能非常稳定。

为什么选它?因为 Node.js 处理并发连接的能力很强,而且 npm 生态里有现成的交易所 SDK。你想想看,对接 10 个交易所,用 Node.js 可能一天就搞定了。

Go:执行层的性能担当

Go 是我最近两年才认真用的。说实话,真香。Go 的并发模型(goroutine + channel)简直就是为交易系统量身定做的。订单路由、滑点控制、交易所对接,这些对延迟敏感的任务,Go 是首选。

我记得有一次,我把一个 Python 写的订单执行模块用 Go 重写,延迟从 50ms 降到了 2ms。客户当场就惊呆了。

我的技术选型建议:

  • 策略开发/回测:Python(生态强、开发快)
  • 数据采集/消息中间件:Node.js(异步 I/O、并发强)
  • 订单执行/高频交易:Go(延迟低、并发安全)
  • 监控/告警:Python + Go 混合(Python 做分析,Go 做采集)

2.5 避坑指南:我踩过的那些坑

最后,分享几个我亲身经历的血泪教训:

  • 坑一:数据流没加缓冲。有一次行情爆发,数据量暴增,直接把策略进程打挂了。后来我在每个节点之间加了 Kafka 做缓冲,再也没出过问题。
  • 坑二:模块耦合太紧。早期我把策略和风控写在一个进程里,结果策略升级时不小心把风控逻辑覆盖了。后来强制要求每个模块独立部署,接口用 Protobuf 定义。
  • 坑三:技术选型跟风。有一阵子 Rust 很火,我非要拿 Rust 写策略引擎。结果开发周期翻了三倍,性能提升却微乎其微。选技术要看场景,不要看热度。

💡 最后说一句: 架构设计不是一次性的。我每半年会 review 一次架构图,看看哪些模块需要重构,哪些技术需要升级。系统是活的,别让它僵死。


专注资料整理