面向市场动态的量化模型滚动评测:Qlib 中 RR 滚动重训与 DDG-DA 动态适应的 benchmark 框架解析 面向市场动态的量化模型滚动评测Qlib 中 RR 滚动重训与 DDG-DA 动态适应的 benchmark 框架解析【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib本指南以 examples/benchmarks_dynamic/README.md 为骨架完整讲解 Qlib 为应对金融数据分布漂移concept drift所提供的两类动态建模评测方案——周期性滚动重训基线 RRRolling Retrain与基于 Meta Controller 的数据分布生成适应方法 DDG-DA并结合仓库源码与配置文件给出可直接复现的完整实验流程。读完本文你将掌握在 Alpha158 数据集上搭建训练—滚动—集成—组合评测全流程、通过--conf_path无缝切换 Linear/LightGBM 等预测模型以及读懂 benchmark 结果表背后评测口径的方法。为什么金融市场中的模型会过时非平稳环境与模型性能衰减量化建模面临的一个根本性难题是金融市场的环境是非平稳non-stationary的。市场数据在不同时期的分布会发生变化即所谓概念漂移。因此建立在某段训练数据上的模型其效果会在未来的测试数据上逐渐衰减performance decay。examples/benchmarks_dynamic/目录正是为了量化研究这一问题而存在它评测不同的动态适应方案在不同预测模型上的滚动表现为研究者提供一个公平、可复现的对照实验平台。目录结构如下examples/benchmarks_dynamic/baseline/——周期性滚动重训RRRolling Retrain基线框架提供 rolling_benchmark.py 与两套配置文件examples/benchmarks_dynamic/DDG-DA/——基于 QlibMeta Controller组件实现的 DDG-DAData Distribution Generation for Predictable Concept Drift Adaptation方案提供 workflow.py、Makefile 与可视化脚本 vis_data.py。核心结论在两份子 README 中表述一致通过应用 DDG-DA可以在测试阶段同时看到代理模型proxy modelIC 与最终预测模型性能的上升趋势——说明预测并生成未来分布确实优于被动重训。第一步准备 crowd-sourced 版 Alpha158 数据集本文涉及的实验使用crowd-sourced 版本的 Qlib 数据与 scripts/data_collector/crowd_source/ 目录配套的数据发布版本一致详见 scripts/data_collector/crowd_source/README.md。之所以强调 crowd-sourced 版本是因为它包含VWAP等 Yahoo 版缺失的关键行情字段后文会专门说明这一差异对实验结果的重大影响。数据准备命令如下从该数据源公开的 qlib_bin 发布渠道下载后解压到本地默认数据目录mkdir -p ~/.qlib/qlib_data/cn_data tar -zxvf qlib_bin.tar.gz -C ~/.qlib/qlib_data/cn_data --strip-components2其中--strip-components2用于剥掉压缩包内前两级目录使数据直接落入~/.qlib/qlib_data/cn_data与该目录下所有配置文件中的provider_uri: ~/.qlib/qlib_data/cn_data保持一致。在跑 benchmark 脚本时还有一条快捷的数据获取路径以 examples/benchmarks_dynamic/DDG-DA/workflow.py 为例入口逻辑会检查环境变量kwargs {} if os.environ.get(PROVIDER_URI, ) : GetData().qlib_data(exists_skipTrue) # 自动下载数据 else: kwargs[provider_uri] os.environ[PROVIDER_URI] auto_init(**kwargs)即若未设置PROVIDER_URI则通过qlib.tests.data.GetData自动拉取数据exists_skipTrue表示已存在则跳过若设置了该环境变量则直接以其作为数据目录避免重复下载。基线方案 RR周期性滚动重训Rolling RetrainRRRolling Retrain是评估动态适应方法最基本的对照基线。它的思想非常朴素周期性地利用最新可得的数据重新训练模型从而让模型持续贴合当前市场分布。RR 的完整说明位于 examples/benchmarks_dynamic/baseline/README.md。运行方式python rolling_benchmark.py run默认预测模型为LinearRR 框架通过model_type/conf_path参数切换预测模型例如切换到 LightGBMpython rolling_benchmark.py --conf_pathworkflow_config_lightgbm_Alpha158.yaml run参数化的代码入口examples/benchmarks_dynamic/baseline/rolling_benchmark.py 非常精简本质是 Qlib 内置Rolling滚动框架的一层薄封装class RollingBenchmark(Rolling): CONF_LIST [ DIRNAME / workflow_config_linear_Alpha158.yaml, DIRNAME / workflow_config_lightgbm_Alpha158.yaml, ] DEFAULT_CONF CONF_LIST[0] def __init__(self, conf_pathDEFAULT_CONF, horizon20, **kwargs): super().__init__(conf_pathconf_path, horizonhorizon, **kwargs) for f in self.CONF_LIST: if conf_path.samefile(f): break else: self.logger.warning(Model type is not in the benchmark!)这里CONF_LIST限制了可选模型集合若传入不属于 benchmark 的配置会发出告警horizon20与目录 README 中标签预测周期为 20 个交易日的实验口径一一对应。滚动运行机制源码级RR 的核心逻辑完全复用 Qlib 的滚动模块 qlib/contrib/rolling/base.py 中的Rolling类其设计目标在类注释中写得很清楚离线地把一个具体任务转化为时间序列上的多个滚动子任务并逐一运行与在线服务的OnlineStrategy、元学习的MetaController分工不同滚动只负责把一段任务按时间切片def run(self): self._train_rolling_tasks() # 1) 每个滚动子任务作为一个 record 存入 rolling_models self._ens_rolling() # 2) 拼接所有滚动预测结果存入最终 experiment self._update_rolling_rec() # 3) 对拼接后的结果执行评测 record其关键环节与所依赖的 Qlib 组件生成滚动任务列表get_task_list()调用task_generator(task, RollingGen(stepself.step, trunc_daysself.horizon 1))。step20表示滚动时间间隔为 20 个交易日与 README 实验设置一致trunc_days21即horizon1目的是截断最后几天防止标签信息泄露代码注释原文the last two days should be truncated to avoid information leakage。生成出的每个子任务在滚动阶段不再做独立分析record仅保留SignalRecord分析统一推迟到最终集成环节。相关生成器实现见 qlib/workflow/task/gen.py。训练滚动任务TrainerR(experiment_nameself.rolling_exp)批量训练实验名未显式指定时自动生成rolling_models_时间戳。集成拼接预测RecorderCollector从滚动实验各 record 中抽取pred与label两个 artifact经 qlib/model/ens/ensemble.py 的RollingEnsemble拼接再以R.save_objects(**{pred.pkl: ..., label.pkl: ...})存入最终 experiment。组合评测_update_rolling_rec()从原始配置读取record列表跳过SignalRecord预测已在集成阶段产生对其余分析类 record如SigAnaRecord、PortAnaRecord逐一generate()最终将评测结果写入名为exp_name的实验。此外Rolling支持通过命令行直接驱动方便在不写代码的情况下复用任意 YAMLpython -m qlib.contrib.rolling.base --conf_path 配置文件路径 run在运行前建议清理历史 mlflow 结果mlruns目录。原因在源码注释中有说明mlflow 无法彻底删除 experiment删除只会移入.trash重名会抛错。目录下的 Makefile 提供了现成的清理目标make clean等价于删除*.pkl与mlruns。基线配置文件解读线性与 LightGBM 两套配置分别对应 workflow_config_linear_Alpha158.yaml 与 workflow_config_lightgbm_Alpha158.yaml二者共享相同的评测口径。以线性版为例关键配置项如下配置块关键参数含义 / 取值qlib_initprovider_uri/region数据目录~/.qlib/qlib_data/cn_data市场区域cnmarket/benchmarkcsi300/SH000300股票池为沪深 300基准指数为沪深 300data_handler_configstart_time/end_time数据起止2008-01-01 ~ 2020-08-01fit_start_time/fit_end_time因子标准化等拟合窗口2008-01-01 ~ 2014-12-31infer_processorsRobustZScoreNormFillna推理阶段对特征组做稳健 Z-Score 归一clip_outlier: true并填充缺失learn_processorsDropnaLabelCSRankNorm训练阶段删除空标签、对标签做横截面排名归一modelLinearModelridgealpha: 0.05预测模型LightGBM 版为LGBModel超参colsample_bytree0.8879、learning_rate0.2、num_leaves210、max_depth8等datasetDatasetHAlpha158handler特征数据集segments将样本划分为 train[2008-01-01, 2014-12-31]、valid、test[2017-01-01, 2020-08-01]recordSignalRecord/SigAnaRecord/PortAnaRecord记录信号、信号分析ana_long_short、组合分析port_analysis_configTopkDropoutStrategy组合策略取信号 top50、每次换仓剔除 5 只topk: 50, n_drop: 5backtest账户 1 亿、涨跌停限幅0.095、交易成本回测窗口2017-01-01 ~ 2020-08-01open_cost: 0.0005、close_cost: 0.0015、min_cost: 5需要特别注意的一点是滚动重训时训练/测试分段并非直接使用 YAML 中写死的segments。Rolling.basic_task()qlib/contrib/rolling/base.py会动态改写 handler 的标签表达式task[dataset][kwargs][handler][kwargs][label] [ Ref($close, -{}) / Ref($close, -1) - 1.format(self.horizon 1) ]即标签被统一改写为未来horizon1天相对下一天的收盘收益率Ref($close, -21) / Ref($close, -1) - 1对应 label horizon20。这样Rolling只依赖horizon/step/segments三个时间参数即可完成任意窗口的切片这也是两个子 README 均以horizon20为默认入口参数的原因源码注释指出该改写方式仅对Alpha158/Alpha360这类内置数据集有效。DDG-DA预测数据分布并生成训练样本的动态适应方法方法背景与核心思想examples/benchmarks_dynamic/DDG-DA/README.md 给出了 DDG-DA 的设计动机在许多真实场景中流式数据如金融行情随时间顺序到达且由于环境非平稳数据分布可能以不可预测的方式变化即概念漂移。以往方法通常先检测漂移发生的时间与位置再让模型适配最新数据分布。但现实中很多环境演化背后的底层因素是可预测的这就使得建模未来概念漂移趋势成为可能而此前的工作对此探索不足。因此 DDG-DA 提出了一条三步流水线先训练一个**预测器predictor**估计未来的数据分布利用该预测生成generate训练样本在生成的数据上训练最终预测模型。值得注意的是论文原文使用的是私有数据本仓库改用 Qlib 公开数据集进行实验即上文的 Alpha158 crowd-sourced 数据。README 明确指出虽然数据集不同但结论保持一致——应用 DDG-DA 后测试阶段代理模型的 IC 与预测模型的性能都呈现上升趋势。运行方式与模型切换在 examples/benchmarks_dynamic/DDG-DA/ 目录下执行python workflow.py run默认预测模型为Linear切换预测模型时通过--conf_path指定其他 YAML注意路径是相对 DDG-DA 目录指向基线配置目录的上一级配置python workflow.py --conf_path../workflow_config_lightgbm_Alpha158.yaml runexamples/benchmarks_dynamic/DDG-DA/workflow.py 同样是薄封装其DDGDABench直接继承 Qlib 的DDGDA类将工作目录固定为自身所在目录并用--conf_path校验模型是否属于可选的 benchmark 集合。源码级实现DDGDA 如何工作DDG-DA 的滚动实现在 qlib/contrib/rolling/ddgda.py 中类DDGDA继承自前文Rolling因此天然复用整套滚动切片—训练—集成—评测机制但把run()的前半段替换为三步元模型准备阶段源代码 qlib/contrib/rolling/ddgda.pydef run(self): # 准备 meta model self._dump_data_for_proxy_model() # 1) - handler_proxy.pkl代理模型数据集 self._dump_meta_ipt() # 2) - internal_data_s20.pklmeta 模型输入 self._train_meta_model() # 3) meta model 存入 experiment DDG-DA # 滚动重训 super().run() # 4) 生成 tasks_s20.pkl 并滚动训练、集成、评测第 1 步为代理模型准备数据_dump_data_for_proxy_model。先用内置 LightGBM 配置训练一个特征重要性模型存入 experimentfeature_importance见 qlib/contrib/rolling/ddgda.py取出fea_imp_n默认 30个最重要的特征若meta_data_procV01再按(x - mean) / std做逐截面标准化并fillna(0)。处理后的特征标签数据被存为fea_label_df.pkl并包装成DataHandlerLP后落盘为handler_proxy.pkl。代理模型采用简化线性代理用于快速评估各滚动期的数据分布变化。第 2 步生成 meta 模型输入_dump_meta_ipt。调用InternalData(sim_task, step, ...)来自 qlib/contrib/meta/data_selection/dataset.py把滚动任务组织成内部数据产出internal_data_s20.pkl相似度模型按sim_task_model参数取linear或gbdt默认gbdt训练在 experimentdata_sim_s20中用于刻画各时段数据分布的相似度。GBDT 版会显式关闭早停并固定num_boost_round150以保证可复现。第 3 步训练 meta 模型_train_meta_model。meta 模型的训练窗口默认取2008-01-01 ~ 2010-12-31可通过meta_1st_train_end覆盖测试起点自动取训练结束次日从而确保后续正式滚动任务不会泄漏进训练数据。核心训练对象是 qlib/contrib/meta/data_selection/model.py 的MetaModelDS关键超参在 qlib/contrib/rolling/ddgda.py 中写死lr0.001、max_epoch30、seed43、alpha0.01该alpha作为 L2 正则只传给MetaModelDS的 ridge 层、loss_skip_thresh50单日样本量低于该阈值时跳过该日损失计算数据集划分比例segments0.62float 语义为训练数据占比 62%历史窗口hist_step_n30。训练好的 meta 模型存入 experimentDDG-DA。第 4 步元推理生成新任务并滚动。get_task_list()从DDG-DA实验加载 meta 模型读取训练时记录的trunc_days/step/hist_step_n/fill_method等配置保证推理口径与训练一致用segments0.0全部作为测试与task_modeMetaTask.PROC_MODE_TRANSFER构建MetaDatasetDSPROC_MODE_TRANSFER定义于 qlib/model/meta/task.py由 meta 模型对每个滚动期输出数据重加权方案reweighter生成带权重的滚动任务集合并存为tasks_s20.pkl最后交给父类Rolling.run()完成滚动训练与组合评测。一句话概括DDG-DA 在训练预测模型之前先学习各历史时段之间数据分布相似度 → 应如何为未来时段加权/生成样本的元知识从而把可预测的分布演化显式编码进滚动训练流程。DDGDA 主要初始化参数速查结合 qlib/contrib/rolling/ddgda.py 的类定义常用参数及语义如下其中未列出的conf_path/horizon/step等继承自Rolling参数默认值作用sim_task_modelgbdt计算数据相似度的模型类型可选linear/gbdt源码注释强调模型类型的选择对结果好坏非常关键alpha0.01ridge 的 L2 正则仅传给MetaModelDSloss_skip_thresh50单日样本数小于该阈值时跳过当日损失计算fea_imp_n30按特征重要性选取的特征个数置None则使用全部特征meta_data_procV01meta 数据集的截面标准化处理方式segments0.62float 表示 meta 任务中训练数据占比字符串则尽力将该日期划入测试集hist_step_n30meta 输入的历史滚动窗口期数meta_1st_train_endNone首个 meta 任务的训练截止日期默认2010-12-31working_dir配置文件所在目录中间产物handler_proxy.pkl、internal_data_s20.pkl、tasks_s20.pkl等的输出目录实验结果与结论DDG-DA 对两类预测模型的提升主 README 在 Alpha158 数据集上给出了 RR 与 DDG-DA 分别搭配 Linear、LightGBM 两种预测模型的完整对照结果本仓库公布的事实数据Model NameDatasetICICIRRank ICRank ICIRAnnualized ReturnInformation RatioMax DrawdownRR[Linear]Alpha1580.09450.59890.10690.64950.08571.3682-0.0986DDG-DA[Linear]Alpha1580.09830.61570.11080.66460.07641.1904-0.0769RR[LightGBM]Alpha1580.08160.58870.09120.62630.07711.3196-0.0909DDG-DA[LightGBM]Alpha1580.08780.61850.09750.65240.12612.0096-0.0744可以观察到的规律仅就表内数据而言IC 类指标全面占优无论 Linear 还是 LightGBMDDG-DA 的 IC、ICIR、Rank IC、Rank ICIR 均高于 RR说明动态生成/加权后的样本确实带来了更强的预测与排序能力收益—回撤改善不同LightGBM 搭配 DDG-DA 时年化收益0.1261 vs 0.0771、信息比率2.0096 vs 1.3196提升显著且最大回撤收窄-0.0744 vs -0.0909Linear 搭配 DDG-DA 时年化收益与信息比率略低于 RR但最大回撤同样更小-0.0769 vs -0.0986。两类模型一致地表现为回撤控制更好。实验口径务必复现时对齐主 README 明确列出了如下实验设置任何复现实验都应保持这些口径一致否则结果不可比Alpha158 数据集的标签预测周期label horizon设为 20滚动时间间隔为 20 个交易日对应Rolling.step20、RollingGen的步长测试滚动期覆盖 2017 年 1 月至 2020 年 8 月对应配置文件中backtest与test段的[2017-01-01, 2020-08-01]训练拟合窗口为2008-01-01 ~ 2014-12-31见配置文件fit_start_time/fit_end_time与train分段。关于数据版本的重要警告为什么必须用 crowd-sourced 数据主 README 末尾专门强调了一个容易踩坑的点结果基于 crowd-sourced 版本数据而 Yahoo 版本的 Qlib 数据不包含VWAP。由于 Alpha158 中所有涉及VWAP的因子在 Yahoo 版数据下全部缺失并被填充为 0会导致特征矩阵秩亏rank-deficient即矩阵不满秩进而使 DDG-DA 中的底层优化lower-level optimization无法求解。这也解释了为何整个目录的所有配置都把provider_uri指向 crowd-sourced 版数据目录而自动下载逻辑GetData().qlib_data也只是为了方便首次实验。深度诊断用 vis_data.py 观察 DDG-DA 内部状态除端到端跑实验外examples/benchmarks_dynamic/DDG-DA/vis_data.py 提供了对 DDG-DA 中间产物的可视化分析脚本近似 notebook 工作流可帮助研究者理解其内部机制Meta 输入分析读取internal_data_s20.pkl用 seaborn 热力图展示各滚动期相似度矩阵data.data_ic_df并叠加rolling(20).mean()观察其趋势平滑形态Meta 模型分析从 experimentDDG-DA加载 meta 模型权重meta_m.tn.twm.linear.weight绘制权重随时间的取值曲线及其 5 期移动平均观察元模型学到的时段→加权模式Meta 输出任务重写分析读取tasks_s20.pkl逐任务提取dataset.kwargs.segments.test并对比重写前后差异验证 meta 推理是否按预期为各滚动期分配了不同数据权重。该脚本的使用前提是先用python workflow.py run跑通全流程、生成上述*.pkl中间文件与 mlflow 实验记录。运行环境与注意事项硬件门槛按 DDG-DA 子 README 给出的最低配置要求运行 examples/benchmarks_dynamic/DDG-DA/workflow.py 需要约45G 内存与 4G 磁盘DDG-DA 的默认实验只需CPU 内存即可完成不强制 GPU。依赖版本examples/benchmarks_dynamic/DDG-DA/requirements.txt 中固定了torch1.10.0meta 模型的训练基于 PyTorch安装新版本可能出现接口不兼容建议按该文件锁定版本。实验清理由于 mlflow 无法彻底删除同名 experiment删除只进.trash重复运行前应清理mlruns目录与中间 pkl 文件可执行make clean定义于 examples/benchmarks_dynamic/DDG-DA/Makefile或直接按 qlib/contrib/rolling/base.py 中的说明手动执行rm -r mlruns。中间产物归属一次完整 DDG-DA 运行会在工作目录生成handler_proxy.pkl、fea_label_df.pkl、internal_data_s20.pkl、tasks_s20.pkl等文件并在 mlflow 的mlruns中留下feature_importance、data_sim_s20、DDG-DA、滚动模型实验与最终组合实验等多组记录可用于逐步检查各环节是否正确。小结examples/benchmarks_dynamic/为量化研究者在 Qlib 生态中对比被动滚动重训 vs. 主动分布适应提供了开箱即用的完整闭环底层是 qlib/contrib/rolling/base.py 中可复用的Rolling滚动—集成—评测流水线上层是RRbaseline/rolling_benchmark.py与DDG-DAqlib/contrib/rolling/ddgda.py两种策略化封装两者共享同一套 Alpha158 配置文件与评测口径。如果你正面临模型上线后随市场漂移快速失效的问题可以基于本目录的 YAML 修改market、时间窗口、预测模型或DDGDA的sim_task_model/segments/fea_imp_n等超参把实验扩展到自己的股票池与数据上并在复现时务必使用包含VWAP字段的 crowd-sourced 数据集。【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

