第二章:系统架构设计
好,咱们直接进入正题。系统架构设计,说白了就是给整个交易系统画一张「施工蓝图」。我做了这么多年量化,见过太多人一上来就写代码,写到一半发现数据流不通,或者模块之间耦合得死死的,改一个地方崩一片。嗯,这章咱们就把这事彻底理清楚。
2.1 整体架构图:先看全局
我个人习惯,设计任何系统之前,先画一张架构图。不是为了好看,是为了让自己和团队一眼看明白:数据从哪来、经过谁、最终去哪。
核心架构分层(我常用的四层模型):
- 数据层:行情数据、历史数据、新闻舆情
- 策略层:信号生成、风险控制、订单管理
- 执行层:订单路由、交易所对接、滑点控制
- 监控层:日志、告警、回测、绩效分析
下面这张 SVG 图,是我自己项目里常用的架构简化版。你仔细看,数据流是单向的,但监控层是双向的——这一点很多人会忽略。
💡 我的经验: 别把监控层当成事后诸葛亮。我早期一个项目,监控层只记录日志,结果策略跑偏了三天才发现。后来我把监控层做成实时反馈回路,任何异常都能秒级告警。你想想看,这差别有多大。
2.2 数据流设计:钱是怎么流动的
数据流设计,说白了就是回答三个问题:数据从哪来?经过谁?最终去哪?
我习惯把数据流分成两条线:
- 实时数据流:行情 tick → 策略计算 → 订单生成 → 交易所执行 → 成交回报
- 离线数据流:历史数据 → 回测引擎 → 策略优化 → 参数更新 → 部署上线
这两条线不能混。我曾经犯过一个错,把回测用的历史数据和实时行情放在同一个管道里,结果回测时误触发了实盘订单。嗯,从那以后我严格隔离了这两条流。
数据流设计的关键原则:
- 单向流动:数据只能从上往下流,不能反向
- 无状态处理:每个处理节点不保存状态,方便水平扩展
- 缓冲机制:每个节点之间加消息队列,防止背压
- 幂等性:同一个数据重复处理,结果必须一致
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 一次架构图,看看哪些模块需要重构,哪些技术需要升级。系统是活的,别让它僵死。