首页
/ Qlib 版本演进全景解析:从 v0.1.0 到 v0.8.0 的算子语法、数据服务化与回测框架重构

Qlib 版本演进全景解析:从 v0.1.0 到 v0.8.0 的算子语法、数据服务化与回测框架重构

2026-09-07 09:06:36作者:苗圣禹Peter

本文以 Qlib 官方变更日志 CHANGES.rst(由 docs/changelog/changelog.rst.. include:: 方式引入文档站)为主体,系统梳理 Qlib 从 v0.1.0 到 v0.8.0 的完整演进脉络,并结合当前仓库源码逐一印证关键特性。读完本文,你将理解 Qlib 的特征算子 DSL、数据缓存/Provider 体系、真实价格回测、在线推理框架与嵌套决策执行等核心能力分别诞生于哪个版本,以及在版本切换时哪些 API 与默认行为发生了不兼容变化,从而为升级迁移、复现历史回测结果提供依据。

一、变更日志文档的定位与阅读方式

在仓库中,docs/changelog/changelog.rst 本身只有一行指令:

.. include:: ../../CHANGES.rst

这意味着文档站渲染出的“变更日志”页面,其全部正文都来自仓库根目录的 CHANGES.rst。该文件按照“版本号 + RST 章节标题”的格式逐版记录变更,覆盖了 v0.1.0(Qlib 的初始发布)至 v0.8.0(回测框架重大重构后的版本)的完整历史,是定位 API 废弃、行为调整与架构重构的第一手依据。文件末尾的 Other Versions 小节提示:v0.8.0 之后的更多版本变更请查阅官方 Release Notes。

阅读该文档时需注意两点:

  1. 它记录的是“当时的”行为。许多条目描述的是当时 API 的默认值或接口形态,而这些 API 在后续版本中可能已再度重构(例如 estimator、fetcher、topk 策略等),因此本文在对照源码时会明确区分“历史记载”与“当前仓库实现”。
  2. 部分版本存在可量化的回测差异。日志中对 risk_analysis 年度化参数、long_short_backtest 行为等给出过明确数值说明(详见下文 v0.4.4 一节),这类提示对结果复现极为关键。

二、版本阶段总览

版本区间 阶段主题 里程碑事件
v0.1.0 – v0.1.3 库雏形与特征算子 初始发布;算子运算符语法(High() - Low());标的过滤机制
v0.2.0 – v0.2.4 数据层与回测雏形 LocalProvider 存储重构;字符串/动态字段;disk_cacheqlib.contrib;backtest 模块与收益归因
v0.3.0 – v0.3.5 数据处理器与训练重构 estimator/filter 模块;真实价格交易;finetune;多标签训练;DataFrame 化的 handler
v0.4.0 – v0.4.6 数据服务化与在线化 data 包重组、qlib-server/ClientProvider;Windows 支持;Alpha360 handler;在线推理交易框架;report 模块;多内核实现
v0.5.0 首次开源发布 精修文档与代码;公开数据采集器;加入 baselines
v0.8.0 回测框架重构 嵌套决策执行框架;做多/做空交易限制区分;年度化常量修正

三、早期算子语法时代(v0.1.0 – v0.1.3)

1. 初始发布与算子扩充(v0.1.0 / v0.1.1)

v0.1.0 是 Qlib 的初始版本("initial release"),v0.1.1 聚焦性能优化,并“增加更多特征与算子”(features and operators)。这一阶段确立了 Qlib 的核心抽象之一——数据算子(Operator)体系:用户通过组合算子来表达衍生特征,而不是直接手工写面板数据变换。

2. v0.1.2:算子运算符语法是数据表达式 DSL 的起点

v0.1.2 引入了一个至今影响深远的能力:

支持算子运算符语法,High() - Low() 等价于 Sub(High(), Low())

从当前源码可以印证这一设计的底层实现。在 qlib/data/base.py 中,抽象类 Expression 通过 Python 运算符重载将算术符号翻译为算子对象:

def __add__(self, other):
    from .ops import Add
    return Add(self, other)

