Qlib QlibRL 使用指南:面向不同背景开发者的强化学习量化策略上手路径
本文基于 Qlib 官方文档中的 QlibRL Guidance 指南编写,面向三类读者(RL 新手、RL 算法研究者、量化研究员)给出各自定制化的 QlibRL 学习路径,并结合 examples/rl_order_execution/ 中单资产订单执行(SAOE)示例的配置文件与 qlib/rl/order_execution/ 下的 MDP 组件源码,帮助你在读完之后掌握"按自身背景选路径 → 跑通训练与回测 → 自定义 State/Action/Reward 等组件"的完整实操能力。
QlibRL 是什么,为哪类人解决什么问题
QlibRL 是 Qlib 中的强化学习(Reinforcement Learning, RL)工具包,用于帮助用户快速上手、便捷地实现基于 RL 算法的量化策略。与"一锅端"的教程不同,官方指南(docs/component/rl/guidance.rst)的核心思路是:按读者的知识背景给出差异化路径。不同读者在"RL 算法知识"与"金融领域知识"两个维度上的储备不同,需要补齐的东西也不同:
| 读者类型 | 已具备 | 需要补齐 | 指南推荐路径 |
|---|---|---|---|
| 强化学习算法新手 | 基本编程/量化常识 | RL 基础、RL 适用场景、QlibRL 框架 | 基础 → 场景 → 示例 → 框架与定制 |
| RL 算法研究者 | RL 算法知识 | 金融交易领域知识 | 场景 → 跑通示例 → 改写 policy 注入自己的算法 |
| 量化研究员 | 金融领域知识、编码能力 | RL 算法、MDP 建模方法 | 基础 → 场景 → 示例 → 框架 → 选算法 → 设计 MDP |
下面按"路径中的每一步"展开:先讲 RL 基础与适用场景(对应 part1/part2),再讲如何跑通官方示例(对应 part3),最后讲框架结构与组件级定制(对应 part4)。
Part 1:RL 基础——四个要素与"试错学习"
这一部分继承自指南的 part1(docs/component/rl/overall.rst)。与分类、回归等监督学习任务不同,RL 是机器学习的另一大范式:智能体(agent)通过与环境的直接交互来优化累积的数值奖励信号,并通常在马尔可夫决策过程(MDP)等假设下建模问题。
一个 RL 系统由四个要素构成:
- Agent(智能体):决策主体;
- Environment(环境):智能体交互的对象;
- Policy(策略):智能体据以对环境影响采取动作的规则;
- Reward(奖励信号):环境反馈给智能体的标量信号。
整体上,智能体感知并解释环境、执行动作、并通过奖励学习,以求长期总奖励最大化为目标。与监督学习从标签学习不同,RL 通过"试错"采样动作,观察哪些动作带来期望结果,从而得到能产生最优动作的策略——奖励是一个延迟标签,告诉我们当前结果是好是坏。一句话概括:RL 的目标就是采取行动使奖励最大化。
Part 2:RL 在量化交易中的潜在应用场景
这一部分继承自指南的 part2(docs/component/rl/overall.rst)。投资本质上是一个持续决策过程:投资者通过买卖行为管理持仓与持股,并在每次决策前评估市场状态与个股信息——这正是"与交互环境驱动的连续决策",也是 RL 的优势场景。文档归纳了两类典型场景:
订单执行(Order Execution)
订单执行任务要求在执行订单时综合考虑:最优价格、最小化交易成本、降低市场冲击、最大化订单完成率(fill rate)、在指定时间窗口内完成执行。RL 的做法是把这些目标全部编码进奖励函数与动作选择过程:智能体与市场环境交互、从市场信息中观察状态、决定下一步执行量,通过试错学习最优执行策略以最大化期望累积奖励。其一般化 MDP 设定为:
- Environment(环境):订单执行发生的金融市场,包含订单簿动态、流动性、价格波动与市场状态等变量;
- State(状态):某时刻智能体可用的信息,通常包括订单簿状态(买卖价差、订单深度)、历史价格、历史成交量、市场波动率等;
- Action(动作):基于观察状态做出的决策,包括选择下单量、价格与执行时机;
- Reward(奖励):指示动作效果的标量信号,通常同时考虑最大化价格优势、最小化交易成本(手续费与滑点)、降低市场冲击、提高完成率等多个目标。
具体场景又分两种:
- 单资产订单执行(Single-asset order execution):针对某一特定资产(股票或加密货币)执行单笔订单,目标是在价格优势、成本、冲击与完成率之间取得最优;
- 多资产订单执行(Multi-asset order execution):同时对组合中多个资产执行订单,除了单笔订单效率,还要管理资产间相互作用与依赖,以及现金约束、市场条件与交易成本,目标是在单资产效率与组合整体目标之间取得平衡。
组合构建(Portfolio Construction)
组合构建是选取与配置资产的过程。RL 提供"与市场交互、在考虑风险管理的前提下最大化长期收益"的决策优化框架,一般设定为:
- State:市场与组合的当前信息,如历史价格与成交量、技术指标等;
- Action:向不同资产分配资本量的决策,即各资产的权重或比例;
- Reward:评估组合表现的指标,可以定义为总收益、风险调整后收益,或最大化夏普比率、最小化回撤等目标。
按市场可细分为股票市场、加密货币市场、外汇市场等。文档同时提醒:基础设定与算法的选择取决于具体任务需求、可用数据与期望的性能目标。
Part 3:跑通官方示例——单资产订单执行(SAOE)
指南中三类读者都要经过的一步:运行示例(part3,docs/component/rl/quickstart.rst),用 RL 解决一个真实交易问题。当前 QlibRL 实现了两个场景示例:订单执行与算法交易,其中单资产订单执行示例最完整,配套代码与配置位于 examples/rl_order_execution/。
数据准备
根据 examples/rl_order_execution/README.md,先下载 5 分钟级数据,再将其处理为 pickle 格式并生成训练订单:
python -m qlib.cli.data qlib_data --target_dir ./data/bin --region hs300 --interval 5min
python scripts/gen_pickle_data.py -c scripts/pickle_data_config.yml
python scripts/gen_training_orders.py
python scripts/merge_orders.py
完成后 data/ 下应有 bin、orders、pickle 三个目录,分别对应训练配置中 data_dir、order_dir、feature_root_dir 引用的路径。
训练配置详解
下面是 quickstart 文档给出的训练配置文件(对应仓库中的 exp_configs/train_ppo.yml 等实际配置),每个键位直接映射到一个 MDP 组件:
simulator:
# Each step contains 30mins
time_per_step: 30
# Upper bound of volume, should be null or a float between 0 and 1, if it is a float,
# represent upper bound is calculated by the percentage of the market volume
vol_limit: null
env:
# Concurrent environment workers.
concurrency: 1
# dummy or subproc or shmem.
parallel_mode: dummy
action_interpreter:
class: CategoricalActionInterpreter
kwargs:
# Candidate actions: a list [a_1..a_L] or an integer n, in which case
# [0, 1/n, 2/n, ..., n/n] is auto-generated.
values: 14
# Total number of steps (an upper-bound estimation)
max_step: 8
module_path: qlib.rl.order_execution.interpreter
state_interpreter:
class: FullHistoryStateInterpreter
kwargs:
data_dim: 6 # Number of dimensions in data.
data_ticks: 240 # Equal to the total number of records (SAOE per minute: day length in minutes).
max_step: 8 # 390min / 30min-per-step ≈ 13 steps(此处按订单窗口取 8 的上界估计)
processed_data_provider:
class: PickleProcessedDataProvider
module_path: qlib.rl.data.pickle_styled
kwargs:
data_dir: ./data/pickle_dataframe/feature
module_path: qlib.rl.order_execution.interpreter
reward:
class: PAPenaltyReward
kwargs:
penalty: 100.0 # The penalty for a large volume in a short time.
module_path: qlib.rl.order_execution.reward
data:
source:
order_dir: ./data/training_order_split
data_dir: ./data/pickle_dataframe/backtest
total_time: 240 # number of time indexes
default_start_time: 0 # start time index
default_end_time: 240 # end time index
proc_data_dim: 6
num_workers: 0
queue_size: 20
network:
class: Recurrent
module_path: qlib.rl.order_execution.network
policy:
class: PPO
kwargs:
lr: 0.0001
module_path: qlib.rl.order_execution.policy
runtime:
seed: 42
use_cuda: false
trainer:
max_epoch: 2
repeat_per_collect: 5 # Number of episodes collected in each training iteration
earlystop_patience: 2
episode_per_collect: 20 # Episodes per collect at training.
batch_size: 16
val_every_n_epoch: 1 # Perform validation every n iterations
checkpoint_path: ./checkpoints
checkpoint_every_n_iters: 1
配置中的几个关键取舍,可以从源码得到解释:
time_per_step: 30+data_ticks: 240:每步覆盖 30 分钟、一天共 240 个一分钟 tick,max_step是对总步数的上界估计(390 分钟交易时段 / 30 分钟每步);values: 14:动作离散化为 15 个候选比例[0, 1/14, ..., 1],由CategoricalActionInterpreter自动生成(见下节源码解析);class: PPO/class: DQN:QlibRL 当前基于 tianshou 支持 PPO 与 DQN 两类策略(指南原文如此),对应 qlib/rl/order_execution/policy.py 中的PPO与DQN封装类。
启动训练
python -m qlib.rl.contrib.train_onpolicy --config_path exp_configs/train_ppo.yml
示例同时提供了两篇论文的复现任务:PPO(IJCAI 2020 "An End-to-End Optimal Trade Execution Framework based on Proximal Policy Optimization")与 OPDS(AAAI 2021 "Universal Trading for Order Execution with Oracle Policy Distillation"),二者的主要差别在于奖励函数,可分别查看 exp_configs/train_ppo.yml 与 exp_configs/train_opds.yml。训练指标、日志与 checkpoint 会输出到配置指定的 outputs/ 目录。
回测配置与命令
训练完成后可用训练好的策略做回测,quickstart 给出的回测配置结构如下(真实配置见 exp_configs/backtest_ppo.yml):
order_file: ./data/backtest_orders.csv
start_time: "9:45"
end_time: "14:44"
qlib:
provider_uri_1min: ./data/bin
feature_root_dir: ./data/pickle
# feature generated by today's information
feature_columns_today: ["$open", "$high", "$low", "$close", "$vwap", "$volume"]
# feature generated by yesterday's information
feature_columns_yesterday: ["$open_v1", "$high_v1", "$low_v1", "$close_v1", "$vwap_v1", "$volume_v1"]
exchange:
# the expression for buying and selling stock limitation
limit_threshold: ['$close == 0', '$close == 0']
# deal price for buying and selling
deal_price: ["If($close == 0, $vwap, $close)", "If($close == 0, $vwap, $close)"]
volume_threshold:
# volume limits are both buying and selling, "cum" means cumulative value over time
all: ["cum", "0.2 * DayCumsum($volume, '9:45', '14:44')"]
buy: ["current", "$close"]
sell: ["current", "$close"]
strategies:
30min:
class: TWAPStrategy
module_path: qlib.contrib.strategy.rule_strategy
kwargs: {}
1day:
class: SAOEIntStrategy
module_path: qlib.rl.order_execution.strategy
kwargs:
state_interpreter:
class: FullHistoryStateInterpreter
module_path: qlib.rl.order_execution.interpreter
kwargs:
max_step: 8
data_ticks: 240
data_dim: 6
processed_data_provider:
class: PickleProcessedDataProvider
module_path: qlib.rl.data.pickle_styled
kwargs:
data_dir: ./data/pickle_dataframe/feature
action_interpreter:
class: CategoricalActionInterpreter
module_path: qlib.rl.order_execution.interpreter
kwargs:
values: 14
max_step: 8
network:
class: Recurrent
module_path: qlib.rl.order_execution.network
kwargs: {}
policy:
class: PPO
module_path: qlib.rl.order_execution.policy
kwargs:
lr: 1.0e-4
# Local path to the latest model. The model is generated during training,
# so please run training first if you want to run backtest with a trained
# policy. You could also remove this parameter file to run backtest
# with a randomly initialized policy.
weight_file: ./checkpoints/latest.pth
# Concurrent environment workers.
concurrency: 5
回测命令:
python -m qlib.rl.contrib.backtest --config_path exp_configs/backtest_ppo.yml
一个值得注意的实现细节(来自 examples/rl_order_execution/README.md):训练与回测使用不同的模拟器。训练阶段为了效率使用简化版 SingleAssetOrderExecutionSimple(不限制交易数量,订单总能完全成交),回测阶段则使用更贴近现实的 SingleAssetOrderExecution(考虑成交量必须是最小交易单位整数倍等真实约束),因此回测结果与训练期测试阶段结果可能存在偏差。若想让回测与训练期测试完全一致,可用 python -m qlib.rl.contrib.train_onpolicy --config_path PATH/TO/CONFIG --run_backtest --no_training 仅运行回测段,并在配置的 policy.kwargs 中加上 weight_file: PATH/TO/CHECKPOINT。
Part 4:理解 QlibRL 框架,并改写组件做定制
指南的最后一步(part4,docs/component/rl/framework.rst)面向想要做定制的用户:先理解框架,再按需重写具体组件。
框架总览:EnvWrapper 与四个可插拔组件
QlibRL 提供了覆盖 RL 全生命周期的组件集合:构建市场模拟器、构造状态与动作、训练策略、在模拟环境中回测。它在 Tianshou 与 Gym 之上实现,核心抽象是 EnvWrapper——对模拟环境的完整封装:它接收外部(policy/strategy/agent)的动作、模拟市场变化、返回奖励与更新后的状态,形成交互闭环。EnvWrapper 是 gym.Env 的子类,实现其全部接口,因此任何接受 gym.Env 的类或流水线也能接受 EnvWrapper。
开发者不需要自己实现 EnvWrapper,只需实现它的 4 个组成部分:
- Simulator(模拟器):环境模拟的核心组件,所有与环境模拟直接相关的逻辑都可放入其中。QlibRL 针对单资产交易提供了两个实现:
SingleAssetOrderExecution基于 Qlib 回测工具链,考虑了大量真实交易细节但较慢;SimpleSingleAssetOrderExecution基于简化交易模拟器,忽略细节(如交易限制、取整)但速度快。对应源码分别为 qlib/rl/order_execution/simulator_qlib.py 与 qlib/rl/order_execution/simulator_simple.py; - State interpreter(状态解释器):把模拟器原始格式的状态"翻译"成策略可理解的格式,例如把非结构化原始特征转换为数值张量;
- Action interpreter(动作解释器):方向相反,把策略输出的动作从策略格式转换为模拟器可接受的格式;
- Reward function(奖励函数):策略每执行一次动作后返回一个数值奖励。
EnvWrapper 会把这四部分"有机关联"起来。这种解耦带来的灵活性是:同一个环境(一个模拟器)可以搭配不同的状态解释器/动作解释器/奖励函数,训练多种类型的策略。所有组件都有定义良好的基类,定制方式就是继承基类并实现其要求的接口,基类 API 见 qlib/rl/interpreter.py(StateInterpreter、ActionInterpreter)与 qlib/rl/reward.py(Reward)。
指南点名的 MDP 模块逐一解析
指南针对"量化研究员设计 MDP"这一步,给出了订单执行示例中需要对照修改的 7 个模块及其源码位置。下面结合源码逐一说明它们在 MDP 建模中承担的角色:
1. State(状态)—— SAOEState
SAOEState 是一个 NamedTuple,是模拟器输出的原始状态结构,包含:当前订单 order、当前时间 cur_time、当前步数 cur_step、剩余待执行量 position、历史成交明细 history_exec、历史各步统计 history_steps、结算后才有的日度指标 metrics、回测数据 backtest_data,以及 ticks_per_step、ticks_index、ticks_for_order 等时间刻度信息。注意源码注释特别强调:解释器使用这些数据时要小心理解未来数据泄漏——FullHistoryStateInterpreter 正是通过 _mask_future_info 把当前时刻之后的数据置零来保证这一点。
2. Metrics(指标)—— SAOEMetrics
SAOEMetrics 定义了按"period"(一天、30 分钟窗口或逐分钟)累积的交易指标:市场侧的 market_volume/market_price,策略侧的 amount/inner_amount/deal_amount/trade_price/trade_value/position,以及累积指标 ffr(订单完成度)与 pa(相对于 TWAP 基线的价格优势,单位为 BP)。这里的 pa 就是训练日志中 reward/pa 的来源,也是示例中挑选 checkpoint 的评价指标。
3. ActionInterpreter(动作解释器)—— CategoricalActionInterpreter
把策略的离散动作转换为连续交易量:values 若为整数 n,则自动生成 [0, 1/n, 2/n, ..., 1] 共 n+1 个候选比例;解释时输出 min(position, order.amount * action_values[action]),即"本步最多交易剩余仓位,且不超过订单量的候选比例"。若已到 max_step 的最后一步,则直接返回全部剩余仓位 position,强制收尾。此外还有 TwapRelativeActionInterpreter,把连续动作解释为相对"剩余时段 TWAP 量"的倍数,适合想让策略学习"偏离 TWAP 多少"的场景。
4. StateInterpreter(状态解释器)—— FullHistoryStateInterpreter
把 SAOEState 翻译成策略可消费的观测字典,输出包含:截至当前的当日处理数据 data_processed(未来信息被 mask)、昨日数据 data_processed_prev、方向 acquiring、当前 tick/step、总步数 num_step、目标量 target、剩余仓位 position 与仓位历史 position_history。其 observation_space 属性声明了对应的 Gym 空间(如 data_processed 为 (data_ticks, data_dim) 的 Box),供 tianshou 策略自动构建网络。若策略只依赖最新状态,可改用更轻量的 CurrentStepStateInterpreter。
5. Reward(奖励)—— PAPenaltyReward
奖励公式为每步 PA_t * vol_t / target - vol_t^2 * penalty:鼓励更高的价格优势,同时对"在极短时间内堆量"施加二次惩罚(penalty 默认 100.0,还有 scale 系数整体缩放奖励)。同文件还提供 PPOReward——按 IJCAI 2020 PPO 论文设计,在订单完成或到达最后一步时,用实际 VWAP 与 TWAP 基线价格的比值给出 -1/0/+1 的离散奖励。这也解释了示例中 PPO 与 OPDS 两个训练任务"主要差别在奖励函数"的说法:OPDS 配置使用 OPDS 相关奖励,PPO 配置使用 PPOReward。
6. Observation(观测)—— FullHistoryObs
观测是状态解释器输出的最终数据契约(TypedDict),规定了策略输入必须包含的 8 个键。定制新状态解释器时,可以参照它定义自己的观测结构(键名、张量形状与 observation_space 保持一致即可),再配合 network.py 中的 Recurrent(默认输出维度 32)或 Attention 等网络构建策略输入通路。
7. Simulator(模拟器)—— simulator_simple.py
前文已述,训练用 SingleAssetOrderExecutionSimple(快、简化),回测用 simulator_qlib.py 的 SingleAssetOrderExecution(慢、含真实交易细节)。定制新交易场景(如换市场、改撮合规则)时,模拟器是改动量最大、也最需要谨慎的组件。
策略(Policy)层的定制入口
指南对"RL 算法研究者"给出的建议是:跑通示例后,修改 policy 部分把自家 RL 算法接进来。从源码看,qlib/rl/order_execution/policy.py 中 PPO 是 tianshou PPOPolicy 的封装(L102-L158):自动创建 actor/critic 网络(仅支持离散动作空间)、对 actor/critic 公共参数去重、支持 weight_file 加载 checkpoint,并暴露 lr、discount_factor、eps_clip、gae_lambda、max_batch_size 等常用超参默认值;DQN 同样是 DQNPolicy 的封装(L164-L208),支持 discount_factor、estimation_step、is_double 等参数。此外还有不可学习的基线策略 AllOne(输出恒定值,用于实现 TWAP 等规则基线,L46-L63)。要接入新算法(如 SAC、TD3 变体或自研算法),继承 tianshou 对应 policy 并按 PPO/DQN 的模式做封装、然后在配置里以 class/module_path 指向即可,无需触碰模拟器与解释器。
三类读者的推荐执行顺序(小结)
把指南原文的推荐序列落到可执行的清单上:
-
RL 算法新手:
- 在 overall 文档 学习 RL 基础(四要素、试错学习);
- 在 overall 文档 理解 RL 可应用的交易场景(订单执行、组合构建的 State/Action/Reward 一般设定);
- 按 quickstart 文档 与 examples/rl_order_execution/ 跑通示例;
- 想进一步定制时,先理解 framework 文档 的 EnvWrapper 四组件结构,再按需重写对应组件。
-
RL 算法研究者:
- 先理解交易场景(overall 文档 part2 章节);
- 选择一个场景(当前实现有订单执行与算法交易两个示例)跑通 quickstart 示例;
- 修改 policy.py 接入自己的 RL 算法。
-
量化研究员:
- 学习 RL 基础(part1)与交易场景(part2);
- 跑通 quickstart 示例;
- 理解 framework 文档的框架结构;
- 按问题特性选择算法(当前 QlibRL 基于 tianshou 支持 PPO 与 DQN);
- 基于市场交易规则与待解问题设计 MDP,参照订单执行示例修改 7 个模块:
SAOEState(state.py#L70)、SAOEMetrics(state.py#L18)、CategoricalActionInterpreter(interpreter.py#L199)、FullHistoryStateInterpreter(interpreter.py#L68)、Reward(reward.py)、FullHistoryObs(interpreter.py#L44)、Simulator(simulator_simple.py)。
最后,文档还指出 QlibRL 模块以松耦合方式设计,核心 RL 部分比示例呈现的更简洁;如果不关心具体业务逻辑,可以配合 examples/rl/simple_example.ipynb 这个"无业务损失"的专用 notebook 来理解 RL 内核。文档同时预告未来会提供更多场景示例(如基于 RL 的组合构建)。适用前提提醒:以上示例与命令均以当前仓库中 examples/rl_order_execution 与 qlib.rl 模块的实际代码为准,且需要依赖 tianshou、gym 与 PyTorch 环境(可参考 examples/rl_order_execution/ 下的配置与 qlib/rl/contrib/ 的训练入口确认参数细节)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

