系统架构概览:从模拟盘的单机脚本到实盘的分布式低延迟架构

说实话,很多做量化的人,一开始都是从模拟盘起步的。我自己也不例外。那时候写个Python脚本,从交易所拉数据,算个信号,再模拟下单,感觉挺爽的。但当你真正要上实盘,尤其是高频交易,你会发现——那套东西根本扛不住。

为什么?因为模拟盘和实盘,本质上是两个世界。模拟盘你关心的是策略对不对,实盘你关心的是能不能抢到单、会不会被塞单、延迟能不能压到微秒级。今天我就带你拆解一下,从单机脚本到分布式低延迟架构,到底要经历哪些蜕变。

一、模拟盘时代的“玩具架构”

先说说模拟盘。我见过太多人,包括早期的我,都是这么干的:

  • 一台笔记本,跑着Python脚本
  • 用pandas算指标,用matplotlib画图
  • 模拟下单就是往本地日志里写一行
  • 行情数据?从免费接口拉,延迟几秒都无所谓

这种架构,说白了就是“能跑就行”。你想想看,模拟盘的核心目的是验证策略逻辑,不是验证系统性能。所以单线程、单进程、单机,完全够用。

核心问题:模拟盘架构假设“市场是静止的”。你算完信号再下单,市场不会因为你慢而改变。但实盘不是这样——你慢1毫秒,单子就被别人抢走了。

二、实盘架构的三大核心挑战

从模拟盘切换到实盘,你首先要面对三个问题:

  1. 延迟——从行情到达到你发出订单,时间必须可控
  2. 吞吐——每秒处理几千笔订单,单机Python扛不住
  3. 可靠性——系统不能挂,挂了就是真金白银的损失

嗯,这里要注意:这三个问题不是独立的。你为了降低延迟,可能会牺牲吞吐;为了可靠性,又可能增加延迟。所以架构设计,本质上是在这三者之间找平衡。

三、分布式低延迟架构的核心组件

我个人习惯把实盘系统拆成五个核心组件。每个组件都有明确的职责,而且必须独立部署、独立优化。

组件 职责 模拟盘对应物 实盘要求
行情网关 接收交易所行情,解码,分发 免费API拉数据 微秒级解码,组播分发
策略引擎 计算信号,生成订单 Python脚本 C++实现,无锁队列
订单管理 管理订单生命周期,风控检查 状态机,超时处理
交易网关 连接交易所,发送订单,接收回报 FIX协议,会话管理
监控系统 记录日志,监控延迟,报警 print() 实时监控,毫秒级报警

你看,模拟盘里很多组件根本不存在。比如订单管理,模拟盘你不需要管订单到底成交了没有,但实盘里,订单可能被拒、被部分成交、被撤销,你必须有一套状态机来管理这一切。

四、架构演进路线:从单机到分布式

我建议你不要一步到位。直接上分布式架构,你可能会被复杂度压垮。我自己的经验是分三步走:

第一步:单机多进程

还是用一台机器,但把行情、策略、交易拆成三个进程。进程间用共享内存通信。这样延迟比Python脚本低一个数量级,而且一个进程挂了不会影响其他进程。

避坑指南:我曾经在单机多进程架构里,直接用Python的multiprocessing.Queue做进程间通信。结果发现延迟不稳定,有时候会卡几十毫秒。后来换成共享内存+无锁队列,延迟才稳定在微秒级。

第二步:多机分离

行情网关单独放一台机器,策略引擎放另一台,交易网关再放一台。这样做的目的是:行情数据量大,容易把CPU打满,分离后策略引擎不会受影响。

第三步:全分布式低延迟

到了这一步,你就要考虑网络拓扑了。行情网关和策略引擎之间用RDMA或者共享内存网络,策略引擎和交易网关之间用低延迟消息队列。每一跳的延迟都要控制在微秒级。

五、一张图看懂架构

下面这张图,是我自己画的一个典型高频交易系统架构。你看一眼,应该就能明白各个组件是怎么配合的。

高频交易系统架构图 交易所 行情网关 策略引擎 订单管理 交易网关 监控系统 行情数据 订单/回报 行情 订单 风控后订单 监控 图例 行情网关:接收解码行情 策略引擎:计算信号 订单管理:生命周期管理 交易网关:连接交易所 监控系统:日志/报警

六、核心组件深度拆解

接下来,我挑几个关键组件,说说它们内部是怎么设计的。

1. 行情网关:第一道关卡

行情网关是系统的入口。它的任务很简单:从交易所拿到行情数据,解码,然后分发给策略引擎。但简单的事情,在高频场景下就变得不简单了。

我记得有一次,交易所改了行情协议,把某个字段的偏移量调了2个字节。我们的行情网关没更新,结果解码出来的价格全是错的。策略引擎根据错误价格下了单,亏了不少钱。从那以后,我要求行情网关必须做两件事:

  • 校验和检查——确保数据没有被篡改
  • 字段边界检查——确保解码不会越界

警告:行情网关绝对不能成为瓶颈。如果行情网关处理不过来,行情数据就会堆积,延迟就会飙升。我建议用C++实现,并且用零拷贝技术,直接从网卡DMA到用户态。

2. 策略引擎:大脑

策略引擎是真正做决策的地方。它拿到行情,算指标,然后决定要不要下单。

在模拟盘里,策略引擎可能是一个Python函数,算完就完事了。但在实盘里,策略引擎必须考虑:

  • 计算延迟——每个指标必须在规定时间内算完
  • 状态管理——策略可能有持仓、有挂单,这些状态必须正确维护
  • 回测一致性——实盘算出来的信号,必须和回测时一模一样

我个人习惯用C++写策略引擎,因为Python的GIL在高频场景下太坑了。你想想看,Python一个线程在算指标,另一个线程在发订单,GIL一锁,两个都动不了。

3. 订单管理:风控的最后一道防线

订单管理这个组件,很多人会忽略。但我觉得它是最重要的。为什么?因为它是风控的最后一道防线。

策略引擎可能会犯错,交易网关可能会断连,但订单管理必须保证:

  • 同一个订单不会重复发送
  • 超时的订单会被撤销
  • 资金不够时,订单会被拒绝

我曾经在订单管理里加过一个“自毁机制”:如果订单管理检测到某个订单超过5秒没有回报,它会自动撤销这个订单,并且暂停策略引擎。这个机制救过我很多次。

七、总结:架构设计的核心原则

说了这么多,我想总结几条核心原则。这些原则是我做了这么多年高频交易系统,踩了无数坑之后总结出来的:

  1. 解耦——每个组件只做一件事,做好一件事
  2. 无锁——能不用锁就不用锁,锁是延迟的根源
  3. 可观测——每个组件都必须暴露延迟、吞吐、错误率等指标
  4. 渐进式——不要一步到位,从单机到分布式,一步步来

嗯,最后说一句:架构设计没有银弹。每个系统都有自己的特点,你需要根据你的策略、你的资金量、你的交易所,来调整架构。但不管怎么调,上面这几个核心组件,你一个都不能少。