def __sub__(self, other):
    from .ops import Sub
    return Sub(self, other)

__mul____div____pow____and__ 等也以同样方式映射到 ops.py 中对应的算子类(如 Sub 定义于 qlib/data/ops.pyRef 定义于第 781 行)。这层设计意味着:

  • 特征既可以写成函数式形态(Sub(High(), Low())),也可以写成自然算术形态(High() - Low());
  • 结合后续版本引入的字符串字段,表达式可以脱离 Python 代码、直接以配置文件中的字符串描述(见 v0.2.1),成为整个因子配置化的基础。

同版本还“增加了更多技术指标(technical indicators)”,进一步丰富了内置算子库。

3. v0.1.3:标的过滤机制(instruments filtering)

v0.1.3 在修复 bug 的同时,加入了标的(instruments)过滤机制,用于按股票池(如 csi300、csi500)圈定研究范围。这一机制沿用至今——日常数据访问入口 qlib.data.D.instruments 即可按市场/指数名称获取标的集合;filter 逻辑对应的实现位于 qlib/data/filter.py(filter 模块在 v0.3.1 被正式独立为公开模块)。

四、数据层与回测雏形成型(v0.2.0 – v0.2.4)

1. v0.2.0:存储格式重构与数据构建脚本

v0.2.0 对 LocalProvider数据库格式进行了重新设计以提升性能,新增“以字符串字段加载特征”的能力,并提供了数据库构建脚本。当前仓库中的 scripts/dump_bin.pyscripts/dump_pit.py 等工具即属于该方向——把原始行情/财务数据转存为 Qlib 二进制存储(bin 文件,由 qlib/data/storage 中的文件存储实现读写)。

2. v0.2.1:自定义 Provider、字符串算子与动态字段

v0.2.1 是数据表达式体系的关键一跃:

  • 支持注册用户自定义的 Provider
  • 支持以字符串形式书写算子字段,例如 ['Ref($close, 1)'] 直接作为字段名合法;
  • 支持 $some_field 形式的动态字段,同时预告旧的函数式字段写法(如 Close())可能在未来废弃。

$close$open$volume$factor 这类以 $ 前缀表达的字段在后来的版本中成为 Qlib 数据的标准约定——例如 qlib/backtest/exchange.py 的注释即说明成交价字段 $close/$open/$vwap 会由 Exchange 自动补全 $ 前缀。动态字段约定让“字段”与“算子”在字符串表达式中解耦,极大提升了配置文件的可读性与跨语言可移植性。

3. v0.2.2:disk_cache 与 qlib.contrib

v0.2.2 引入两项对工程化至关重要的能力:

  • disk_cache(磁盘缓存),用于复用已计算的特征,且默认开启。缓存机制的当前实现位于 qlib/data/cache.py;同一表达式的计算结果只计算一次,后续实验直接命中缓存,这正是反复调参实验能高效进行的前提。
  • qlib.contrib,一个承载“实验性模型构建与评估”的包。它演化为今天 qlib/contrib 下的庞大家族:数据侧有 Alpha158/Alpha360 等 handler 与高频数据模块,模型侧有 qlib/contrib/model 下的 CatBoost、LightGBM、XGBoost 以及各类 PyTorch 深度模型(GRU、LSTM、Transformer、Localformer、HIST、TRA、TFT 等),策略侧有 qlib/contrib/strategy 的成本控制与信号策略,此外还包含 rolling 滚动训练、tuner 超参搜索、report 分析等模块。

4. v0.2.3:backtest 模块与四大对象解耦

v0.2.3 新增 backtest 模块,并把回测中的 Strategy(策略)、Account(账户)、Position(持仓)、Exchange(交易所) 解耦为独立对象。当前仓库 qlib/backtest 目录完整保留了这套分层:exchange.pyaccount.pyposition.pystrategy 相关定义与 executor.pydecision.py 等共同构成了“策略生成交易决策 → executor 下达指令 → exchange 撮合 → position/account 记账”的回测链路。解耦的意义在于:任一环节都可以被替换(例如自定义撮合规则、自定义交易成本模型),而无需改动其余环节。

