halo 的技术博客

返回

量化交易的核心竞争力不在于某个神奇的策略,而在于验证策略的能力。一个设计良好的回测系统,能让你在实盘之前就把 90% 的坑踩完。这篇文章从工程实践角度,拆解如何从零搭建一个可靠的回测框架。

为什么现成的回测平台不够用#

市面上的回测工具很多——聚宽、米筐、Backtrader、Zipline。它们各有千秋,但在实际工作中总有”差点意思”的地方:

  • 数据粒度不可控:大多数平台只提供日线或分钟线,你没法验证 tick 级别的策略逻辑
  • 撮合模型过于简化:涨跌停、流动性冲击、滑点模型往往和实盘差距很大
  • 无法自定义因子计算管线:想在回测过程中动态计算 Alpha 因子?很多时候只能 hack
  • 回测速度瓶颈:当你需要跑 5000 只股票 × 10 年的参数扫描,Python 单线程根本扛不住

自建回测系统的目的不是重复造轮子,而是获得对每一行代码的掌控力

回测架构图

核心模块拆解#

一个生产级回测系统至少包含以下模块:

数据层#

数据是回测的血液。数据层的设计决定了整个系统的上限。

DataFeed
├── MarketData (OHLCV + 复权因子)
├── FundamentalData (财报、估值)
├── AlternativeData (舆情、资金流)
└── FactorCache (预计算因子存储)
plaintext

关键设计决策:

  1. 前复权 vs 后复权:回测统一用后复权价格,避免未来数据泄露。在实盘信号生成时再转回前复权
  2. 数据对齐:不同来源的数据(财报季度 vs 日线行情)必须做时间对齐,Pandas 的 merge_asof 是你的好朋友
  3. 缓存策略:高频使用的因子数据应该预计算并缓存为 Parquet 格式,读写速度比 CSV 快 10 倍以上

策略层#

策略层只做一件事:给定一个时间点和持仓状态,返回目标持仓。

class BaseStrategy:
    def generate_signals(self, context: StrategyContext) -> pd.Series:
        """返回每个标的的目标权重"""
        raise NotImplementedError
python

这里的设计哲学是策略和撮合解耦。策略只负责输出”我想要什么”,不管”能不能买到”。这样你可以单独测试信号的预测能力,而不会被撮合逻辑干扰。

撮合引擎#

撮合是回测系统中最容易被低估的部分。一个好的撮合引擎需要处理:

  • 涨跌停限制:A 股 10%(创业板 20%),涨停买不到、跌停卖不掉
  • T+1 制度:当日买入次日才能卖出,这个约束会显著影响高频策略的回测结果
  • 滑点模型:不是简单扣万分之三,要根据成交量和盘口深度动态估算
  • 冲击成本:大资金买入会推高价格,可以用 Almgren-Chriss 模型估算

信号生成与撮合流程

风控层#

风控是回测和实盘之间的桥梁。即使回测曲线再漂亮,没有风控模块的策略就是裸奔:

  • 单票仓位上限:任一股票不超过总资产的 10%
  • 行业敞口限制:单一行业不超过 20%,避免变成行业赌注
  • 最大回撤熔断:当日回撤超过 5% 时强制清仓
  • 流动性约束:日交易量不超过该股票日均成交量的 1%

评估层#

回测结果的评估不仅仅是看年化收益率。一个完整的评估框架包括:

指标类别核心指标说明
收益类年化收益率、累计收益绝对收益水平
风险类年化波动率、最大回撤风险敞口
风险调整夏普比率、Calmar 比率单位风险收益
交易类换手率、胜率、盈亏比交易行为特征
归因类IC 均值、IR、行业贡献Alpha 来源拆解

性能优化实战#

当回测规模上来后(比如 5000 只股票 × 10 年日线),性能就成为瓶颈。以下是几个实战优化:

向量化 > 循环:能用 NumPy 数组运算就别用 Python for 循环。一个横截面排序操作,向量化比循环快 100 倍。

多进程并行:参数扫描是最容易并行的场景。用 multiprocessingray 把不同参数组合分发到不同核心:

from ray import remote, get

@remote
def backtest_with_params(params):
    engine = BacktestEngine(params)
    return engine.run()

results = get([backtest_with_params.remote(p) for p in param_grid])
python

惰性计算:不是所有因子都需要在回测开始时全部计算。使用生成器模式,只在策略实际需要时才计算因子值。

常见陷阱#

自建回测系统最容易犯的三个错误:

  1. 前视偏差(Look-ahead Bias):在 t 日使用了 t+1 日才公布的数据。财报发布日期 ≠ 财报截止日期,这个时间差必须处理
  2. 幸存者偏差:只用当前还在交易的股票做回测,忽略了已退市的股票。你的回测池必须包含历史成分股
  3. 过拟合:参数调得太完美,回测曲线几乎 45 度向上——那基本可以确定是过拟合了。留出 out-of-sample 时间段做验证

总结#

回测系统的价值不在于代码本身,而在于它给你提供了一个可复现的实验环境。每一次策略迭代,你都能在几分钟内得到可靠的反馈,这才是量化交易真正的护城河。

如果你正在从零搭建自己的回测系统,建议从最简单的日线 + 等权重策略开始,先把数据流跑通,再逐步添加撮合、风控、归因模块。迭代速度比完美度更重要。

量化回测系统搭建实战:从零构建可靠的策略验证框架
https://blog.halo26812.eu.org/blog/quant-backtesting-system
Author halo
Published at 2026年6月19日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