Stefan Jansen《Machine Learning for Trading》2nd:量化金融 ML 工程化完全指南
posts posts 2026-06-02T03:05:00+08:00Stefan Jansen 的《Machine Learning for Algorithmic Trading》第 2 版配套代码库,150+ Jupyter Notebooks 覆盖 23 章、800+ 页、四大主题:数据源与特征工程、监督/无监督交易策略、文本 NLP 信号、深度与强化学习。本文详解其端到端 ML4T 工作流、可复现的 notebook 矩阵与基于 Zipline-reloaded 的回测引擎集成方式。技术笔记量化交易, 机器学习, Python, Zipline, 金融工程Stefan Jansen《Machine Learning for Trading》2nd:量化金融 ML 工程化完全指南
量化交易的机器学习资源长期割裂成两端:学术论文重理论、与代码脱节,券商研报重策略、数据封闭。Stefan Jansen 的《Machine Learning for Algorithmic Trading》第 2 版是少数同时给出完整代码与系统框架的工程化手册——150+ Jupyter Notebooks 覆盖 23 章、800+ 页,从数据源、特征工程、监督/无监督模型,一路走到 NLP(自然语言处理)、深度学习和强化学习的回测落地。
大多数 ML 交易教程停在一个 RandomForestClassifier 跑完分类就收工——没有回测、没有因子评估、没有过拟合检测。Jansen 这本书处理的是 demo 之后的部分:怎么把模型输出变成策略信号,怎么在历史数据上验证,怎么判断一个因子是真实 alpha 还是噪音。
阅读路线:只有 10 分钟的话,先看「核心方法论」和「一次完整任务流过系统」两节;准备动手的话,直接跳到「安装与运行」和「实战采用建议」。
项目概览
| 指标 | 数值 |
|---|---|
| 仓库 | stefan-jansen/machine-learning-for-trading |
| Stars | 17,747 |
| Forks | 5,179 |
| 主要语言 | Jupyter Notebook(核心交付物) + Python |
| 协议 | 未指定开源协议(默认仅供读者使用) |
| 配套书籍 | 《Machine Learning for Algorithmic Trading》2nd Edition(Packt,2020) |
| 章节 | 23 章 + 1 附录(Alpha Factor Library,100+ 因子) |
| Notebooks | 150+(多数为已运行可读状态) |
| 主页 | ml4trading.io |
| 社区 | exchange.ml4trading.io |
| 最近活跃 | 2026-06-01 仍接受 Issue(项目维护中) |
为什么值得看
这本书值得投入时间,原因不在功能列表的长度,在于它解决了量化 ML 从学到用的几个实际障碍:
- 端到端工作流:不是"调个模型就结束",而是把 ML 嵌入到
Idea → Data → Feature → Model → Strategy → Backtest → Live的完整链路里。你可以看到模型预测如何变成持仓、交易成本和滑点怎么影响收益、过拟合在回测曲线上长什么样。 - 多源数据实操:从 NASDAQ ITCH 逐笔数据重建订单簿、从 SEC XBRL 财报提取财务比率、从财报电话会议提取情绪信号——涵盖了从结构化到非结构化的主要数据形态,而且给出了可运行的取数代码,不是“建议使用这些数据源”就完了。
- Zipline 回测集成:使用
zipline-reloaded(社区维护分支)作为回测引擎,把 ML 模型预测接入策略信号,Pipeline API 的用法在书中拆得很细。 - 学术前沿可复现:第 18/20/21 章分别复现 Sezer & Ozbahoglu 2018(CNN 时间序列转图像)、Gu/Kelly/Xiu 2019(Autoencoder 资产定价)、Yoon/Jarrett/van der Schaar 2019(TimeGAN 合成数据)等顶刊论文。复现价值不在于模型本身能不能赚钱——论文里的 SOTA 在真实市场通常都会衰减——而在于把一个端到端 ML pipeline 工程化的全部细节(数据预处理、特征工程、超参搜索、回测防过拟合)摆在你面前。
- 出版后持续维护:作者在 2022 年更新到
conda-forge通道,2021 年配套 Zipline 升级移除 Docker 依赖。这个行为本身比 Stars 数量更能说明项目质量。
核心方法论:ML4T 工作流
Jansen 把量化 ML 抽象成 7 步循环。这个框架的价值在于把散落在各章的具体操作统一到了一个可迭代的模型里:
┌─────────────────────────────────────────────────────┐
│ 1. Idea 定义投资范围(如美股大盘、加密资产) │
│ ↓ │
│ 2. Data 采集相关数据(价格、财报、新闻、卫星) │
│ ↓ │
│ 3. Feature 提取 alpha 因子(动量、波动、情绪等) │
│ ↓ │
│ 4. Model 设计/调优 ML 模型(监督/无监督/RL) │
│ ↓ │
│ 5. Strategy 把模型预测转化为多空头寸 │
│ ↓ │
│ 6. Backtest 在历史数据上模拟并评估 │
│ ↓ │
│ 7. Deploy 上线后持续迭代(添加新数据/新信号) │
└─────────────────────────────────────────────────────┘整套工程哲学的核心:ML 是策略 pipeline 的一环,不是策略本身。没有好的数据源和特征工程,再复杂的模型也只是 garbage-in-garbage-out。这也是为什么第 2-5 章占据了全书近四分之一的篇幅——它们处理的是 ML 模型之外、但决定模型能不能用的基础设施。
全书 23 章结构矩阵
| 部分 | 章节 | 主题 | 核心算法 / 工具 |
|---|---|---|---|
| Part 1:Data → Strategy | 1 | ML for Trading 全景 | 行业趋势、用例 |
| 2 | 市场与基本面数据 | NASDAQ ITCH、XBRL、Algoseek 分钟 bar | |
| 3 | 另类数据 | 网络爬虫、情绪信号、卫星图 | |
| 4 | 金融特征工程 | NumPy / pandas / TA-Lib / wavelets / Kalman | |
| 5 | 组合优化与绩效 | mean-variance、pyfolio | |
| Part 2:ML 基础 | 6 | ML 流程通用框架 | 训练/调优/评估 |
| 7 | 线性模型 | 风险因子、收益预测 | |
| 8 | ML4T 工作流 | Zipline 端到端回测 | |
| 9 | 时间序列 | GARCH、协整、配对交易 | |
| 10 | 贝叶斯 ML | 动态 Sharpe、配对交易 | |
| 11 | 随机森林 | 日股多空策略 | |
| 12 | 梯度提升 | 提升策略表现 | |
| 13 | 无监督学习 | 风险因子、资产配置 | |
| Part 3:NLP | 14 | 文本数据 | 情绪分析 |
| 15 | 主题建模 | 金融新闻摘要 | |
| 16 | 词嵌入 | 财报电话会议、SEC 文件 | |
| Part 4:DL & RL | 17 | 深度学习入门 | TensorFlow 2 |
| 18 | CNN | 时间序列→图像、卫星图 | |
| 19 | RNN | 多变量时间序列、情绪 | |
| 20 | 自编码器 | 条件风险因子、资产定价 | |
| 21 | GAN | 合成时序数据(TimeGAN) | |
| 22 | 深度强化学习 | 交易 agent(DQN / PPO) | |
| 23 | 结论与下一步 | 工程化路线 | |
| 附录 | 24 | Alpha 因子库 | 100+ 因子即查即用 |
关键工程实践
1. 数据:多源融合是基本功
Jansen 把数据源切成三档:
| 类型 | 代表 | 用途 |
|---|---|---|
| 市场数据 | NASDAQ ITCH、Algoseek 分钟 bar | 重建订单簿、做日内策略 |
| 基本面数据 | SEC XBRL filings、Compustat | 财务比率、行业分析 |
| 另类数据 | 财报电话会议、新闻、卫星图 | 情绪信号、宏观预测 |
# 第 2 章:重建订单簿
import pandas as pd
import numpy as np
def reconstruct_order_book(itch_messages: pd.DataFrame) -> pd.DataFrame:
"""从 NASDAQ ITCH 消息流重建 L2 order book"""
book = {'bids': {}, 'asks': {}}
snapshots = []
for _, msg in itch_messages.iterrows():
if msg['type'] == 'A': # Add order
side = 'bids' if msg['side'] == 'B' else 'asks'
book[side][msg['price']] = msg['shares']
elif msg['type'] == 'D': # Delete
side = 'bids' if msg['side'] == 'B' else 'asks'
book[side].pop(msg['price'], None)
# ... 完整实现见 ch02 notebook
return book2. 特征工程:Alpha 因子是策略的“语言”
第 4 章与第 24 章附录给出 100+ 可计算的 alpha 因子(动量、波动、价值、情绪、质量),并教读者如何系统化地研究、回测、评估一个新因子。这两章是全书使用频率最高的部分——不是因为你应该照搬这些因子,而是因为这里展示了因子研究的标准流程。
# 24_alpha_factor_library 中的动量因子
def momentum_factor(prices: pd.Series, lookback: int = 252) -> pd.Series:
"""12-1 月动量:过去 12 个月收益,跳过最近 1 个月"""
return (prices.shift(21) / prices.shift(lookback)) - 1# 用 Alphalens 评估因子的 IC、turnover、decay
import alphalens
factor_data = alphalens.utils.get_clean_factor_and_forward_returns(
factor=momentum_signal,
prices=stock_prices,
quantiles=5,
periods=(1, 5, 21)
)
alphalens.performance.factor_information_coefficient(factor_data).plot()
alphalens.tears.create_returns_tear_sheet(factor_data)3. 端到端回测:Zipline-reloaded
第 8 章把 ML 模型接入 Zipline 策略:
# zipline_reloaded 策略:把 ML 模型预测作为 alpha
from zipline.pipeline import Pipeline, CustomFactor
from zipline.api import attach_pipeline, pipeline_output, order_target_percent
class MLAlphaFactor(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 252
def compute(self, today, assets, out, prices):
returns = (prices[1:] - prices[:-1]) / prices[:-1]
out[:] = returns.mean(axis=0)
def initialize(context):
attach_pipeline(
Pipeline(columns={'alpha': MLAlphaFactor()}),
name='ml_alpha'
)
schedule_function(rebalance, date_rules.month_start())
def rebalance(context, data):
alpha = pipeline_output('ml_alpha')
longs = alpha.dropna().nlargest(int(len(alpha) * 0.2))
shorts = alpha.dropna().nsmallest(int(len(alpha) * 0.2))
for asset in longs.index:
order_target_percent(asset, 1.0 / len(longs))
for asset in shorts.index:
order_target_percent(asset, -1.0 / len(shorts))4. 学术前沿可复现
第 18/20/21 章直击顶会论文,把“看论文”变成“跑代码”:
| 论文 | 复现章节 | 核心创新 |
|---|---|---|
| Sezer & Ozbahoglu (2018) | 第 18 章 CNN | 把金融时序转成 2D 图像,用 CNN 预测涨跌 |
| Gu, Kelly & Xiu (2019) | 第 20 章自编码器 | 用 autoencoder 提取条件风险因子做资产定价 |
| Yoon, Jarrett & van der Schaar (2019) | 第 21 章 GAN | TimeGAN 生成合成金融时序,缓解小样本问题 |
一次完整任务流过系统
下面用“基于动量因子的日股多空策略”这个场景,走一遍 Jansen 工作流的 7 个步骤,看看书中的各章是怎么串起来的。
Step 1 — Idea(第 1 章):假设我们观察到美股大盘股存在中期动量效应——过去 12 个月涨幅高的股票,接下来 1 个月继续跑赢。投资范围限制在 S&P 500 成分股。
Step 2 — Data(第 2 章):从 Algoseek 分钟 bar 或 yfinance 日线获取 500 只股票过去 5 年的价格数据,存入 pandas DataFrame。第 2 章提供了多种数据源的取数代码和清洗流程。
Step 3 — Feature(第 4、24 章):基于价格数据计算 12-1 月动量因子(momentum_factor 函数)。同时计算波动率、换手率等辅助因子用于后续过滤。用 Alphalens 评估因子的 IC(信息系数)和分层收益衰减——如果 IC 均值不到 0.02 或 decay 太快,回退到 Step 1 调整假设。
Step 4 — Model(第 11 章):用随机森林把多个因子合并成一个预测信号。第 11 章详细讲了金融场景下随机森林的训练要点:用时间序列交叉验证而非随机 K-fold、如何处理类别不平衡、如何解读特征重要性。
Step 5 — Strategy(第 8 章):把随机森林的预测概率写入 MLAlphaFactor(替换上面代码中的简单动量均值),接入 Zipline 的 Pipeline API。策略规则:每月初做多预测概率最高的 20% 股票,做空最低的 20%,等权配置。
Step 6 — Backtest(第 5、8 章):在 2018-2022 的样本外数据上运行回测。用 pyfolio 生成 tear sheet,关注四个指标:样本外 Sharpe 是否显著低于样本内(过拟合信号)、max drawdown 的持续时间和幅度、月换手率(过高意味着交易成本侵蚀收益)、因子 IC 是否在回测期持续为正。
Step 7 — 迭代:如果回测结果可接受,回到 Step 3 添加新因子或替换模型(如第 12 章的梯度提升),重新走 Step 4-6。这 7 步不是一次性的,而是一个持续运转的循环——这正是 Jansen 全书结构的组织逻辑。
安装与运行
Jansen 在 README 里明确建议按章节装环境(避免一次装全导致版本冲突):
# 1. 克隆仓库
git clone https://github.com/stefan-jansen/machine-learning-for-trading.git
cd machine-learning-for-trading
# 2. 创建环境(推荐 conda)
conda env create -f installation/environment.yml
conda activate ml4t
# 3. 安装 zipline-reloaded(推荐 conda-forge 通道)
conda install -c conda-forge zipline-reloaded
# 4. 下载 algoseek 分钟 bar 数据(可选)
# 详见 ch02 notebook2022 年更新要点:
zipline-reloaded、pyfolio-reloaded、alphalens-reloaded、empyrical-reloaded都迁移到了conda-forge通道- 原
ml4t通道已弃用 - 移除了 Docker 依赖,改为 OS-specific environment 文件
适用读者与边界
适合
- 已掌握 Python + pandas + scikit-learn,希望进入量化金融的工程师
- 想系统化理解 ML 交易全流程而非追逐噱头的研究者
- 已有交易经验,希望补齐 ML 工具栈的从业者
- 准备做毕业论文或课程项目(涵盖数据→模型→回测完整链路)的研究生
不适合
- 期望跑完 notebook 就能直接赚钱的人——Jansen 在第 5、8、22 章都明确警告了过拟合与样本外失效
- 完全没金融基础(需要先看 Hull 的《Options, Futures, and Other Derivatives》或类似教材打底)
- 寻找高频或微观结构策略的人(本书数据频率最高到分钟 bar,不涉及 tick-level HFT(高频交易))
- 需要一个能直接部署到生产环境的交易系统的团队(本书侧重研究和回测阶段,不覆盖实盘执行、风控、订单路由)
与同类资源的横向对比
| 资源 | 定位 | 覆盖广度 | 深度 | 工程化 |
|---|---|---|---|---|
| Jansen 2nd(本仓库) | 教科书 + 完整代码 | ★★★★★ | ★★★★ | ★★★★★ |
| Marcos López de Prado《Advances in Financial ML》 | 学术专著 | ★★★ | ★★★★★ | ★★★ |
| Ernest Chan《Quantitative Trading》 | 入门书 | ★★ | ★★★ | ★★ |
| Hudson & Thames 开源 notebooks | 专题实现 | ★★ | ★★★★ | ★★★ |
| QuantConnect / Zipline 官方示例 | 平台文档 | ★★ | ★★ | ★★★★ |
Jansen 的定位是“教科书深度 + 完整工程代码”的双轨覆盖。López de Prado 的书在数学深度上更强,但代码是片段式的;Chan 的书更适合零基础入门但 ML 覆盖浅;Hudson & Thames 的 notebooks 在特定专题(如组合优化)上更深入,但缺少统一的叙事框架。如果你需要一边学理论一边改代码跑结果,Jansen 的仓库是目前最接近“开箱即用”的选择。
实战采用建议
按三类读者的节奏给出建议:
从零开始的工程师:第 1-5 章打底(约 2-3 周),理解 ML4T 的完整生命周期;然后选一个 Part 2 的算法(推荐随机森林,第 11 章)做完整 case,从头跑到尾;确认流程跑通后,再切到 Part 3/4 探索 NLP 和 DL。不要一上来就冲深度学习章节——没有前面的数据工程和回测基础,DL 模型的结果你无法判断是信号还是过拟合。
已有交易经验的从业者:直接跳到第 4 章(特征工程)和第 8 章(Zipline 端到端),把自己已有的因子和策略逻辑用书中的 Pipeline API 重新表达一遍。24 章附录的 100+ 因子不要当信号直接使用——拿它们当“因子研究方法论”的教材:看 Jansen 怎么提假设、怎么评估 IC、怎么做组合,然后把这个方法论套到你自己熟悉的市场上。
带研究方向的硕士/博士生:第 18/20/21 章的论文复现是快速进入金融 DL 文献的入口。建议按以下顺序:先跑通第 20 章(Autoencoder 资产定价),因为 Gu/Kelly/Xiu 的论文在学术引用量上最高,理解这篇就打通了条件风险因子这条线;再决定是走 CNN(时序→图像)还是 GAN(合成数据),而不是两篇同时啃。
三条通用原则:
- 训练/测试严格分时间窗(walk-forward,而非随机 K-fold),这是金融数据时序依赖的硬约束。
- 用
pyfolio同时看样本内和样本外的 Sharpe、max drawdown、turnover——如果样本外 Sharpe 不到样本内的一半,大概率过拟合。 - NASDAQ ITCH 与 SEC filings 有使用条款,商业用途需确认 license;Algoseek 数据需购买。
引用与延伸阅读
- 仓库主页:https://github.com/stefan-jansen/machine-learning-for-trading
- 配套书籍购买:https://www.amazon.com/Machine-Learning-Algorithmic-Trading-alternative/dp/1839217715
- 项目主页:https://ml4trading.io
- 社区平台:https://exchange.ml4trading.io
- 作者博客:https://ML4Trading.io/
本文基于 Stefan Jansen《Machine Learning for Algorithmic Trading》2nd Edition (2020) 与对应 GitHub 仓库(commit 截至 2026-06-01)。所有 notebook 路径以仓库 main 分支为准。读者应自行评估文中提及的所有策略在真实市场的可交易性。