5. v0.2.4:收益归因与风控/成本策略

v0.2.4 加入 profit attribution(收益归因)模块,对应 qlib/backtest/profit_attribution.py;同时引入 rick_control(日志原文拼写,即风控)与 cost_control(成本控制)策略。成本控制策略的现代形态可见 qlib/contrib/strategy/cost_control.py

五、数据处理器与训练体系重构(v0.3.x)

1. estimator 与 filter 模块(v0.3.0 / v0.3.1)

v0.3.0 增加 estimator 模块;v0.3.1 增加 filter 模块。filter 在数据路径中承担标的过滤职责,对应 qlib/data/filter.py。需要说明的是,根据日志记载 estimator 模块在此版本出现,但从当前仓库目录看该模块已并入或重构至其他体系,读者在复用 v0.3.x 时代文档时应以现有包结构为准。

2. v0.3.2:真实价格交易与训练组件重构

v0.3.2 是一个行为变化较密集的版本:

  • 真实价格交易:若数据集中 factor(复权因子)字段不完整,则改用 adj_price(后复权价格)进行交易,避免因子缺失导致撮合价失真;
  • 重构 handlerlaunchertrainer 三块代码;
  • 支持在配置文件中直接书写回测(backtest)配置参数——这使 YAML 工作流成为可能,如今 examples/benchmarks 下每个模型的 workflow_config_*.yaml 都包含完整的回测段;
  • 修复持仓 amount 为 0 的 bug,并修复 filter 模块的 bug。

3. finetune 与 fetcher 重构(v0.3.3 / v0.3.4)

v0.3.3 再次修复 filter 模块问题;v0.3.4 支持模型微调(finetune),并重构 fetcher 代码。finetune 能力为“先在大数据集上预训练、再在目标池上精调”的范式提供了基础,也是 qlib/contrib/model 中多个深度模型在冷启动/滚动场景下的常规操作。

4. v0.3.5:handler 的 DataFrame 化与多标签训练

v0.3.5 重构了 handler,其影响一直延续到今天:

  • 支持多标签训练,可在 handler 中提供多个 label(日志特别注明:LightGBM 因算法本身的限制不支持多标签);
  • dataset.py 不再被使用;用户可以在 feature_label_config 中自行部署自己的特征与标签;
  • handler 只输出 DataFrame,trainermodel.py 也只接收 DataFrame——统一了各组件间的数据契约;
  • 变更 split_rolling_data滚动切分改为基于交易日历(market calendar)滚动,而非普通自然日,从而保证训练/验证/测试切分对齐实际交易边界;
  • 部分日期相关配置从 handler 迁移至 trainer

六、v0.4.x:数据服务化、在线化与报告体系

v0.4.x 是 Qlib 架构信息量最大的版本段,承载了从“单机研究库”向“可服务化、可上线”平台演进的关键一步。

1. v0.4.0:数据包重组与 server/client 架构

  • 新增 data 包,集中所有与数据相关的代码;
  • 重构数据提供者(Provider)结构
  • 创建用于数据集中管理的服务端 qlib-server,并新增配套的 ClientProvider,使本地代码能以客户端方式远程取数;
  • 引入可插拔的缓存机制
  • 引入递归回溯算法,用于检查某个特征表达式能够追溯到的最远依赖日期(对 Point-in-Time 计算与数据起始日期校验很有价值,相关数据结构可参考 qlib/data/pit.pyqlib/data/cache.py)。

该版本还给出了一条重要的兼容性说明D.instruments 不再支持 start_timeend_timeas_list 参数。若希望得到旧版本 D.instruments 的效果,应改为以下写法:

>>> from qlib.data import D
>>> instruments = D.instruments(market='csi500')
>>> D.list_instruments(instruments=instruments, start_time='2015-01-01', end_time='2016-02-15', as_list=True)

也就是说,取标的集合与按时间段展开为股票列表这两步被拆分为两个 API,D.instruments 负责返回标的对象,D.list_instruments 负责按时间窗展开。

