系统化交易的难点,常常来自数据、研究、回测、组合构建和交易执行之间的衔接。GitHub 上的 paperswithbacktest/awesome-systematic-trading 把这条链路拆成多个目录,整理了 97 个用于研究和实际交易的库与包、40 多种策略论文、55 本书、23 个视频,以及博客和课程。
这份清单适合当作量化交易工具栈的地图。它不会替开发者做出唯一选择,却能把一个交易系统需要面对的工程边界逐项暴露出来:数据从哪里来,信号如何计算,策略如何回测,风险如何度量,组合如何优化,订单怎样通过经纪商 API 送出。

先把交易系统拆成六层
一个可维护的量化项目,至少可以拆成六层:
- 数据层:获取行情、基本面、订单簿和其他时间序列数据。
- 研究层:清洗数据、计算指标、提取特征、分析统计关系。
- 策略层:把规则或模型转成可执行的入场、出场和仓位逻辑。
- 回测层:在历史数据上重放事件,模拟成交、资金和持仓变化。
- 组合与风险层:分配资产权重,控制波动、集中度和回撤。
- 执行层:连接交易所或经纪商,处理订单、行情流、异常和状态恢复。
清单中的分类基本沿着这六层展开。TuShare、yfinance、AkShare 和 OpenBB Terminal 位于数据入口;ta-lib、pandas-ta、finta 负责指标;backtrader、backtesting.py、zipline、vectorbt 和 vnpy 负责回测或交易框架;PyPortfolioOpt、Riskfolio-Lib 和 pyfolio 对应组合优化与风险分析;ccxt 和 Ib_insync 则连接执行端。

