简介:这份PDF文档是华泰证券金工研究团队出品的深度研究报告《微软AI量化投资平台Qlib体验》,面向量化投资研究者、金融工程从业者及希望入门AI选股的学生群体。报告系统梳理了Qlib的基础与进阶功能,对比传统量化策略开发流程,提炼其数据存储方案、表达式引擎、缓存系统等工程创新,并探讨实际使用体会。资源包内仅含1个PDF文件,大小约4.71MB,内容涵盖Qlib安装、数据准备、因子生成、策略构建与结果展示全流程,以港股日频量价因子LightGBM选股策略为案例,同时讲解自定义因子、标签、预处理方式与AI模型的进阶用法。目前已有1172人学习下载。读者可借此快速理解Qlib覆盖量化投资全过程的架构优势,掌握从零搭建AI选股策略的实操思路,并了解其相对MySQL、MongoDB、InfluxDB等方案在因子计算性能上的提升,适合作为量化研究入门与工具选型的参考材料。
1. Qlib 安装踩坑记:为什么我放弃了 pip 改用 setup.py
2020 年底 Qlib 刚开源那阵子,我正好在折腾港股量价因子选股的小项目,想着拿它跑一套 LightGBM 流程试试水。结果第一步安装就翻车了——pip install pyqlib在 Windows 上直接报Microsoft Visual C++ 14.0 is required,换到 Mac 上虽然能装上,但跑官方示例时又缺qlib.tests模块。后来翻文档才发现,Qlib 官方推荐 Python 3.7 及以上,而且 pip 装的是稳定版,setup.py 装的是开发版,两者在数据脚本和模块完整性上差别不小。这套环境适合做 AI 选股、因子挖掘的量化研究者,装不好连数据都下不下来,更别提跑策略了。下面把我从零装通 Qlib 0.6.1.dev0 的完整过程拆开讲,包括数据准备、因子生成、策略构建和验证,照着走能少踩不少坑。
2. 环境准备与 Qlib 安装:从 C++ 生成工具到 setup.py
2.1 先装 Microsoft C++ 生成工具,别只装运行组件
Qlib 底层依赖 Microsoft Visual C++ 14.0 编译环境,这是第一个硬门槛。很多人看到报错去装Microsoft Visual C++ Redistributable,结果发现根本不管用——运行组件只负责跑已编译好的程序,不提供编译能力。正确做法是装完整的 Microsoft C++ 生成工具,下载地址在微软官网的 Visual C++ Build Tools 页面。
安装时注意勾选「使用 C++ 的桌面开发」工作负载,右侧细节里确保勾上「MSVC v142 - VS 2019 C++ x64/x86 生成工具」和「Windows 10 SDK」。我一般还会把「C++ CMake 工具」也勾上,后面编译某些 Python 包时能省事。整个安装包大概 4-6 GB,装完重启一次命令行让环境变量生效。
提示:如果公司网络下载慢,可以只勾选 MSVC 和 Windows SDK 两项,能压到 2 GB 左右。
2.2 setup.py 安装 Qlib,开发版比稳定版更省心
装完 C++ 生成工具后,先更新两个基础库:
pip install numpy pip install --upgrade cython这两步别跳过。numpy 是 Qlib 数据运算的底层依赖,cython 用于编译 Qlib 的表达式引擎加速模块。版本上 numpy 建议 1.19 以上,cython 建议 0.29 以上,老版本在编译qlib.data._libs时会报语法错误。
接下来分两种情况。如果你机器上 git 可用:
git clone https://github.com/microsoft/qlib.git && cd qlib python setup.py install如果 git 不通(我办公环境就是这样),去 GitHub 下载 zip 源码包,解压到任意路径,比如C:/Users/username/anaconda3/Lib/site-packages/qlib,确保setup.py在该目录下,然后:
cd C:/Users/username/anaconda3/Lib/site-packages/qlib python setup.py installsetup.py 方式会自动拉取开发版依赖,我 2020 年 12 月 14 日装出来的是 0.6.1.dev0。这个版本比 pip 的稳定版多了scripts/get_data.py和scripts/dump_bin.py两个关键脚本,后面下数据和转格式全靠它们。装完后用python -c "import qlib; print(qlib.__version__)"验证,能打印版本号就说明编译通过了。
2.3 验证安装:检查关键模块是否齐全
装完别急着跑策略,先确认几个核心模块能正常导入:
import qlib from qlib.data import D from qlib.contrib.data.handler import Alpha158 from qlib.contrib.model.gbdt import LGBModel print("qlib version:", qlib.__version__) print("all core modules imported")如果Alpha158或LGBModel导入报错,大概率是 setup.py 安装时依赖没拉全,重新跑一遍python setup.py install即可。这一步过了,环境就算立住了。
3. 数据准备:get_data 下载与 dump_all 转换用户数据
3.1 get_data 下载官方数据,顺手补上 tests 模块
Qlib 自带 A 股和美股测试数据,下载命令在安装路径下执行:
cd C:/Users/username/anaconda3/Lib/site-packages/qlib python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn参数说明:qlib_data是数据集名称,--target_dir指定存储路径,--region cn表示下载 A 股数据。下载完数据落在C:/Users/username/.qlib/qlib_data/cn_data,包含 calendar、features、instruments 三个目录。
如果你是用 pip 装的 Qlib,跑这条命令可能报ModuleNotFoundError: No module named 'qlib.tests'。原因是 pip 包没打包 tests 目录,而 get_data.py 里引用了它。解决办法是从 GitHub 下载 zip 源码包,把里面的tests文件夹整个拷到 Qlib 安装路径下,再重新执行下载命令。
3.2 dump_all 转换港股 CSV 数据,字段和格式都有讲究
官方数据只能用来跑通流程,真做研究得用自己的数据。Qlib 支持 CSV 导入,但格式要求比较细。我拿港股行情做例子,数据从 2008 年初到 2020 年 11 月末,共 3739 只股票(含权证和已退市),每只股票存成一个 CSV 文件,文件名就是股票代码,统一放在hk_data文件夹下。
CSV 内部字段至少包含这些:
| 字段名 | 说明 | 字段名 | 说明 |
|---|---|---|---|
| stock_code | 股票代码,与文件名一致 | low | 复权最低价 |
| date | 日频日期 | close | 复权收盘价 |
| volume | 成交量 | factor | 复权因子 |
| money | 成交额 | vwap | 复权均价 |
| open | 复权开盘价 | change | 相对前一交易日涨跌幅 |
| high | 复权最高价 |
两个容易翻车的点:第一,价格数据官方文档没强调,但一定要用复权价。因为后续标签计算用 close 或 vwap 算未来收益率,回测用 close、open 或 vwap 做交易,不复权的话收益和净值会失真。第二,必须包含factor或change字段,否则跑examples/workflow_by_code.py时策略收益和净值会出现异常值。
指数数据也要准备,恒生指数按同样格式存成hkhsi.csv,放在同一目录下。然后回到 Qlib 安装路径执行转换:
python scripts/dump_bin.py dump_all \ --csv_path ~/.qlib/csv_data/hk_data \ --qlib_dir ~/.qlib/qlib_data/hk_data \ --symbol_field_name stock_code \ --date_field_name date \ --include_fields open,high,low,close,volume,money,factor,vwap,change参数逐个说:--csv_path是 CSV 所在目录,--qlib_dir是转换后 bin 文件的输出目录,--symbol_field_name指定股票代码列名,--date_field_name指定日期列名,--include_fields列出要保留的字段。注意--include_fields里逗号后面不能有空格,否则解析会出错,这个坑我踩过,报错信息还不明显,排查了半天。
转换完成后~/.qlib/qlib_data/hk_data下会生成 calendar、features、instruments 三个目录,features 里每只股票一个文件夹,里面是 bin 格式的列式存储。这套存储方案是 Qlib 的工程创新之一,读取速度比直接读 CSV 快很多,后面生成因子时能明显感觉到。
4. 因子生成与 LightGBM 策略构建:从 Alpha158 到回测
4.1 初始化环境与自定义股票池
数据就位后,先初始化 Qlib 运行环境并读取数据:
import qlib from qlib.data import D qlib.init(provider_uri="~/.qlib/qlib_data/hk_data", region="hk") # 获取交易日历和全部股票代码 cal = D.calendar(start_time="2008-01-01", end_time="2020-11-30") instruments = D.instruments(market="all") stock_list = D.list_instruments(instruments=instruments, start_time="2008-01-01", end_time="2020-11-30") print("交易日数量:", len(cal), "股票数量:", len(stock_list))qlib.init的provider_uri指向转换后的数据目录,region填hk表示港股。D.calendar拿交易日历,D.instruments配合D.list_instruments拿股票列表。如果你想限定股票池,比如只选恒生指数成分股,可以自己维护一个股票代码列表,传给D.instruments的market参数或直接用D.list_instruments过滤。
4.2 Alpha158 因子库生成特征和标签
Qlib 内置了 Alpha158 和 Alpha360 两个因子库,Alpha158 包含 158 个量价因子,适合日频选股。生成方式:
from qlib.contrib.data.handler import Alpha158 handler = Alpha158( instruments="all", start_time="2008-01-01", end_time="2020-11-30", fit_start_time="2008-01-01", fit_end_time="2017-12-31", infer_processors=[ {"class": "RobustZScoreNorm", "kwargs": {"fields_group": "feature", "clip_outlier": True}}, {"class": "Fillna", "kwargs": {"fields_group": "feature"}}, ], learn_processors=[ {"class": "DropnaLabel"}, {"class": "CSRankNorm", "kwargs": {"fields_group": "label"}}, ], label=["Ref($close, -2) / Ref($close, -1) - 1"], ) data = handler.fetch(col_set=["feature", "label"]) print("特征维度:", data["feature"].shape, "标签维度:", data["label"].shape)这里几个参数值得展开:fit_start_time和fit_end_time划定训练集范围,预处理器的归一化参数只在这段数据上拟合,避免未来信息泄露。infer_processors里的RobustZScoreNorm做稳健标准化并裁剪异常值,Fillna填充缺失。learn_processors里的DropnaLabel丢掉标签缺失的样本,CSRankNorm对标签做截面排序归一化。label表达式Ref($close, -2) / Ref($close, -1) - 1表示下期收益,即用后一天收盘价除以下一天收盘价再减一,注意 Qlib 的Ref负值表示未来。
4.3 LightGBM 模型训练与回测配置
因子准备好后,配置 LightGBM 模型和数据集:
from qlib.contrib.model.gbdt import LGBModel from qlib.contrib.data.dataset import DatasetH model = LGBModel( loss="mse", colsample_bytree=0.8, learning_rate=0.05, subsample=0.8, lambda_l1=1, lambda_l2=1, max_depth=8, num_leaves=210, num_threads=10, verbosity=-1, ) dataset = DatasetH( handler=handler, segments={ "train": ("2008-01-01", "2017-12-31"), "valid": ("2018-01-01", "2019-12-31"), "test": ("2020-01-01", "2020-11-30"), }, ) model.fit(dataset) pred = model.predict(dataset) print("预测结果样例:", pred.head())LightGBM 参数里learning_rate和num_leaves是调参重点,lambda_l1、lambda_l2控制正则化强度。数据集按时间切三段:训练集 2008 到 2017,验证集 2018 到 2019,测试集 2020 年前 11 个月。这种切法避免随机划分带来的未来信息泄露,是量化回测的基本纪律。
回测配置:
from qlib.contrib.evaluate import backtest_daily, risk_analysis from qlib.contrib.strategy import TopkDropoutStrategy strategy = TopkDropoutStrategy( signal=pred, topk=50, n_drop=5, ) port_analysis_config = { "strategy": strategy, "backtest": { "start_time": "2020-01-01", "end_time": "2020-11-30", "account": 100000000, "benchmark": "hkhsi", "exchange_kwargs": { "freq": "day", "limit_threshold": 0.095, "deal_price": "close", "open_cost": 0.0005, "close_cost": 0.0015, "min_cost": 5, }, }, } report, positions = backtest_daily(**port_analysis_config) analysis = risk_analysis(report["return"] - report["benchmark"]) print(analysis)TopkDropoutStrategy每期选预测分数最高的 50 只,卖掉其中 5 只。回测参数里account是初始资金,benchmark填恒生指数,limit_threshold是涨跌停限制,open_cost和close_cost是交易成本。这些参数直接影响回测结果的真实性,设得太乐观容易高估策略表现。
5. 避坑与排查:Qlib 安装配置中最容易翻车的五个点
5.1 报错 Microsoft Visual C++ 14.0 is required
现象:pip 或 setup.py 安装时编译 Cython 扩展失败,命令行抛出error: Microsoft Visual C++ 14.0 is required。
原因:系统缺少 MSVC 编译工具链,只有运行组件不够。
解决:去微软官网下载 Microsoft C++ 生成工具,安装时勾选「使用 C++ 的桌面开发」,确保 MSVC v142 和 Windows 10 SDK 都选中。装完重启命令行再试。
5.2 get_data 报 No module named 'qlib.tests'
现象:pip 安装 Qlib 后跑scripts/get_data.py报模块缺失。
原因:pip 包未包含 tests 目录,而 get_data.py 依赖其中的工具函数。
解决:从 GitHub 下载 zip 源码包,把tests文件夹拷到 Qlib 安装路径下。或者直接用 setup.py 方式安装,源码包里自带 tests。
5.3 dump_all 转换后数据为空或字段错位
现象:转换命令跑完,features 目录下没有文件,或者 bin 文件读出来全是 NaN。
原因:--include_fields逗号后带了空格,或者 CSV 里字段名与参数不匹配。
解决:检查--include_fields参数,逗号后不能有空格。确认 CSV 列名与--symbol_field_name、--date_field_name一致。转换前先用head看一眼 CSV 前几行。
5.4 回测收益和净值异常
现象:策略回测结果收益曲线平滑得不像话,或者净值突然暴涨暴跌。
原因:CSV 数据缺少factor或change字段,或者价格未复权。
解决:确保 CSV 包含factor和change字段,价格用复权价。检查dump_all的--include_fields是否包含这两个字段。
5.5 Alpha158 因子生成时报内存不足
现象:handler.fetch()时进程被 kill,或者报 MemoryError。
原因:全市场 3739 只股票、十几年日频数据一次性加载,内存扛不住。
解决:缩小股票池,比如只选恒生指数成分股;或者缩短时间范围,先跑 2015 到 2020 年。也可以在Alpha158初始化时设置instruments为自定义列表,减少数据量。
6. 装完怎么验证跑通:从 IC 到净值曲线
环境装完、数据转好、策略跑通之后,怎么确认这套 Qlib 是真的在工作,而不是在自欺欺人?我一般会走三步验证。
第一步,看模型预测的 IC 和 Rank IC。IC 是预测值和实际收益的相关系数,Rank IC 是排序后的相关系数。正常量价因子模型日频 IC 在 0.03 到 0.08 之间算合理,Rank IC 略高一些。如果 IC 接近 0 或者为负,说明因子没生效或者数据有问题。代码:
from qlib.contrib.evaluate import calc_ic ic, ric = calc_ic(pred["score"], pred["label"]) print("IC均值:", ic.mean(), "Rank IC均值:", ric.mean())第二步,看回测净值曲线和基准的对比。把report里的return、benchmark、excess_return画出来,正常策略净值应该围绕基准波动,超额收益曲线缓慢向上。如果净值曲线是一条直线或者波动极小,大概率是交易成本没设对,或者股票池里全是低流动性股票。
第三步,检查换手率和最大回撤。换手率反映策略交易频率,TopkDropout 策略日频换手率在 5% 到 15% 算正常。最大回撤要和基准对比,如果策略回撤远大于基准,说明风控没做好。这些指标在risk_analysis的输出里都有。
我自己的习惯是,每次装完 Qlib 或者换数据源,都强制走一遍这三步验证,哪怕只是换个股票池。有一次我图省事跳过了 IC 检查,直接看净值曲线觉得还行,结果后来发现标签表达式写错了,Ref的正负号搞反,模型在预测历史收益而不是未来收益,净值曲线照样好看,但实盘完全不能用。从那以后我每次跑新数据都先打印 IC 和 Rank IC,确认因子方向对了再往下走。
希望帮到你。
本文还有配套的精品资源,点击获取