2. v0.4.1:跨平台与多项修复

  • 正式支持 Windows
  • 修复 instruments 的类型 bug、features 为空导致更新失败的 bug;
  • 修复 cache 加锁与更新问题,并修复“同一字段却各自新建缓存”的问题——同名同参数的特征字段应复用同一份缓存;
  • 将“logger handler”改为从配置读取;
  • 模型加载逻辑调整为兼容 v0.4.0 及之后的模型文件;
  • 行为变化risk_analysis 函数的 method 参数默认值由 ci 改为 si

3. v0.4.2:DataHandler 重构与 Alpha360

v0.4.2 重构 DataHandler,并新增 Alpha360 DataHandler。Alpha360 以过去 60 个交易日 × 6 类基础量价信息构成 360 维特征,是 Qlib 最重要的两大内置特征集之一(另一为 Alpha158)。翻看 examples/benchmarks 下各模型目录即可发现,绝大多数模型同时提供了 workflow_config_xxx_Alpha158.yamlworkflow_config_xxx_Alpha360.yaml 两套可直接运行的工作流配置。

4. v0.4.3:在线推理与交易框架

v0.4.3 实现了在线推理与交易框架(Online Inference and Trading Framework),并重构了 backtest 与 strategy 模块的接口。当前仓库中 qlib/workflow/online 下的 manager.pystrategy.pyupdate.py 以及 qlib/contrib/online 中的 operator/user/manager 即该框架的现代形态,支撑“模型上线后的每日滚动预测与交易”场景。

5. v0.4.4:报告模块、回测参数重构与可量化差异提示

  • 优化缓存生成性能;新增 report 模块(现在的 qlib/contrib/report 提供模型表现分析、风险分析、收益归因等一系列分析图表);
  • 修复 ServerDatasetCache 在离线场景下的 bug;
  • long_short_backtest 行为变化:旧版本中 long_short 计算存在出现 np.nan 的情况,v0.4.4 修复后结果会与旧版本不同;
  • risk_analysisN 值变化:v0.4.2 中 N=250,v0.4.3 起 N=252(按一年约 252 个交易日年化),导致 v0.4.2 与 v0.4.3 的年度化指标相差约 0.002122,回测结果也随之略有差异。当前 qlib/contrib/evaluate.pyrisk_analysis 已进一步演进:可通过 freq 自动推导年化缩放因子(内置周度 50、月度 12 等常量),并支持 mode="sum"(算数累加)与 mode="product"(几何复利累乘)两种累计方式;
  • 回测函数参数重构,其中特别提示:
    • topk margin 策略的默认参数已改变,若要复现旧版本回测结果,请显式传入参数;
    • TopkWeightStrategy 行为有轻微变化:会尝试卖出超出 topk 数量的股票(TopkAmountStrategy 的结果保持一致);
    • Topk Margin 系列策略中支持保证金比例(margin ratio)机制

6. v0.4.5:多内核实现与 dict 配置

  • 为 client 与 server 增加多内核(multi-kernel)实现:新增一种跳过 dataset cache、直接从 client 加载数据的方式;默认数据集方法由单内核实现切换为多内核实现;
  • 通过优化相关模块加速高频数据读取
  • 支持用 dict 直接书写配置文件(无需先落盘为文件再加载)。

7. v0.4.6:日频兼容性修复

v0.4.6 主要修复两类问题:v0.4.5 的默认配置对日频数据不友好TopkWeightStrategyWithInteract=True 时回测报错。

七、v0.5.0:首次开源发布

v0.5.0 是 Qlib 的首个开源版本,核心工作是让代码库达到可对外发布的质量:

  • 精修文档与代码(refine the docs, code);
  • 加入 baselines(基线模型)——今天 examples/benchmarks 下涵盖 LightGBM、XGBoost、CatBoost、GRU、LSTM、Transformer、Localformer、HIST、TRA 等数十个模型与完整 YAML 工作流的基线体系即由此发展而来;
  • 提供公开数据爬虫(public data crawler)——对应 scripts/data_collector 下的 Yahoo、baostock、cn_index、fund、crypto 等各类数据采集器,负责拉取并清洗公开行情/基本面数据。

