第四章:系统架构设计——分层架构、模块划分、数据流设计、事件驱动模型

好,咱们进入正题。系统架构这东西,说白了就是给整个回测系统搭骨架。我见过太多人一上来就写代码,写到后面发现改不动、跑不快、查不了bug。嗯,今天我就把我在高频回测系统上踩过的坑、积累的经验,一次性讲清楚。

4.1 为什么必须分层?

先问个问题:你写回测代码时,是不是经常把数据读取、策略逻辑、订单管理全塞在一个大函数里?我以前也这么干过。结果呢?想换个数据源,改了一堆代码;想加个新策略,又得从头捋一遍逻辑。说白了,耦合太紧,牵一发动全身。

我个人习惯,把系统拆成四层:

  • 数据层:负责行情数据的获取、清洗、存储
  • 策略层:只做一件事——根据行情信号生成交易指令
  • 执行层:把交易指令变成真实的订单,处理撮合逻辑
  • 风控层:在订单出去之前,做最后一关检查

每一层只跟相邻层打交道。数据层不知道策略层在想什么,策略层也不关心订单怎么执行。这样改起来才舒服。

核心原则:高内聚、低耦合。每个模块只做自己该做的事,别越界。

4.2 模块划分——我踩过的坑

模块怎么分?我建议按职责来,而不是按功能来。举个例子:

模块名称 职责 输入 输出
行情引擎 接收并解析Tick/Bar数据 原始行情流 标准化行情事件
策略容器 加载策略、管理策略实例 行情事件 交易信号
订单管理器 维护订单状态、处理成交回报 交易信号 订单状态更新
资金管理器 计算持仓、盈亏、保证金 订单状态 资金快照
风控模块 检查下单限制、资金限制 交易信号 通过/拒绝

我曾经犯过一个错:把行情引擎和策略容器写在一起。结果想换一个数据源,策略逻辑也得跟着改。后来我学乖了,每个模块独立编译、独立测试。你想想看,这样改一个模块,其他模块完全不受影响,多省心。

4.3 数据流设计——让数据跑起来

数据流是系统的血脉。高频回测最怕什么?数据跑得慢、数据丢了、数据顺序乱了。我建议用事件驱动的方式组织数据流。

来看一个典型的数据流:

行情源 → 行情引擎 → 行情事件队列 → 策略容器 → 交易信号事件队列 → 风控模块 → 订单管理器 → 成交回报事件队列 → 资金管理器

每个箭头都是一个事件队列。为什么用队列?因为可以解耦。行情引擎只管往队列里塞事件,策略容器只管从队列里取事件。两者速度不一致?没关系,队列能缓冲。

小技巧:队列用无锁环形缓冲区实现,能大幅降低延迟。我在实盘回测中试过,比用Python的queue.Queue快3倍以上。

数据流里还有一个关键点:时间戳。每个事件都必须带上精确的时间戳,否则回测结果就是错的。我记得有一次,因为时间戳精度不够,回测出来的夏普比率比实盘高了0.5,差点误导了策略上线。

4.4 事件驱动模型——核心中的核心

事件驱动,说白了就是「有事件来了,才干活」。没有事件,系统就闲着。这跟高频交易的本质完全吻合——市场在动,我们才动。

事件驱动模型的核心组件有三个:

  • 事件源:谁产生事件?行情引擎、策略容器、订单管理器都是事件源
  • 事件总线:负责把事件分发给订阅者。我建议用发布-订阅模式
  • 事件处理器:每个模块都是一个事件处理器,只处理自己关心的事件

举个例子,行情引擎产生一个Tick事件,事件总线把它发给策略容器。策略容器处理完后,产生一个交易信号事件,事件总线再把它发给风控模块和订单管理器。整个过程是异步的、非阻塞的。

避坑指南:我曾经在事件总线上用了全局锁,结果回测速度直接掉到原来的1/10。后来改成无锁队列+原子操作,才把性能拉回来。记住,高频场景下,锁是万恶之源。

4.5 架构图——一张图说清楚

下面这张SVG图,是我自己画的高频回测系统架构。你看一眼,就能明白整个系统的脉络。

高频回测系统架构图 数据层 行情源(Tick/Bar) 数据清洗 数据存储 数据缓存 策略层 策略容器 信号生成 策略参数管理 策略回放 执行层 订单管理器 撮合引擎 资金管理器 持仓管理 风控层 下单检查 资金限制 频率限制 异常检测 事件总线(异步、无锁队列)

你看,数据从底层往上流,经过每一层处理后,最终形成交易结果。每一层之间通过事件总线连接,互不干扰。这就是我推荐的分层+事件驱动的架构。

4.6 实战中的几个要点

最后,分享几个我在实战中总结的要点:

  • 事件类型要标准化:我习惯用枚举定义所有事件类型,比如TickEvent、SignalEvent、OrderEvent、FillEvent。这样事件处理器可以快速判断事件类型,不用做字符串匹配。
  • 日志要贯穿全流程:每个事件处理前后都要打日志。我遇到过因为日志没打全,查了一个星期的bug才发现是订单状态更新错了。
  • 性能监控不能少:在事件总线上加一个性能计数器,统计每个事件的处理耗时。如果某个模块处理时间突然变长,说明有问题了。
  • 回测和实盘用同一套架构:我见过有人回测用一套代码,实盘又重写一套。结果回测跑得飞起,实盘各种问题。记住,架构设计的目标就是让回测和实盘共用同一套核心逻辑。

一句话总结:分层架构让系统好改,事件驱动让系统快跑。两者结合,就是高频回测系统的基石。

好了,这一章就到这里。架构设计是地基,地基打好了,后面写代码才踏实。下一章咱们聊聊数据模块的具体实现,到时候我会把行情引擎的代码一行行拆给你看。


公众号:蓝海资料掘金营,微信deep3321