最新新闻

Ceph离线部署流程

Ceph离线部署流程

文章目录第一步:导出镜像和 cephadm第二步:准备系统依赖 RPM(离线机器没装 podman 就需要)第三步:离线环境重建集群三个容易踩的坑完全可以,而且这正是 cephadm 部署的标准离线姿势。你的集群所有容器都来自…

2026/9/9 13:36:51
需求管理决定项目成败:从需求分析到测试验收的完整指南

需求管理决定项目成败:从需求分析到测试验收的完整指南

1. 需求到底是什么:先搞清楚我们在解决谁的问题干了这么多年软件开发,我越来越觉得一个项目能不能成,技术选型反而是其次,最要命的往往是需求。需求这词儿听起来谁都知道,但真到落地的时候,百分之八十的麻烦…

2026/9/9 13:36:51
Claude Code开发避坑指南:从ruflo误触到Agent生产落地

Claude Code开发避坑指南:从ruflo误触到Agent生产落地

1. “ruflo”不是工具名,而是当前AI开发圈一个典型认知错位的缩影最近在多个技术社区和私聊群里,频繁看到有人问:“ruflo怎么安装?”“ruflo官网在哪?”“ruflo和Claude Code冲突吗?”——甚至有开发者在Gi…

2026/9/9 13:36:51
墨衍 SEO检测实测:60 秒出报告,30+ 字段逐项说明