八、v0.8.0:回测框架重大重构与嵌套决策执行

v0.8.0 是一次“伤筋动骨”的回测重构,日志明确表示“每日交易相关改动非常多,难以一一列出”,仅点出以下重要变化:

1. 嵌套决策执行框架

回测开始支持**嵌套决策执行(Nested Decision Execution)**框架——高层决策可以在一个交易日内部展开为多层子决策,例如先按信号生成交易目标,再由调度器把大单拆分为多个时间段内的执行子任务(配合 qlib/rl 下的执行强化学习策略使用)。这一框架的当前实现位于 qlib/backtest/decision.pyqlib/backtest/executor.py,配套的可运行示例见 examples/nested_decision_execution/workflow.py

2. 交易限制更精确:做多与做空独立约束

旧版本中,做多与做空动作共享同一套交易限制;v0.8.0 起,做多与做空的交易限制彼此独立。这在当前 qlib/backtest/exchange.pyExchange 构造参数上得到了直接体现:limit_threshold 可以是一个二元组 (<买入限制表达式>, <卖出限制表达式>),表达式为 True 表示该方向当日被限制不可交易,False 表示可交易;因此完全能够为买入与卖出分别配置涨跌停等限制规则。

3. 年度化指标常量修正

v0.8.0 在计算年度化指标时采用了比旧版本更精确的常量(对比位置即 qlib/contrib/evaluate.py 中年度化逻辑的演化,日志称当前实现位于 evaluate.py#L42 附近;如今该文件中的 risk_analysis/cal_risk_analysis_scaler 已将不同频率的缩放常量统一管理,见上文 v0.4.4)。这一改动会系统性影响年度化收益率、信息比率等数值,跨版本对比指标时需注意口径一致。

4. 新版本数据发布与结果可复现性提醒

v0.8.0 发布了新版本的数据(对应 tests/data.py 中的数据约束)。由于 Yahoo 数据源不稳定,再次下载的数据可能与历史数据存在差异,从而影响结果复现。官方建议直接在 examples/benchmarks 下对比新旧版本的回测结果,评估重构带来的影响。

九、跨版本差异的实践影响与升级建议

综合 v0.4.x 至 v0.8.0 的多次“微调”,跨版本复现回测时需要特别留意以下口径类问题:

  1. 年度化参数口径:v0.4.2 的 N=250 → v0.4.3 起 N=252 → v0.8.0 起使用更精确常量。若要严格对齐旧结果,须显式指定 N 而非依赖默认值。
  2. Topk 策略默认参数:v0.4.4 起 topk margin 策略默认参数变化,TopkWeightStrategy 会卖出超出 topk 的部分。若想复现旧版资金曲线,应显式传参,例如参考 qlib/contrib/strategy/rule_strategy.py 中相关策略的构造函数。
  3. 标的接口拆分D.instruments 不再接受时间范围与 as_list,需配合 D.list_instruments 使用(见 v0.4.0 一节给出的 Python 示例)。
  4. 数据源与缓存:数据每次重新下载可能不同(Yahoo 稳定性);同字段复用缓存由 qlib/data/cache.py 统一管理,怀疑结果异常时优先排查缓存与数据版本。

十、如何继续追踪后续版本

CHANGES.rstOther Versions 一节说明:v0.8.0 之后的各版本变更统一收录于官方 Release Notes。就当前仓库而言,v0.8.0 之后代码库又持续扩充了大量能力(例如 qlib/rl 强化学习子框架、qlib/contrib/model 中不断增加的深度模型族、qlib/contrib/rolling 滚动训练体系等),读者可结合 docs 下的组件文档(component/data、component/model、component/rl 等)与 CHANGES.rst 对照阅读,把握“日志条目 → 组件实现 → 使用示例”的完整链路。在升级依赖或复用历史实验配置时,本文整理的版本时间轴可作为快速定位行为差异的索引。

登录后查看全文
热门项目推荐
相关项目推荐