简介这份PDF资料是华泰证券金工研究团队2020年12月发布的深度研究报告聚焦微软AI量化投资平台Qlib的实操体验面向量化投资研究者、金融从业者及希望降低AI算法使用门槛的学习者。报告以港股日频量价因子LightGBM选股策略为案例分Qlib安装、数据准备、因子生成、策略构建、结果展示等步骤讲解基础功能并进一步介绍自定义因子、标签、数据预处理方式与AI模型等进阶组件同时对比传统量化开发流程提炼Qlib在数据存储方案、表达式引擎和缓存系统上的工程创新。资源包共1个PDF文件约4.71MB内容完整、结构清晰便于按章节检索学习。目前已有1173人学习下载适合希望快速上手Qlib、理解其优势与局限并借鉴案例设计新应用场景的读者参考。1. 从一份研报说起Qlib 到底能不能直接拿来跑策略2020 年底一份金工深度研报在圈子里传开主题是体验一个刚开源不久的 AI 量化投资平台。当时很多人第一反应是又一个“覆盖全流程”的大饼。我最初也是这个态度直到自己把它的安装、数据转换、因子生成、LightGBM 选股、回测这条链路完整走了一遍才意识到它的价值不在“道”上而在“术”上——它没有颠覆传统因子选股方法论但把因子数据存储、表达式计算、缓存这些工程环节重做了一遍让一个熟手从零到跑出第一条净值曲线的时间从几天压到半天。这篇笔记就按我实际复现的顺序拆它是什么、怎么装、数据怎么灌、策略怎么搭、坑在哪。适合手里有 csv 行情数据、想快速验证量价因子想法的人不适合指望开箱即得 alpha 的人。2. 装 Qlib 之前先把环境这关过了C 生成工具与 setup.py 两条路安装是绝大多数人翻车的第一站而且报错信息往往指向一个和 Python 无关的东西。这一章把安装拆成“依赖准备”和“两种安装方式的选择”两块顺带说清为什么我更推荐源码方式而不是 pip。2.1 为什么 pip install pyqlib 经常不够用官方给了两条安装路径pip install pyqlib装最新稳定版或者下载源码跑setup.py install装包含开发版在内的最新代码。pip 那条路看起来最省事但它有两个隐性前提一是你的机器上得有 Microsoft Visual C 14.0 的编译环境二是 pip 包里的tests目录往往不全后面跑官方数据下载脚本时会直接报ModuleNotFoundError: No module named qlib.tests。我当时的实际选择是源码方式原因很朴素办公网络拉 git 不稳干脆下 zip 包解压到 site-packages 下再装。这条路的好处是源码、脚本、tests 全都在手边后面改组件、看实现都方便。代价是要手动处理编译依赖。先装编译工具。注意这里有个高频误解只装 Microsoft Visual C Redistributable 运行组件是没用的报错依旧。必须装完整的生成工具Build Tools安装时勾选“使用 C 的桌面开发”那一组工作负载否则编译 cython 扩展时会继续报Microsoft Visual C 14.0 is required。# 先确保 numpy 和 cython 是最新的否则编译扩展容易失败 pip install numpy pip install --upgrade cython # 方式一有 git 且网络通 git clone https://github.com/microsoft/qlib.git cd qlib python setup.py install # 方式二下 zip 源码包解压到任意路径示例放在 site-packages 下 # 确保 setup.py 就在该目录下然后在该目录启动命令行 cd C:/Users/username/anaconda3/Lib/site-packages/qlib python setup.py install上面两段命令的逻辑差异要说清楚git clone那条会拿到完整仓库历史适合想跟进上游改动的人zip 解压那条拿的是某个时间点的快照适合网络受限或只想稳定复现的人。setup.py install会顺带把开发版依赖一起装上装完的版本号可能带dev后缀我装到的是 0.6.1.dev0 这一类这不是问题反而说明你拿到的是比 pip 稳定版更新的代码。参数层面没什么可调的真正要盯的是安装日志末尾有没有编译错误。如果看到 cython 编译阶段报缺失头文件八成还是生成工具没装全回去补勾工作负载别在 Python 层面反复折腾。2.2 装完先验证别急着灌数据装完不要直接冲数据准备先花两分钟确认包能正常导入、脚本目录存在。常见做法是在 Python 里import qlib看有没有报错再去安装路径下确认scripts/和qlib/tests/两个目录都在。前者是后面get_data.py、dump_bin.py的所在地后者是 pip 安装方式最容易缺的东西。这一步省下来后面会以更难排查的形式还给你。3. 数据准备官方数据下载与用户 csv 转 bin 的完整链路Qlib 不吃原始 csv它有自己的二进制存储格式。这一章分两条线一条是拿官方 A 股/美股数据快速跑通另一条是把你手里的港股 csv 灌进去。后者才是真实工作场景也是坑最密集的地方。3.1 get_data 下载官方数据以及那个 tests 报错官方数据下载命令要在 Qlib 安装路径下执行因为它依赖同目录的scripts/get_data.py# 在 Qlib 安装路径下启动命令行 python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn参数含义qlib_data是数据集的标识--target_dir指定落地目录--region cn表示 A 股换成 us 就是美股。下载完成后数据落在~/.qlib/qlib_data/cn_data里面是 calendar、features、instruments 三块结构。如果你是用 pip 装的这条命令大概率报ModuleNotFoundError: No module named qlib.tests。原因不复杂pip 包裁剪了测试目录而下载脚本内部引用了它。解决办法是把源码 zip 里的tests目录拷到安装路径下或者干脆改用源码安装。这个坑我踩过一次后来一律源码安装省心。3.2 dump_all 把港股 csv 转成 bin字段和参数逐项说真实场景里你手里是自己的行情数据。研报里用的是港股日频数据组织方式是每只股票一个 csv文件名就是股票代码统一放在hk_data文件夹下时间跨度 2008 年初到 2020 年 11 月末含权证和已退市股票共 3739 只。每个 csv 内部至少要有这些字段字段说明字段说明stock_code股票代码与文件名一致low复权最低价date日频日期close复权收盘价volume成交量factor复权因子money成交额vwap复权均价open复权开盘价change相对前一交易日涨跌幅high复权最高价这里有两个必须点名的坑。第一价格要用复权价。原因在源码里后续数据标注qlib.contrib.data.handler用 close 或 vwap 算未来收益率回测qlib.contrib.evaluate.backtest用 close、open 或 vwap 成交你喂不复权价收益率和成交价全是错的。第二数据里必须包含factor或change字段缺了它跑官方全流程范例examples/workflow_by_code.py时策略收益和净值会出现异常——不是报错是数值不对这种静默错误最难查。除个股外还要准备基准指数把恒生指数按同样格式存成hkhsi.csv放在同一路径。然后执行转换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告诉脚本哪一列是股票代码这里是stock_code--date_field_name指定日期列--include_fields列出要保留的其余字段。最后一个参数有个致命细节逗号后面不能有空格写成open, high, low会直接导致转换出错。这个空格问题坑过不少人因为肉眼几乎看不出来。转换成功后--qlib_dir下会出现 calendar、features、instruments 三块features 里是按股票代码分目录的 bin 文件。到这一步数据层就算通了。4. 从因子到净值Alpha158 加 LightGBM 的选股策略怎么搭数据灌进去只是开始真正体现 Qlib 设计思路的是它把“因子生成—模型训练—回测”串成一条 workflow。这一章按初始化、股票池、因子、模型、回测的顺序走每步给出可抄的代码和参数解释。4.1 初始化运行环境与自定义股票池一切从初始化开始告诉 Qlib 数据在哪、用哪个市场import qlib from qlib.constant import REG_HK # 指向刚才 dump 出来的港股数据目录 qlib.init(provider_uri~/.qlib/qlib_data/hk_data, regionREG_HK)provider_uri必须和dump_bin.py的--qlib_dir一致region决定日历和交易规则。初始化之后可以取交易日历和全部股票代码用来确认数据读得对不对from qlib.data import D # 取交易日历和股票列表验证数据完整性 cal D.calendar(start_time2008-01-01, end_time2020-11-30) instruments D.instruments(marketall) codes D.list_instruments(instruments, start_time2008-01-01, end_time2020-11-30)股票池这块官方默认给的是全市场实际研究里通常要自己筛。常见做法是写一个 instruments 文件把可交易标的列进去再在配置里引用。研报里强调自定义股票池本质就是控制 universe避免把低价股、低流动性股票混进来污染回测——这一点在风险提示里也被专门点出案例本身没做这层过滤所以只能当教学看。4.2 Alpha158 因子库与标签生成Qlib 内置 Alpha158 和 Alpha360 两套因子库。Alpha158 是 158 个量价类特征标签默认是下期收益。生成特征和标签的核心是 handler 配置from qlib.contrib.data.handler import Alpha158 # 用 Alpha158 生成当期因子标签为下期收益 handler Alpha158( instrumentsall, start_time2008-01-01, end_time2020-11-30, fit_start_time2008-01-01, fit_end_time2017-12-31, # 训练段预处理参数只在这段上拟合 )这里的关键参数是fit_start_time/fit_end_time数据预处理比如标准化的统计量只在这段上算避免用到未来信息。这是很多人手写流程时容易忽略的地方Qlib 用参数把它显式化了。取因子和标签时分别调handler.fetch拿特征、拿 label逻辑上就是“当期因子对下期收益”训练集测试集按时间切别打乱。4.3 LightGBM 模型训练与 task 参数组织Qlib 把训练任务组织成一个task字典里面分model和dataset两块。模型部分指定 LightGBM 及其超参数据集部分指定 handler 和切分方式from qlib.contrib.model.gbdt import LGBModel from qlib.contrib.data.dataset import DatasetH # 模型参数LightGBM 的核心超参 model LGBModel( lossmse, learning_rate0.05, num_leaves64, max_depth8, num_threads8, ) # 数据集参数引用上面的 handler按时间切训练/验证/测试 dataset DatasetH( handlerhandler, segments{ train: (2008-01-01, 2017-12-31), valid: (2018-01-01, 2018-12-31), test: (2019-01-01, 2020-11-30), }, )learning_rate和num_leaves是最影响过拟合的两个旋钮量价因子信噪比低叶子数别开太大。segments的时间切分必须严格按时间先后训练段在前、测试段在后任何随机切分都会让回测结果虚高。训练就是model.fit(dataset)预测用model.predict(dataset)拿到的是每只股票每期的打分。4.4 回测配置与绩效结果读取回测配置port_analysis_config决定怎么用预测分数建仓、怎么算绩效from qlib.contrib.evaluate import backtest_daily from qlib.contrib.strategy import TopkDropoutStrategy # 策略每期取打分最高的 topk掉出 topk 的卖出 strategy TopkDropoutStrategy(topk50, n_drop5, signalpred_score) # 回测指定基准、交易成本、调仓频率 report, positions backtest_daily( start_time2019-01-01, end_time2020-11-30, strategystrategy, benchmarkhkhsi, account100000000, exchange_kwargs{freq: day, limit_threshold: 0.095, deal_price: close}, )topk50是持仓数量n_drop5是每期最多换掉的仓位数benchmark填你准备的指数代码limit_threshold是涨跌停限制港股没有涨跌停这里按案例设了个宽松值deal_price决定按收盘还是开盘成交。跑完拿report里的 IC、Rank IC、净值、超额收益、最大回撤、换手率。研报里展示的就是这几张图IC 和 Rank IC 看因子有效性净值曲线和最大回撤看策略稳健性换手率看成本压力。5. 自定义组件避坑改参数、改源码与四类高频翻车Qlib 的组件都通过 workflow 串联每个组件有对应参数也有对应源码。最简单的自定义是改参数更灵活的是仿照源码写继承类。这一章先讲自定义的层次再集中列踩坑记录。5.1 自定义因子、标签、预处理与模型的四个入口自定义特征在 handler 里加表达式或者继承 Alpha158 重写get_feature_config。自定义标签改 label 表达式比如把下期收益换成下期收益的排序分位。自定义预处理Qlib 内置了一批 processor在qlib.data.dataset.processor下Alpha158 和 Alpha360 各有默认预处理链想换就在 handler 配置里替换 processor 列表。自定义模型内置模型在qlib.contrib.model下想用 SVR 之类没内置的就仿照现有 Model 子类写一个实现fit和predict两个方法即可。四个入口的共同点是先看源码路径再决定改参数还是继承。研报里给了一张“各组件参数及对应源码路径”的对照表这个习惯值得学——改之前先定位源码比盲调参数高效得多。5.2 常见问题与排查记录现象一安装时报Microsoft Visual C 14.0 is required。原因只装了运行组件没装生成工具。解决装完整 Build Tools勾选 C 桌面开发工作负载重装。现象二get_data.py报No module named qlib.tests。原因pip 包裁剪了 tests 目录。解决下源码 zip把 tests 拷进安装路径或直接源码安装。现象三dump_all 转换报错或字段缺失。原因--include_fields逗号后带了空格。解决去掉所有空格重跑转换检查 features 目录下 bin 文件是否齐全。现象四策略净值和收益异常但不报错。原因csv 缺factor或change字段或用了不复权价。解决补齐字段、统一复权口径重灌数据再回测。现象五回测 IC 高得离谱。原因训练测试切分打乱或预处理统计量用了全样本。解决严格按时间切 segmentsfit_end_time卡在训练段末尾。6. 进阶验证用 IC 衰减和换手率给策略做体检跑出净值不等于策略能用。我后来养成一个习惯任何一条新 workflow 跑通后先不看净值先看 IC 的时间序列和衰减。具体做法是把测试段按季度切开逐段算 IC 和 Rank IC看因子有效性是稳定还是集中在某几段。如果 IC 只在某一两个季度高、其余接近零那大概率是过拟合到某段行情净值曲线再漂亮也不能信。第二个体检指标是换手率。TopkDropoutStrategy的n_drop直接控制换手n_drop调大换手上升、成本吃掉收益调小则持仓粘性高、可能错过调仓。我的经验是把换手率和交易成本一起看在exchange_kwargs里把成本设成偏保守的值如果策略在这个成本下净值还站得住才值得进一步调参。研报的风险提示里专门说了案例未剔除低价股、低流动性股票训练测试段也短所以那些净值只能当流程演示不能当业绩参考。还有一个容易被忽略的验证点把同一套因子换一个模型比如从 LightGBM 换成线性模型再跑一遍。如果 IC 量级差不多说明信号主要来自因子本身如果差距巨大说明模型在拟合噪声。这个对照实验花不了多少时间但能帮你判断到底是因子有用还是模型在“背答案”。从那以后我每次接一个新数据源都强制先跑一遍“字段完整性 复权口径 时间切分”三件套检查再谈策略。这三步任何一步偷懒后面调参调得再细都是白费。希望这套流程能帮你少走几个我踩过的坑。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?