首页
/ Qlib QlibRL 使用指南:面向不同背景开发者的强化学习量化策略上手路径

Qlib QlibRL 使用指南:面向不同背景开发者的强化学习量化策略上手路径

2026-09-05 22:27:58作者:董宙帆

本文基于 Qlib 官方文档中的 QlibRL Guidance 指南编写,面向三类读者(RL 新手、RL 算法研究者、量化研究员)给出各自定制化的 QlibRL 学习路径,并结合 examples/rl_order_execution/ 中单资产订单执行(SAOE)示例的配置文件与 qlib/rl/order_execution/ 下的 MDP 组件源码,帮助你在读完之后掌握"按自身背景选路径 → 跑通训练与回测 → 自定义 State/Action/Reward 等组件"的完整实操能力。

QlibRL 框架图

RL 框架四要素图

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 系统由四个要素构成:

  1. Agent(智能体):决策主体;
  2. Environment(环境):智能体交互的对象;
  3. Policy(策略):智能体据以对环境影响采取动作的规则;
  4. 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/ 下应有 binorderspickle 三个目录,分别对应训练配置中 data_dirorder_dirfeature_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 中的 PPODQN 封装类。

启动训练

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.ymlexp_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.pyqlib/rl/order_execution/simulator_simple.py
  • State interpreter(状态解释器):把模拟器原始格式的状态"翻译"成策略可理解的格式,例如把非结构化原始特征转换为数值张量;
  • Action interpreter(动作解释器):方向相反,把策略输出的动作从策略格式转换为模拟器可接受的格式;
  • Reward function(奖励函数):策略每执行一次动作后返回一个数值奖励。

EnvWrapper 会把这四部分"有机关联"起来。这种解耦带来的灵活性是:同一个环境(一个模拟器)可以搭配不同的状态解释器/动作解释器/奖励函数,训练多种类型的策略。所有组件都有定义良好的基类,定制方式就是继承基类并实现其要求的接口,基类 API 见 qlib/rl/interpreter.pyStateInterpreterActionInterpreter)与 qlib/rl/reward.pyReward)。

指南点名的 MDP 模块逐一解析

指南针对"量化研究员设计 MDP"这一步,给出了订单执行示例中需要对照修改的 7 个模块及其源码位置。下面结合源码逐一说明它们在 MDP 建模中承担的角色:

1. State(状态)—— SAOEState

SAOEState 是一个 NamedTuple,是模拟器输出的原始状态结构,包含:当前订单 order、当前时间 cur_time、当前步数 cur_step、剩余待执行量 position、历史成交明细 history_exec、历史各步统计 history_steps、结算后才有的日度指标 metrics、回测数据 backtest_data,以及 ticks_per_stepticks_indexticks_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.pySingleAssetOrderExecution(慢、含真实交易细节)。定制新交易场景(如换市场、改撮合规则)时,模拟器是改动量最大、也最需要谨慎的组件。

策略(Policy)层的定制入口

指南对"RL 算法研究者"给出的建议是:跑通示例后,修改 policy 部分把自家 RL 算法接进来。从源码看,qlib/rl/order_execution/policy.pyPPO 是 tianshou PPOPolicy 的封装(L102-L158):自动创建 actor/critic 网络(仅支持离散动作空间)、对 actor/critic 公共参数去重、支持 weight_file 加载 checkpoint,并暴露 lrdiscount_factoreps_clipgae_lambdamax_batch_size 等常用超参默认值;DQN 同样是 DQNPolicy 的封装(L164-L208),支持 discount_factorestimation_stepis_double 等参数。此外还有不可学习的基线策略 AllOne(输出恒定值,用于实现 TWAP 等规则基线,L46-L63)。要接入新算法(如 SAC、TD3 变体或自研算法),继承 tianshou 对应 policy 并按 PPO/DQN 的模式做封装、然后在配置里以 class/module_path 指向即可,无需触碰模拟器与解释器。

三类读者的推荐执行顺序(小结)

把指南原文的推荐序列落到可执行的清单上:

  1. RL 算法新手

  2. RL 算法研究者

    • 先理解交易场景(overall 文档 part2 章节);
    • 选择一个场景(当前实现有订单执行与算法交易两个示例)跑通 quickstart 示例;
    • 修改 policy.py 接入自己的 RL 算法。
  3. 量化研究员

    • 学习 RL 基础(part1)与交易场景(part2);
    • 跑通 quickstart 示例;
    • 理解 framework 文档的框架结构;
    • 按问题特性选择算法(当前 QlibRL 基于 tianshou 支持 PPO 与 DQN);
    • 基于市场交易规则与待解问题设计 MDP,参照订单执行示例修改 7 个模块:SAOEStatestate.py#L70)、SAOEMetricsstate.py#L18)、CategoricalActionInterpreterinterpreter.py#L199)、FullHistoryStateInterpreterinterpreter.py#L68)、Rewardreward.py)、FullHistoryObsinterpreter.py#L44)、Simulatorsimulator_simple.py)。

最后,文档还指出 QlibRL 模块以松耦合方式设计,核心 RL 部分比示例呈现的更简洁;如果不关心具体业务逻辑,可以配合 examples/rl/simple_example.ipynb 这个"无业务损失"的专用 notebook 来理解 RL 内核。文档同时预告未来会提供更多场景示例(如基于 RL 的组合构建)。适用前提提醒:以上示例与命令均以当前仓库中 examples/rl_order_executionqlib.rl 模块的实际代码为准,且需要依赖 tianshou、gym 与 PyTorch 环境(可参考 examples/rl_order_execution/ 下的配置与 qlib/rl/contrib/ 的训练入口确认参数细节)。

登录后查看全文
热门项目推荐
相关项目推荐