系统架构概览:从模拟盘的单机脚本到实盘的分布式低延迟架构
说实话,很多做量化的人,一开始都是从模拟盘起步的。我自己也不例外。那时候写个Python脚本,从交易所拉数据,算个信号,再模拟下单,感觉挺爽的。但当你真正要上实盘,尤其是高频交易,你会发现——那套东西根本扛不住。
为什么?因为模拟盘和实盘,本质上是两个世界。模拟盘你关心的是策略对不对,实盘你关心的是能不能抢到单、会不会被塞单、延迟能不能压到微秒级。今天我就带你拆解一下,从单机脚本到分布式低延迟架构,到底要经历哪些蜕变。
一、模拟盘时代的“玩具架构”
先说说模拟盘。我见过太多人,包括早期的我,都是这么干的:
- 一台笔记本,跑着Python脚本
- 用pandas算指标,用matplotlib画图
- 模拟下单就是往本地日志里写一行
- 行情数据?从免费接口拉,延迟几秒都无所谓
这种架构,说白了就是“能跑就行”。你想想看,模拟盘的核心目的是验证策略逻辑,不是验证系统性能。所以单线程、单进程、单机,完全够用。
核心问题:模拟盘架构假设“市场是静止的”。你算完信号再下单,市场不会因为你慢而改变。但实盘不是这样——你慢1毫秒,单子就被别人抢走了。
二、实盘架构的三大核心挑战
从模拟盘切换到实盘,你首先要面对三个问题:
- 延迟——从行情到达到你发出订单,时间必须可控
- 吞吐——每秒处理几千笔订单,单机Python扛不住
- 可靠性——系统不能挂,挂了就是真金白银的损失
嗯,这里要注意:这三个问题不是独立的。你为了降低延迟,可能会牺牲吞吐;为了可靠性,又可能增加延迟。所以架构设计,本质上是在这三者之间找平衡。
三、分布式低延迟架构的核心组件
我个人习惯把实盘系统拆成五个核心组件。每个组件都有明确的职责,而且必须独立部署、独立优化。
| 组件 | 职责 | 模拟盘对应物 | 实盘要求 |
|---|---|---|---|
| 行情网关 | 接收交易所行情,解码,分发 | 免费API拉数据 | 微秒级解码,组播分发 |
| 策略引擎 | 计算信号,生成订单 | Python脚本 | C++实现,无锁队列 |
| 订单管理 | 管理订单生命周期,风控检查 | 无 | 状态机,超时处理 |
| 交易网关 | 连接交易所,发送订单,接收回报 | 无 | FIX协议,会话管理 |
| 监控系统 | 记录日志,监控延迟,报警 | print() | 实时监控,毫秒级报警 |
你看,模拟盘里很多组件根本不存在。比如订单管理,模拟盘你不需要管订单到底成交了没有,但实盘里,订单可能被拒、被部分成交、被撤销,你必须有一套状态机来管理这一切。
四、架构演进路线:从单机到分布式
我建议你不要一步到位。直接上分布式架构,你可能会被复杂度压垮。我自己的经验是分三步走:
第一步:单机多进程
还是用一台机器,但把行情、策略、交易拆成三个进程。进程间用共享内存通信。这样延迟比Python脚本低一个数量级,而且一个进程挂了不会影响其他进程。
避坑指南:我曾经在单机多进程架构里,直接用Python的multiprocessing.Queue做进程间通信。结果发现延迟不稳定,有时候会卡几十毫秒。后来换成共享内存+无锁队列,延迟才稳定在微秒级。
第二步:多机分离
行情网关单独放一台机器,策略引擎放另一台,交易网关再放一台。这样做的目的是:行情数据量大,容易把CPU打满,分离后策略引擎不会受影响。
第三步:全分布式低延迟
到了这一步,你就要考虑网络拓扑了。行情网关和策略引擎之间用RDMA或者共享内存网络,策略引擎和交易网关之间用低延迟消息队列。每一跳的延迟都要控制在微秒级。
五、一张图看懂架构
下面这张图,是我自己画的一个典型高频交易系统架构。你看一眼,应该就能明白各个组件是怎么配合的。
六、核心组件深度拆解
接下来,我挑几个关键组件,说说它们内部是怎么设计的。
1. 行情网关:第一道关卡
行情网关是系统的入口。它的任务很简单:从交易所拿到行情数据,解码,然后分发给策略引擎。但简单的事情,在高频场景下就变得不简单了。
我记得有一次,交易所改了行情协议,把某个字段的偏移量调了2个字节。我们的行情网关没更新,结果解码出来的价格全是错的。策略引擎根据错误价格下了单,亏了不少钱。从那以后,我要求行情网关必须做两件事:
- 校验和检查——确保数据没有被篡改
- 字段边界检查——确保解码不会越界
警告:行情网关绝对不能成为瓶颈。如果行情网关处理不过来,行情数据就会堆积,延迟就会飙升。我建议用C++实现,并且用零拷贝技术,直接从网卡DMA到用户态。
2. 策略引擎:大脑
策略引擎是真正做决策的地方。它拿到行情,算指标,然后决定要不要下单。
在模拟盘里,策略引擎可能是一个Python函数,算完就完事了。但在实盘里,策略引擎必须考虑:
- 计算延迟——每个指标必须在规定时间内算完
- 状态管理——策略可能有持仓、有挂单,这些状态必须正确维护
- 回测一致性——实盘算出来的信号,必须和回测时一模一样
我个人习惯用C++写策略引擎,因为Python的GIL在高频场景下太坑了。你想想看,Python一个线程在算指标,另一个线程在发订单,GIL一锁,两个都动不了。
3. 订单管理:风控的最后一道防线
订单管理这个组件,很多人会忽略。但我觉得它是最重要的。为什么?因为它是风控的最后一道防线。
策略引擎可能会犯错,交易网关可能会断连,但订单管理必须保证:
- 同一个订单不会重复发送
- 超时的订单会被撤销
- 资金不够时,订单会被拒绝
我曾经在订单管理里加过一个“自毁机制”:如果订单管理检测到某个订单超过5秒没有回报,它会自动撤销这个订单,并且暂停策略引擎。这个机制救过我很多次。
七、总结:架构设计的核心原则
说了这么多,我想总结几条核心原则。这些原则是我做了这么多年高频交易系统,踩了无数坑之后总结出来的:
- 解耦——每个组件只做一件事,做好一件事
- 无锁——能不用锁就不用锁,锁是延迟的根源
- 可观测——每个组件都必须暴露延迟、吞吐、错误率等指标
- 渐进式——不要一步到位,从单机到分布式,一步步来
嗯,最后说一句:架构设计没有银弹。每个系统都有自己的特点,你需要根据你的策略、你的资金量、你的交易所,来调整架构。但不管怎么调,上面这几个核心组件,你一个都不能少。