这种分层方式解决了一个常见问题:开发者把“能跑出收益曲线”误认为“交易系统已经完成”。收益曲线只是研究输出,真正的系统还要回答数据更新、时区、复权、滑点、订单拒绝、断线重连和持仓对账等问题。
回测框架怎么区分
事件驱动:贴近交易过程
backtrader、zipline、vnpy、Rqalpha、nautilus_trader 和 aat 都属于事件驱动方向。系统按时间顺序处理行情事件,再调用策略逻辑,更新订单和持仓状态。
事件驱动框架适合描述真实交易中的过程:某个 bar 到达后计算信号,订单进入未成交状态,下一条行情到来时再判断成交或撤单。它的代码结构通常更接近实盘,因此便于把研究逻辑迁移到模拟交易或 live trading。
代价是模型运行会带有更多状态管理。你需要处理事件顺序、订单生命周期和手续费规则,也需要明确同一根 K 线中最高价、最低价和收盘价的可见性。策略逻辑写得越复杂,测试边界越多。
向量化:适合快速研究
vectorbt 的路径不同。它使用 pandas 和 NumPy 对象,并通过 Numba 加速,在较短时间内批量测试大量策略。对于参数扫描、信号组合和初步研究,向量化能够显著降低试错成本。
向量化的优势在于计算密度。假设策略只需要根据收盘价计算均线交叉,信号可以批量生成,多个窗口参数也可以一起运行。研究者能迅速发现参数空间中是否存在稳定区域,随后再把少量候选策略放进更接近实际成交过程的回测器。
两类框架并不冲突。一个更稳妥的工作流是:先用向量化框架搜索和筛选,再用事件驱动框架重放交易细节,最后在模拟盘验证订单状态。研究阶段追求速度,执行阶段追求状态完整性。
数据层决定回测上限
清单把数据来源单独列出,原因很实际:策略代码再漂亮,数据处理错误也会让结果失去意义。
TuShare 面向中国股票历史数据,AkShare 提供金融数据接口,yfinance 用 Python 方式下载海外市场数据,pandas-datareader 提供远程数据访问。基本面方向还有能够收集公司简介、财务报表、比率和股票数据的 Fundamental Analysis Data。
接入数据时,至少要把以下字段作为系统契约的一部分:
| 字段 | 要回答的问题 |
|---|---|
| 时间戳 | 数据属于哪个市场时区?多个来源如何对齐? |
| 价格口径 | 是原始价格、前复权价格,还是后复权价格? |
| 成交信息 | 回测使用收盘成交、下一根开盘成交,还是盘口成交? |
| 股票集合 | 是否包含退市标的?股票池在每个时点如何生成? |
| 缺失值 | 停牌、节假日、网络中断怎样标记? |
| 版本 | 原始数据和清洗后的数据是否可以重现? |
最危险的错误通常没有异常堆栈。比如用未来才知道的成分股列表构造过去的股票池,或者把复权后的价格用于模拟真实成交,程序都能正常运行,结果却已经包含未来信息。数据层应该记录下载时间、数据版本和处理步骤,让同一份研究可以重新执行。
指标、特征与模型应当分开
指标库和机器学习库位于清单的不同目录,这种安排值得保留在项目结构中。
ta-lib 提供金融市场技术分析能力;pandas-ta 列出 130 多个指标和 60 多种 TA-Lib 蜡烛图模式;go-tart 用 Go 实现技术分析库,并支持增量更新;ta-rust 则面向 Rust。它们解决的是信号计算问题。
QLib、FinRL、MlFinLab 和 TradingGym 解决的是机器学习量化研究问题。QLib 是面向 AI 的量化投资平台,FinRL 以深度强化学习为重点,MlFinLab 强调可重复和可解释的工具,TradingGym 可以作为训练强化学习代理或规则算法的交易环境。
工程上可以把一条特征流水线写成这样的接口:
class FeaturePipeline:
def fit(self, train_data):
"""只使用训练区间计算需要学习的参数。"""
raise NotImplementedError
def transform(self, data):
"""将已知参数应用到新数据。"""
raise NotImplementedError
def fit_transform(self, train_data):
self.fit(train_data)
return self.transform(train_data)关键点是 fit 和 transform 分离。标准化参数、缺失值填充规则或特征选择结果,都不能用完整历史数据一次性计算后再回到过去。模型训练、参数选择和测试应当有时间边界,测试区间只在最后一次评估时使用。
组合优化是信号之后的第二个决策
单个资产的预测信号并不会自动变成组合。多个信号同时出现时,系统还要决定每个资产放多少资金,以及资产之间的相关性如何处理。
PyPortfolioOpt 支持有效边界、Black-Litterman 和分级风险平价;Riskfolio-Lib 面向组合优化和定量战略资产配置;Deepdow 把组合优化与深度学习连接起来;quantstats 和 ffn 用于组合分析;pyfolio 面向投资组合与风险分析。
组合层可以用一个简单的约束问题表达:
最大化:预期收益 - 风险惩罚
约束:权重之和 = 1
约束:单个资产权重不超过上限
约束:行业或资产类别暴露不超过上限
约束:换手率不超过预算实际运行时,估计误差常常比求解器更麻烦。预期收益、协方差矩阵和相关性都来自样本,样本窗口稍微变化,权重就可能剧烈变化。因此组合模块应当保存输入矩阵、约束条件和求解结果,方便比较每次调仓之间的变化。
用仓库里的策略表读懂指标
README 的策略部分列出了 40 多篇策略论文,并按资产类别组织,表格包含夏普比率、波动率、再平衡频率、实现代码和论文链接。它同时保留了正值与负值结果,这一点很重要,因为策略清单不应只展示成功案例。
例如表中列出的几项数据如下:
| 策略 | 夏普比率 | 波动率 | 再平衡 |
|---|---|---|---|
| 时间序列动量效应 | 0.576 | 20.5% | 月度 |
| 资产类别趋势跟踪 | 0.502 | 10.4% | 月度 |
| 成对切换 | 0.691 | 9.5% | 季度 |
| 比特币隔夜季节性 | 0.892 | 20.8% | 日内交易 |
| 股票低波动因子 | 0.717 | 11.5% | 月度 |
| 股票短期反转效应 | 0.816 | 21.4% | 每周 |
| 动量因素效应 | -0.008 | 21.8% | 月度 |
| 应计项目异常 | -0.272 | 13.7% | 每年一次 |
这些数字适合用来理解研究结果的结构,不能脱离论文、样本区间、交易成本和资产范围单独使用。夏普比率需要和波动率、调仓频率一起阅读。一个日内策略的执行成本、数据粒度和成交假设,与月度组合完全不同;负值记录也提醒我们,策略名称本身不等于有效信号。
回测结果如何避免失真
量化回测最常见的风险有四类。
未来函数
特征计算使用了当前时点之后才会出现的数据,或者调仓时直接使用当天收盘价,却把成交也记在当天收盘。处理办法是为每个字段写明可见时间,并让信号至少在下一个可成交时点生效。
生存者偏差
只使用当前仍然存在的股票、基金或交易对,会自动排除退市和失败样本。股票池应该按历史时点重建,数据层也应记录标的进入和退出集合的日期。
过拟合
在同一段历史数据上反复调整参数,收益曲线会越来越漂亮,策略却未必更可靠。参数搜索需要留出验证区间,最终测试区间只使用一次。多策略比较也要记录尝试过的组合数量,避免只报告最好的那条曲线。
成交与成本
手续费、滑点、最小交易单位、涨跌停限制、流动性和订单延迟都会改变结果。事件驱动回测器需要把订单状态建模清楚,向量化研究则要把成本函数明确写入收益计算。纸面收益无法替代模拟成交。
一套可执行的选型顺序
可以按以下顺序搭建个人量化交易工具栈:
- 先固定数据契约:明确标的、时间粒度、复权口径、时区和版本。
- 选一个研究入口:Python 生态可以从 pandas、NumPy 和
vectorbt开始,快速验证信号。 - 选一个事件驱动回测器:把候选策略放入
backtrader、zipline、vnpy或其他事件框架,重放订单与持仓。 - 补齐分析模块:用
ta-lib或pandas-ta计算指标,用quantstats、ffn或pyfolio检查风险。 - 再接组合优化:根据资产数量和约束选择
PyPortfolioOpt、Riskfolio-Lib或其他优化工具。 - 最后连接执行端:加密货币方向可看
ccxt,Interactive Brokers 方向可看Ib_insync,同时实现订单对账和断线恢复。
这套顺序把研究速度和执行可靠性分开管理。开发者不需要一开始就搭建完整的分布式平台,但每增加一层,都要保留输入、输出和版本记录。
结语
awesome-systematic-trading 更像一份工程地图,而不是单一框架的推荐表。它把从数据获取到订单执行所需的组件放在同一个索引中,也把事件驱动与向量化、传统因子与机器学习、研究分析与实盘连接之间的差异展示出来。
对于个人开发者,第一步通常是从一条可复现的数据流水线和一个小型回测开始,逐步加入成本模型、组合约束和订单状态。对于已有 Go 或 React 工程背景的人,Python 可以承担研究和模型部分,Go 则适合承接数据服务、执行服务或状态管理,边界清晰后再决定是否拆分部署。
来源: