第二章:系统架构设计

好,咱们直接进入正题。一个交易策略回测系统,说白了就是一台「时光机」。你得让策略回到过去,看看它到底行不行。但怎么造这台时光机?我踩过不少坑,今天把经验摊开讲。

2.1 整体架构分层

我个人习惯把系统拆成四层。为什么是四层?你想想看,如果所有代码揉在一起,改个数据源就得动策略逻辑,改个策略又得动执行代码——那画面太美我不敢看。

核心分层原则:每一层只关心自己的事,层与层之间通过标准接口通信。

这四层分别是:

  • 数据层:负责喂数据,管它来自交易所、CSV 还是数据库
  • 策略层:负责出信号,买入、卖出、还是躺平
  • 执行层:负责模拟撮合,按信号生成真实成交记录
  • 分析层:负责算账,收益率、回撤、夏普比率全在这

嗯,这里要注意:层与层之间千万别搞「直接调用」。我建议用事件驱动或者消息队列。我在项目中遇到过,有人把数据层和策略层写成了强耦合,结果换数据源时改了 200 行代码——那周我加了三天班。

交易策略回测系统 · 四层架构 数据层 行情数据 · 交易数据 · 因子数据 策略层 信号生成 · 逻辑判断 · 参数管理 执行层 模拟撮合 · 滑点模型 · 手续费计算 分析层 绩效报告 · 风险指标 · 归因分析 数据流方向:自上而下,层层传递

2.2 数据层

数据层是整个系统的地基。地基不稳,后面全是扯淡。我曾经见过一个团队,回测结果漂亮得不行,实盘一跑就崩——后来发现是数据层用了未来数据,回测时偷偷看了明天的价格。

⚠️ 避坑指南:我曾经在数据层犯过一个低级错误——没做「前向填充」处理。结果策略在回测时遇到空值直接跳过,导致信号数量虚高。后来我加了一条铁律:数据层必须输出「干净、对齐、无未来」的时序数据。

数据层要处理的核心问题:

  1. 数据清洗:去重、补缺、异常值处理
  2. 数据对齐:不同时间频率的数据要统一时间戳
  3. 数据缓存:避免重复从磁盘或网络加载
  4. 数据版本:每次回测要记录用了哪份数据

我个人习惯用 pandasDataFrame 作为数据层的统一输出格式。为什么?因为它的时间序列操作太方便了。但要注意,别把整个数据层写成 pandas 的「套娃」——我见过有人一个函数里嵌套了 5 个 apply,那代码读起来跟天书似的。

2.3 策略层

策略层是系统的「大脑」。它接收数据层的行情,输出买卖信号。这里有个常见的误区:很多人把策略逻辑和参数调优混在一起写。

💡 我的建议:策略层只负责「给定参数,输出信号」。参数调优是分析层的事,别掺和进来。这样你换参数时不用改策略代码,改个配置文件就行。

策略层的标准接口长这样:

class BaseStrategy:
    def __init__(self, params: dict):
        self.params = params

    def on_data(self, data: pd.DataFrame) -> pd.Series:
        """
        输入:行情数据(DataFrame)
        输出:信号序列(-1 卖出, 0 持有, 1 买入)
        """
        raise NotImplementedError

嗯,这里要注意:信号输出必须是「离散值」还是「连续值」?我个人倾向用连续值(比如 -1 到 1 之间的浮点数),这样执行层可以自己做仓位管理。你想想看,如果策略直接输出「全仓买入」,那执行层就失去了风控的灵活性。

2.4 执行层

执行层是系统的「手脚」。它把策略的信号变成真实的成交记录。很多人觉得这层简单,其实最容易出幺蛾子。

执行层要模拟的东西:

  • 撮合逻辑:市价单怎么成交?限价单能不能成交?
  • 滑点模型:大单买入时价格会往上跑,这个要模拟
  • 手续费:佣金、印花税、过户费,一个都不能少
  • 交易限制:涨跌停、停牌、最小交易单位

核心原则:执行层要「悲观」一点。我建议默认假设你的成交条件比实际更苛刻。这样回测出来的结果偏保守,实盘反而可能更好。

我曾经在项目中遇到过一个问题:回测时所有限价单都假设「立即成交」,结果实盘时很多单子挂了一天都没成交。后来我加了一个「成交概率模型」,根据订单深度和流动性来模拟成交概率——虽然回测速度慢了点,但结果靠谱多了。

2.5 分析层

分析层是系统的「裁判」。它告诉你这个策略到底行不行。但要注意,分析层不只是算几个指标那么简单。

我习惯把分析层分成三个维度:

维度 核心指标 说明
收益维度 年化收益率、累计收益率 赚了多少,别只看绝对值
风险维度 最大回撤、波动率、VaR 亏了多少,这个更重要
综合维度 夏普比率、卡玛比率 收益风险比,一锤定音

但光看指标还不够。我建议分析层一定要输出「交易明细」和「资金曲线」。为什么?因为指标会骗人。我曾经见过一个策略,夏普比率 2.5,但资金曲线一看——前三年一直在亏,最后一年突然暴涨。这种策略你敢用吗?

💡 一个小技巧:分析层加一个「滚动夏普比率」的计算。它能告诉你策略的稳定性。如果滚动夏普比率忽高忽低,说明策略可能过拟合了。

好了,架构设计就聊到这。记住一句话:架构不是画出来的,是改出来的。先跑通一个最小闭环,再慢慢优化每一层。别一开始就想搞个「完美架构」——我试过,结果项目烂尾了。


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