简介这份PDF文档是华泰证券金工研究团队出品的深度研究报告《微软AI量化投资平台Qlib体验》面向量化投资研究者、金融工程从业者及希望借助AI技术开展选股策略开发的读者。报告系统梳理了Qlib的基础与进阶功能对比传统量化策略开发流程提炼其特色与优势并分享实际使用体会。内容涵盖Qlib安装、数据准备、港股日频量价因子生成、LightGBM选股策略构建与结果展示以及自定义因子、标签、数据预处理和AI模型等进阶组件还探讨了数据存储方案、表达式引擎与缓存系统等工程创新。资源包为1个PDF文件大小约4.71MB结构完整、便于检索阅读。目前已有1172人学习下载适合希望快速上手Qlib、理解AI量化选股全流程并借鉴工程优化思路的读者参考。1. 从一份港股选股需求说起为什么我最终选了 Qlib 而不是自己搭一套去年帮一个做量化的朋友看他的研究流程发现一个很典型的问题数据用 csv 存、因子用 pandas 算、模型用 sklearn 训、回测自己写循环四个环节四套代码改一个因子要动三个文件。这不是个例很多做 AI 选股方向的人都是这么起步的。问题在于当股票池从几十只扩到几千只、因子从十几个扩到上百个时这套拼凑流程的维护成本会指数级上升。微软亚洲研究院开源的 Qlib 就是冲着这个痛点来的——它把数据存储、因子计算、模型训练、策略回测串成一条完整流水线用一套框架覆盖量化投资全过程。这篇方案面向两类人一是要做 AI 选股方向毕设或课设的同学需要一套能跑通、能讲清楚、能验收的完整流程二是想从零散脚本迁移到工程化框架的从业者。下面我以港股日频量价因子 LightGBM 选股策略为案例把从环境搭建到策略验收的每一步拆开讲。2. 总体方案设计三层架构与五个核心模块的职责划分2.1 为什么选 Qlib 而不是自己拼工具链传统量化策略开发流程通常是这样的用 Wind 或本地 csv 存行情数据用 pandas 做因子计算用 sklearn 或 LightGBM 训练模型再自己写回测循环。这套流程在股票池小、因子少的时候没问题但一旦规模上去三个瓶颈会同时出现。第一是数据读取慢csv 每次全量加载几千只股票的历史数据动辄几个 G内存和 IO 都吃不消。第二是因子计算重复同一个因子在不同策略里反复算没有缓存机制。第三是流程割裂因子生成、模型训练、回测各写各的参数传递靠手动改代码容易出错。Qlib 的方案是把这些环节统一到一个框架里。它的三层架构分别是基础架构层负责数据存储和计算加速量化投资流程层负责因子生成、模型训练和策略回测的串联交互层提供配置文件和代码两种使用方式。这个分层的好处是你可以在任意一层做自定义而不影响其他层。比如只想换一个 AI 模型改 workflow 配置里的 model 参数就行想换因子库改 data_handler 配置就行。2.2 五个核心模块的职责与数据流整个方案围绕五个模块展开数据从原始 csv 一路流到最终的回测报告。第一个模块是数据准备。Qlib 支持两种数据来源官方提供的 A 股和美股数据以及用户自己的 csv 数据。官方数据通过get_data脚本下载用户数据通过dump_all脚本转换。转换后的数据以 bin 格式存储配合 calendar 文件和 instruments 文件构成 Qlib 的数据底座。第二个模块是因子生成。Qlib 内置了 Alpha158 和 Alpha360 两个因子库Alpha158 包含 158 个量价因子覆盖 K 线形态、均线、波动率、成交量等维度。因子通过表达式引擎计算支持缓存同一个因子第二次调用时直接读缓存。第三个模块是模型训练。Qlib 内置了 LightGBM、XGBoost、CatBoost、MLP、LSTM 等多种模型通过 workflow 配置串联。训练时自动划分训练集和验证集支持自定义标签和预处理方式。第四个模块是策略回测。Qlib 的回测模块支持 TopK 选股、调仓周期设置、手续费和滑点配置输出净值曲线、超额收益、最大回撤、换手率等指标。第五个模块是结果分析。Qlib 提供 IC、Rank IC、分组收益等分析工具帮助判断因子和模型的有效性。这五个模块通过 workflow 配置文件串联一个典型的 workflow 配置包含数据 handler、模型、策略和回测四个部分。下面这张表概括了各模块的输入输出关系。模块输入输出关键配置项数据准备原始 csv 或官方数据bin 格式数据 calendar instrumentscsv_path、qlib_dir、include_fields因子生成bin 数据 因子表达式因子矩阵 标签handler 类、因子库名称模型训练因子矩阵 标签训练好的模型文件model 类、训练参数策略回测模型预测值 价格数据净值曲线 绩效指标选股数量、调仓频率、手续费结果分析回测输出IC 序列、分组收益、回撤分析分析指标选择2.3 环境搭建与数据准备的关键步骤环境搭建是第一个容易翻车的环节。Qlib 依赖 Microsoft Visual C 14.0如果系统里只有运行组件而没有完整生成工具安装时会报错。我一般建议直接装 Visual Studio Build Tools勾选 C 生成工具选项不要只装 Redistributable。安装 Qlib 本身推荐用 setup.py 方式比 pip 更可控。先确保 numpy 和 cython 已安装然后从源码包运行安装命令。# 先更新基础依赖 pip install numpy pip install --upgrade cython # 进入 Qlib 源码目录后执行 python setup.py install安装完成后验证版本确认安装成功。import qlib print(qlib.__version__) # 输出示例0.6.1.dev0数据准备分两种情况。用官方数据的话运行 get_data 脚本下载 A 股数据。python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn用自己的 csv 数据的话需要先按规范整理文件结构。每只股票一个 csv 文件文件名是股票代码所有文件放在同一个文件夹下。csv 内部必须包含的字段有股票代码、日期、开盘价、最高价、最低价、收盘价、成交量、成交额、复权因子、复权均价、涨跌幅。这里有两个坑后面会细说先记住价格要用复权价factor 字段不能省。整理好之后运行 dump_all 转换。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注意 include_fields 里的逗号后面不能有空格否则转换会报错。转换完成后目标目录下会出现 calendar、features 和 instruments 三个子目录分别存交易日历、因子数据和股票列表。3. 因子生成与模型训练从 Alpha158 到 LightGBM 的完整链路3.1 初始化运行环境与自定义股票池数据准备好之后第一步是初始化 Qlib 运行环境指定数据路径和区域。import qlib from qlib.constant import REG_HK # 初始化 Qlib指定港股数据路径 qlib.init(provider_uri~/.qlib/qlib_data/hk_data, regionREG_HK)初始化完成后可以获取交易日历和股票列表验证数据是否加载正常。from qlib.data import D # 获取交易日历 calendar D.calendar(start_time2020-01-01, end_time2020-11-30) print(f交易日数量{len(calendar)}) # 获取全部股票代码 instruments D.instruments(marketall) stock_list D.list_instruments(instrumentsinstruments, start_time2020-01-01, end_time2020-11-30) print(f股票数量{len(stock_list)})自定义股票池是实际项目里必须做的一步。官方示例通常用全市场股票但实际策略需要过滤掉低价股、低流动性股票和 ST 股票。Qlib 支持通过 instruments 文件或代码方式定义股票池。我一般会在数据准备阶段就生成一个过滤后的股票列表文件然后在初始化时指定。# 自定义股票池过滤掉日均成交额低于 1000 万港元的股票 from qlib.data import D # 获取指定字段数据用于筛选 fields [$volume, $close] data D.features(D.instruments(marketall), fields, start_time2020-01-01, end_time2020-11-30) # 计算日均成交额筛选流动性达标的股票 import pandas as pd daily_amount data[$volume] * data[$close] avg_amount daily_amount.groupby(levelinstrument).mean() filtered_stocks avg_amount[avg_amount 1e7].index.tolist() print(f过滤后股票数量{len(filtered_stocks)})3.2 Alpha158 因子库的调用与标签生成Alpha158 是 Qlib 内置的量价因子库包含 158 个因子覆盖 K 线形态、均线、波动率、成交量等维度。调用方式很简单在 workflow 配置里指定 handler 类即可。from qlib.contrib.data.handler import Alpha158 # 配置 Alpha158 因子库 handler_config { class: Alpha158, module_path: qlib.contrib.data.handler, kwargs: { start_time: 2008-01-01, end_time: 2020-11-30, fit_start_time: 2008-01-01, fit_end_time: 2017-12-31, instruments: all, }, } # 生成因子和标签 from qlib.data.dataset import DatasetH from qlib.data.dataset.handler import DataHandlerLP handler Alpha158(**handler_config[kwargs]) dataset DatasetH(handlerhandler, segments{ train: (2008-01-01, 2017-12-31), valid: (2018-01-01, 2019-12-31), test: (2020-01-01, 2020-11-30), }) # 获取训练集特征和标签 train_df dataset.prepare(train, col_set[feature, label]) print(f训练集特征维度{train_df[feature].shape}) print(f训练集标签维度{train_df[label].shape})标签默认是下期收益率计算方式是用 close 或 vwap 算未来 N 日收益。这里要注意标签的计算依赖复权价格如果数据准备阶段用了不复权的价格标签会失真。3.3 LightGBM 模型训练与参数配置模型训练通过 workflow 配置串联。Qlib 的 workflow 是一个字典结构包含 model、dataset、record 等部分。下面是一个完整的 LightGBM 训练配置。from qlib.contrib.model.gbdt import LGBModel from qlib.workflow import R # 配置 LightGBM 模型参数 model_config { class: LGBModel, module_path: qlib.contrib.model.gbdt, kwargs: { loss: mse, colsample_bytree: 0.8, learning_rate: 0.05, subsample: 0.8, lambda_l1: 0.1, lambda_l2: 0.1, max_depth: 6, num_leaves: 64, num_threads: 8, verbosity: -1, seed: 42, }, } # 训练模型 model LGBModel(**model_config[kwargs]) model.fit(dataset) # 在测试集上预测 pred_score model.predict(dataset, segmenttest) print(f预测值范围{pred_score.min():.4f} ~ {pred_score.max():.4f})LightGBM 的关键参数里learning_rate 和 num_leaves 对结果影响最大。学习率一般设在 0.03 到 0.1 之间num_leaves 控制在 32 到 128 之间。max_depth 设 6 到 8 层就够了再深容易过拟合。训练时 Qlib 会自动用验证集做早停不需要手动写早停逻辑。训练完成后模型文件会保存在 mlruns 目录下可以通过 Qlib 的 R 模块读取。# 读取训练记录 from qlib.workflow import R recorder R.get_recorder(recorder_idyour_recorder_id) model recorder.load_object(trained_model) print(f模型类型{type(model).__name__})4. 策略回测与绩效分析从预测值到净值曲线的落地4.1 回测参数配置与 TopK 选股策略模型训练完只是第一步真正决定策略表现的是回测环节。Qlib 的回测模块支持 TopK 选股、调仓周期设置、手续费和滑点配置。下面是一个典型的回测配置。from qlib.contrib.strategy import TopkDropoutStrategy from qlib.backtest import backtest, executor from qlib.contrib.evaluate import risk_analysis # 配置 TopK 选股策略 strategy_config { class: TopkDropoutStrategy, module_path: qlib.contrib.strategy, kwargs: { signal: pred_score, # 模型预测值 topk: 50, # 每期选 50 只股票 n_drop: 5, # 每期淘汰 5 只 }, } # 配置回测执行器 executor_config { class: SimulatorExecutor, module_path: qlib.backtest.executor, kwargs: { time_per_step: day, generate_portfolio_metrics: True, }, } # 配置回测参数 backtest_config { start_time: 2020-01-01, end_time: 2020-11-30, account: 10000000, # 初始资金 1000 万 benchmark: hkhsi, # 基准指数 exchange_kwargs: { freq: day, limit_threshold: 0.095, # 涨跌停限制 deal_price: close, # 成交价用收盘价 open_cost: 0.0005, # 买入手续费 close_cost: 0.0015, # 卖出手续费 min_cost: 5, # 最低手续费 }, }TopK 选股的核心逻辑是每期选预测值最高的 K 只股票同时淘汰表现最差的 n_drop 只。topk 和 n_drop 的比值决定了换手率topk50、n_drop5 意味着每期换手约 10%。如果策略容量大、交易成本低可以适当提高 n_drop 来增加换手反之则降低。4.2 回测执行与绩效指标解读配置好之后执行回测。# 执行回测 portfolio_metrics, indicator backtest( executorexecutor_config, strategystrategy_config, **backtest_config, ) # 计算风险指标 report, positions risk_analysis( portfolio_metrics[return] - portfolio_metrics[benchmark_return], freqday, ) print(report)回测输出的核心指标包括年化收益、信息比率、最大回撤和换手率。年化收益看策略的绝对表现信息比率看相对基准的超额收益稳定性最大回撤看策略的风险控制能力换手率看交易成本的影响。这四个指标要结合起来看单看某一个容易误判。比如一个策略年化收益 30% 但最大回撤 40%信息比率只有 0.5那这个策略的实际风险收益比并不好。我一般会要求信息比率在 1.0 以上、最大回撤控制在 20% 以内才认为策略有进一步研究的价值。4.3 IC 分析与因子有效性判断除了净值曲线IC 分析是判断因子和模型有效性的关键工具。IC 是因子值与下期收益的截面相关系数Rank IC 是秩相关系数。IC 均值越高、ICIR 越大说明因子预测能力越强。from qlib.contrib.evaluate import calc_ic # 计算 IC 和 Rank IC ic, ric calc_ic(pred_score, dataset.prepare(test, col_setlabel)) print(fIC 均值{ic.mean():.4f}) print(fRank IC 均值{ric.mean():.4f}) print(fICIR{ic.mean() / ic.std():.4f})IC 均值在 0.03 以上、ICIR 在 0.3 以上通常认为因子有一定预测能力。如果 IC 均值接近 0 或者 ICIR 很低说明模型没有学到有效信号需要检查因子质量、标签定义和训练集划分。5. 避坑与常见问题排查那些官方文档没写的细节5.1 数据准备阶段的三个高频翻车点现象一回测净值曲线异常收益忽高忽低。原因通常是 csv 数据里缺少 factor 或 change 字段。Qlib 在计算标签和回测时依赖复权因子如果 factor 字段缺失价格调整会出错。解决方法是确保 csv 里包含 factor 字段且复权因子与价格数据对应。现象二dump_all 转换报错提示字段不存在。原因通常是 include_fields 参数里逗号后面带了空格。比如写成open, high, low而不是open,high,lowQlib 会把空格当成字段名的一部分。解决方法是检查参数格式确保逗号后没有空格。现象三因子计算结果全为 NaN。原因通常是股票池里的股票在指定时间段内没有数据或者数据日期格式不匹配。解决方法是先用 D.calendar 和 D.list_instruments 检查数据覆盖范围确认股票池和日期范围有交集。5.2 模型训练阶段的过拟合与数据泄露现象训练集 IC 很高但测试集 IC 接近 0。这是典型的过拟合。原因可能是模型太复杂、训练轮数太多或者因子数量远大于样本数量。解决方法是降低模型复杂度比如减小 num_leaves、增大 lambda_l1 和 lambda_l2同时用验证集做早停。现象测试集表现异常好但实盘或样本外表现差。这通常是数据泄露。常见的数据泄露来源有两个一是预处理时用了全量数据做标准化导致测试集信息泄露到训练集二是标签计算时用了未来数据。解决方法是确保预处理只在训练集上 fit然后 transform 到验证集和测试集标签计算严格用未来 N 日收益不能用当日或历史数据。5.3 回测阶段的参数设置陷阱现象回测收益很高但换手率异常低。原因可能是涨跌停限制设置过严导致很多交易无法执行。Qlib 的 limit_threshold 参数控制涨跌停幅度港股没有涨跌停限制这个参数应该设大一些或者不设。解决方法是根据市场规则调整 limit_threshold港股可以设为 0.5 或更高。现象回测结果与预期不符超额收益为负。原因可能是基准指数选择不当。基准应该与策略股票池匹配比如港股策略用恒生指数做基准A 股策略用沪深 300 做基准。解决方法是检查 benchmark 参数是否与股票池匹配。现象回测运行速度极慢。原因可能是数据量太大或者缓存未生效。Qlib 的表达式引擎有缓存机制但第一次计算因子时会比较慢。解决方法是确保数据以 bin 格式存储避免每次从 csv 重新加载同时检查缓存目录是否有写入权限。6. 验收与答辩怎么证明这套方案真的跑通了验收这套方案我一般会按四个层次来检查。第一层是环境验收确认 Qlib 安装成功、数据加载正常、因子计算无报错。第二层是流程验收确认从数据准备到模型训练到回测的完整链路能跑通中间没有手动干预。第三层是结果验收确认回测输出的净值曲线、IC 序列、绩效指标符合预期。第四层是复现验收换一组数据或换一个时间段同样的代码能跑出合理结果。具体到答辩场景评委通常会问三个问题你的因子为什么有效你的模型有没有过拟合你的回测有没有未来函数这三个问题对应三个验收动作。因子有效性用 IC 和分组收益证明过拟合用训练集和测试集的 IC 对比证明未来函数用标签计算逻辑和预处理流程证明。下面这张表是我常用的验收清单可以直接拿去对照检查。验收项检查方法合格标准数据完整性检查 calendar 和 instruments 文件交易日无缺失股票池非空因子计算随机抽 3 个因子检查数值分布无全 NaN无无穷值模型训练对比训练集和验证集 IC验证集 IC 不低于训练集 IC 的 50%回测执行检查净值曲线和换手率净值曲线平滑换手率在合理范围绩效指标计算年化收益、信息比率、最大回撤信息比率 0.5最大回撤 30%代码复现换时间段重新运行流程无报错结果合理答辩时还有一个技巧提前准备一份最小可复现示例。把数据准备、因子生成、模型训练、回测四个环节各保留最核心的几行代码放在一个脚本里。评委让你现场演示时跑这个脚本比跑完整流程快得多而且不容易出错。我一般会把最小示例控制在 50 行以内确保 3 分钟内能跑完。从那以后我每次做量化项目都会在正式开发前先跑通一个最小闭环确认数据、因子、模型、回测四个环节能串起来再往上加复杂度。这个习惯帮我省了很多返工的时间。希望这套方案能帮到你不管是交毕设还是落地项目先把流程跑通再谈优化。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?