第 8 章 · 04 Zipline 回测集成


文档摘要

第 8 章 · 04 Zipline 回测集成 本节摘要:本节把 ML4T 工作流推到工业级——用 Quantopian 维护的 Zipline 做端到端回测。Zipline 不只是回测引擎,它是一整套「数据-因子-下单-绩效」的基础设施:用 bundle 存点在时 OHLCV、用 TradingCalendar 对齐交易所时区、用 Pipeline API 声明式地算因子、用 调度整套流程。

第 8 章 · 04 Zipline 回测集成

本节摘要:本节把 ML4T 工作流推到工业级——用 Quantopian 维护的 Zipline 做端到端回测。Zipline 不只是回测引擎,它是一整套「数据-因子-下单-绩效」的基础设施:用 bundle 存点在时 OHLCV、用 TradingCalendar 对齐交易所时区、用 Pipeline API 声明式地算因子、用 run_algorithm 调度整套流程。本节讲清四件事:bundle 与自定义 bundle 如何让你把自有数据接进来;Pipeline API 的 Factor/Filter/Classifier 如何让因子计算向量化提速;initialize/before_trading_start/handle_data/schedule_function 的事件调度模型;以及如何用 CustomFactor 把「在回测中训练 ML 模型」嵌进 Pipeline,实现真正的端到端 ML4T。读完本节,你能在 Zipline 里跑通一个从原始数据到 pyfolio 绩效的完整闭环。

内容来源:原项目 08_ml4t_workflow/04_ml4t_workflow_with_zipline/,汉化并套用体系化模板。

⚠️ 学习提示:Zipline 1.3(2018 年 7 月)是本书使用的最后版本,需要打补丁(参见 installation)。它强依赖国库券曲线和 S&P500 基准,跑之前要先把 SPY_benchmark.csv 放到 .zipline 目录,否则会因缺基准报错。

学习目标

阅读完本节,你应当能够:

  1. 说清 bundleTradingCalendarPipeline API 各自的职责。
  2. 写出注册自定义 bundle 的 extension.py 四步流程。
  3. 用 Pipeline 的 Factor/Filter/Classifier 声明因子并选股。
  4. 解释 initialize/before_trading_start/handle_data 的调用时机。
  5. CustomFactorML 训练嵌进回测做端到端 ML4T。

一、Zipline 的定位与架构

Zipline 是 Quantopian 自 2012 年起开源的事件驱动回测系统,也是其在线平台的生产引擎。它比 backtrader 更「重」——但换来的是规模化(可同时处理数千只证券)与防前视(数据按点在时 point-in-time 对齐)。

组件 职责
Bundle bcolz 列式存储 + SQLite 元数据,支持拆股/分红点在时调整
TradingCalendar 交易所时区、开盘收盘、节假日
Pipeline API 声明式计算横截面因子,内部向量化加速
Algorithm API initialize/handle_data 等回调驱动交易逻辑

💡 核心心法:Zipline 的关键不是「快」,而是「防前视 + 规模化」。它把数据、因子、订单分别交给专门的子系统,每个子系统都为「别让未来泄漏到当前」做了设计——这是它能被生产级对冲基金使用的核心原因。

二、Bundle:点在时 OHLCV 数据

Bundle 是 Zipline 的主数据存储,用 bcolz 列式格式压缩存储 OHLCV,SQLite 存元数据。最大优点是存了拆股和分红信息,Zipline 会根据你回测的时间段自动计算点在时调整——这意味着你回测 2015 年的某天,看到的是「那时那天的真实价格」,而不是被后来拆股回填过的价格。

自定义 bundle 四步走

要把自有数据(如本书用的 AlgoSeek 分钟级 NASDAQ100)接进 Zipline,需要:

  1. 拆数据 + 存元数据:把每只 ticker 一个文件存好,并保留拆股/分红调整信息,产出 algoseek.h5
  2. 写 ingest 函数:实现 load_equities()(元数据)、ticker_generator()data_generator(),组合成 algoseek_to_bundle() 返回 ingest() 函数。
  3. 注册 bundle:在 ~/.zipline/extension.py 里用 register() 注册 bundle 名,用 sys.path.append 让 Zipline 能找到 ingest 函数,并指定自定义日历。
  4. 自定义 TradingCalendar:像 AlgoSeek 这种含盘前盘后数据的,要继承 NYSE 日历并覆盖开收盘时间,否则会因为「交易时长超过默认 6.5 小时」对齐错乱。