墨衍 SEO检测实测:60 秒出报告,30+ 字段逐项说明

标签:SEO检测 SEO检测工具 墨衍 实测 「SEO检测工具 快不快、报告有没有用?」——本文用 墨衍 SEO检测 做一次 实测向说明,帮你在百度搜 SEO检测 时快速判断要不要试。 实测环境 入口:https://mp.csdn.net/seo对象:已…

2026/9/9 13:36:51
STM32F103输入捕获测量PWM占空比与周期详解

STM32F103输入捕获测量PWM占空比与周期详解

简介:STM32F103输入捕获工程资源,面向需要测量外部PWM信号周期与占空比的嵌入式开发者与学习者,提供一套基于Keil5的完整工程示例。资源围绕定时器输入捕获原理展开,从定时器初始化、输入捕获通道配置到中断服务程序编写&#xff…

2026/9/9 13:36:51
GPT-6双版本深度解析:Sol快6倍背后的工程优化与Agent新范式

GPT-6双版本深度解析:Sol快6倍背后的工程优化与Agent新范式

GPT-6的发布消息在圈子里炸开之后,我第一时间把Astra和Sol两个版本的公开信息、内测反馈翻了个底朝天。这一代最让人意外的不是Astra的能力上限又拉高了多少,而是Sol这个轻量版爆出来的内测数据——速度快6倍,这个数字放在大模型迭代历史上&a…

2026/9/9 13:31:50