注册后用 zipline ingest -b algoseek 把数据写进 bundle,用 ZIPLINE_ROOT 环境变量可改默认存储位置(默认在用户主目录的 .zipline)。

⚠️ Bundle 只存 OHLCV:它不存基本面、另类数据。要喂额外特征,用 fetch_csv()(适合日频)或 DataFrameLoader(适合 Pipeline 内的日频特征)。分钟级额外特征只能靠 fetch_csv,这是 Pipeline API 的限制。

三、Pipeline API:声明式因子计算

Pipeline API 是 Zipline 区别于 backtrader 的另一大杀器。你声明「我要哪些因子、怎么过滤」,Zipline 在整个回测期间向量化地算这些因子,而不是每个事件单独算——既保留了事件驱动架构,又获得了向量化速度。

Pipeline 用三类构件:

构件 作用 示例
Factor 输入历史 bar 数组,输出每只证券一个值 SimpleMovingAverage,自定义 MLSignal
Filter 输出布尔值,用于筛选证券 top(10).bottom(10)
Classifier 输出类别,用于分组 按行业、按市值分桶

一个典型 Pipeline:加载 lasso 预测作为 MLSignal 因子,用 top(10) 选预测最高的 10 只做多、bottom(10) 选最低的 10 只做空,每边至少 5 只。这套声明式逻辑让因子研究与下单逻辑解耦,改因子不动下单代码。

四、Algorithm API:回测按调度执行

TradingAlgorithm 实现了 Algorithm API,操作与某交易日历对齐的 BarData。关键回调:

方法 调用时机 典型用途
initialize(context, data) 模拟开始时一次 注册 Pipeline、设佣金滑点、初始化 context
before_trading_start(context, data) 每日开盘前 选当日交易标的
handle_data(context, data) 每个交易频率 下单、调仓
schedule_function 自定义时间 每周/每月再平衡

context 是状态字典(贯穿整个回测),data 提供点在时的当前与历史数据。整个算法通过 run_algorithm() 启动,返回的 DataFrame 直接兼容 pyfolio 出绩效报告。

五、端到端 ML4T:在回测里训练模型

最关键的能力是——Zipline 允许在回测过程中训练 ML 模型,而不是预先训好把预测喂进去。notebook ml4t_with_zipline.ipynb 演示了这套真正的端到端流程:

class MLLiquidityReturn(CustomFactor): """在 Pipeline 内训练模型并产出预测""" def compute(self, today, assets, out, returns, *inputs): # 用今天之前的数据训练,预测今天 model.fit(X_train, y_train) out[:] = model.predict(X_latest)

CustomFactor 接收收益与特征作为输入,在 compute 里训练模型并输出预测——这是「随时间向前滚动训练」的实现方式。第 7 章用过的技术指标(动量、波动、滞后收益等)作为特征,目标是粗略复现那章的日收益预测。

💡 避免前视的训练纪律:compute(today, ...) 里训练数据必须严格截断到 today 之前,绝不能用 today 当天的收益当标签。Zipline 的 Pipeline 在调度上帮你对齐,但特征工程的细节仍要你自己把关——把训练集与预测集的边界画清楚,是端到端 ML4T 最容易出错的地方。

本节要点回顾

  1. Zipline 定位:工业级事件驱动框架,强在规模化与防前视,bundle 自动做点在时拆股分红调整。
  2. 自定义 bundle 四步:拆数据存 HDF5 → 写 ingest() → 在 extension.py 注册 → 必要时自定义 TradingCalendar。
  3. Pipeline 三构件:Factor(算值)、Filter(筛证券)、Classifier(分组),声明式 + 向量化,因子与下单解耦。
  4. Algorithm 回调:initialize(一次)/before_trading_start(每日盘前)/handle_data(每频率)/schedule_function(自定义)。
  5. 端到端 ML4T:CustomFactor.compute() 内训练模型,实现回测中滚动训练,但要严守「训练只用过去」的纪律。
  6. pyfolio 闭环:run_algorithm() 输出直接接 pyfolio,完成从原始数据到标准绩效报告的完整链路。

下一章,我们进入树模型与梯度提升——从决策树讲起,看非线性模型如何捕捉线性模型抓不到的因子交互,并落到日本股票多空策略。


发布者: 作者: 灏天文库 转发
评论区 (0)
U