前言:为什么选择Qlib?

如果你是一名技术开发者,想要进入量化投资领域,你可能会面临这些问题:

  • 数据从哪里来? 如何高效存储和检索海量金融数据?
  • 特征怎么构建? 158个技术因子?360个?还是自己一个个写?
  • 模型怎么选? LSTM、LightGBM、Transformer…哪个适合金融预测?
  • 策略怎么回测? 如何模拟真实交易环境,考虑滑点、手续费、流动性?
  • 如何系统化? 怎么把数据处理、模型训练、策略回测串联成完整流水线?

Microsoft Qlib 正是为解决这些问题而生的AI量化投资平台。它不是一个简单的回测框架,而是一个覆盖量化投资全流程的机器学习研究平台。

Qlib的定位:AI-oriented Quantitative Investment Platform(面向AI的量化投资平台)


一、Qlib架构设计理念

1.1 整体架构:四层设计

Qlib采用分层架构设计,从底层基础设施到上层用户接口,共分为四层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────────────────────────────────────────────────────┐
│ Interface Layer(接口层) │
│ Analyser: 提供预测信号、投资组合、执行结果的分析报告 │
├─────────────────────────────────────────────────────────────┤
│ Workflow Layer(工作流层) │
│ Information Extractor → Forecast Model → Decision Generator │
│ → Execution Env → Strategy → Executor │
├─────────────────────────────────────────────────────────────┤
│ Learning Framework Layer(学习框架层) │
│ Forecast Model & Trading Agent(支持监督学习+强化学习) │
├─────────────────────────────────────────────────────────────┤
│ Infrastructure Layer(基础设施层) │
│ DataServer: 高性能数据管理 Trainer: 灵活训练控制 │
└─────────────────────────────────────────────────────────────┘

各层职责

层次 核心组件 职责
基础设施层 DataServer, Trainer 数据存储检索、训练过程控制
学习框架层 Forecast Model, Trading Agent 模型训练、策略学习
工作流层 Strategy, Executor, Analyser 策略生成、订单执行、结果分析
接口层 Analyser 用户友好的分析报告

1.2 模块化设计哲学

Qlib的核心设计理念是松耦合

1
2
3
4
5
# 每个模块都可以独立使用
from qlib.data.dataset import DatasetH # 数据模块
from qlib.contrib.model.gbdt import LGBModel # 模型模块
from qlib.contrib.strategy import TopkDropoutStrategy # 策略模块
from qlib.backtest import backtest # 回测模块

这种设计的好处:

  1. 灵活替换:不满意某个模型?换成自己的实现
  2. 渐进学习:先掌握数据处理,再学模型训练,最后回测
  3. 复用性强:同一套数据可以用于多个模型实验

1.3 配置驱动流水线(CDPE)

Qlib提供了Config-Driven Pipeline Engine,用YAML配置定义整个工作流:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 一个完整的量化研究工作流配置
task:
model:
class: LGBModel
module_path: qlib.contrib.model.gbdt
kwargs:
loss: mse
learning_rate: 0.05
dataset:
class: DatasetH
module_path: qlib.data.dataset
kwargs:
handler:
class: Alpha158 # 内置158因子

二、数据处理流水线

2.1 数据存储设计

Qlib使用时间序列扁平文件存储,专为金融数据优化:

1
2
3
4
5
6
7
8
9
10
qlib_data/
├── calendars/
│ └── day.txt # 交易日历
├── instruments/
│ └── csi300.txt # 股票池定义
└── features/
└── SH000001/
├── close.day.bin # 收盘价(二进制存储)
├── open.day.bin
└── volume.day.bin

性能优势

  • 二进制存储,读取速度快
  • 内置缓存机制,避免重复计算
  • 支持表达式计算,如 $close / $open

2.2 快速初始化数据

1
2
3
4
5
6
7
8
import qlib
from qlib.data import D

# 方式1:使用内置数据(1分钟下载)
qlib.init(provider_uri='~/.qlib/qlib_data/cn_data')

# 方式2:自定义数据路径
qlib.init(provider_uri='./my_data')

2.3 数据API详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from qlib.data import D

# 1. 获取单只股票数据
close = D.features(
instruments=["SH000001"], # 股票代码
fields=["$close", "$open"], # 字段
start_time="2020-01-01",
end_time="2020-12-31",
freq="day"
)

# 2. 获取整个股票池数据
csi300_data = D.features(
D.instruments(market="csi300"), # 沪深300成分股
["$close", "$open", "$high", "$low"],
start_time="2020-01-01",
end_time="2020-12-31"
)

# 3. 表达式计算(因子构建)
factor = D.features(
["SH000001"],
["($close - $open) / $open", # 日收益率
"Mean($close, 5)", # 5日均线
"Std($close, 20)"], # 20日标准差
start_time="2020-01-01",
end_time="2020-12-31"
)

2.4 数据处理器与特征工程

Qlib提供了强大的DataHandler进行特征工程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from qlib.contrib.data.handler import Alpha158

# Alpha158:内置158个技术因子
handler_config = {
"start_time": "2010-01-01",
"end_time": "2020-12-31",
"fit_start_time": "2010-01-01",
"fit_end_time": "2017-12-31",
"instruments": "csi300",
}

handler = Alpha158(**handler_config)

# Alpha158包含的因子类型:
# - KBAR系列:开高低收相关
# - KDJ系列:随机指标
# - RSI系列:相对强弱指标
# - MACD系列:指数平滑异同移动平均
# - BOLL系列:布林带
# ... 共158个

自定义数据处理器

1
2
3
4
5
6
7
8
from qlib.data.dataset.handler import DataHandlerLP

class MyCustomHandler(DataHandlerLP):
def fit_process(self):
# 自定义特征工程逻辑
df = self.fetch()
df['my_factor'] = df['$close'] / df['$open'] - 1
return df

2.5 数据集划分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from qlib.data.dataset import DatasetH

dataset = DatasetH(
handler={
"class": "Alpha158",
"module_path": "qlib.contrib.data.handler",
"kwargs": {
"start_time": "2008-01-01",
"end_time": "2020-08-01",
"instruments": "csi300",
},
},
segments={
"train": ("2008-01-01", "2014-12-31"), # 训练集
"valid": ("2015-01-01", "2016-12-31"), # 验证集
"test": ("2017-01-01", "2020-08-01"), # 测试集
},
)

三、模型训练与预测

3.1 内置模型库

Qlib内置了丰富的机器学习模型:

模型 类型 适用场景
LGBModel GBDT 表格数据,速度快
MLPModel 神经网络 非线性关系
GRUModel RNN 时序依赖
LSTMModel RNN 长期记忆
TFTModel Transformer 多变量时序
GATsModel 图神经网络 股票关联

3.2 LightGBM模型实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from qlib.utils import init_instance_by_config

# 模型配置
model_config = {
"class": "LGBModel",
"module_path": "qlib.contrib.model.gbdt",
"kwargs": {
"loss": "mse", # 损失函数
"colsample_bytree": 0.8879, # 特征采样比例
"learning_rate": 0.0421, # 学习率
"subsample": 0.8789, # 样本采样比例
"lambda_l1": 205.6999, # L1正则化
"lambda_l2": 580.9768, # L2正则化
"max_depth": 8, # 树深度
"num_leaves": 210, # 叶子节点数
"num_threads": 20, # 并行线程数
},
}

# 初始化模型
model = init_instance_by_config(model_config)

# 训练模型
model.fit(dataset)

# 预测
predictions = model.predict(dataset)

3.3 实验管理与记录

Qlib内置了完善的实验管理系统:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from qlib.workflow import R
from qlib.workflow.record_temp import SignalRecord

# 开始实验
with R.start(experiment_name="my_experiment"):
# 记录超参数
R.log_params(learning_rate=0.05, model="LightGBM")

# 训练模型
model.fit(dataset)

# 保存模型
R.save_objects(trained_model=model)

# 获取实验记录器ID
recorder_id = R.get_recorder().id

# 生成预测信号记录
sr = SignalRecord(model, dataset, R.get_recorder())
sr.generate()

3.4 自定义模型开发

继承qlib.model.base.Model即可开发自定义模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from qlib.model.base import Model
import pandas as pd

class MyCustomModel(Model):
def __init__(self, **kwargs):
# 初始化参数
self.params = kwargs

def fit(self, dataset):
"""
训练模型
dataset: Qlib数据集对象
"""
# 获取训练数据
train_data = dataset.prepare("train")

# 实现你的训练逻辑
# self._train_your_model(train_data)

return self

def predict(self, dataset):
"""
预测
返回: pd.Series,索引为(instrument, datetime)
"""
test_data = dataset.prepare("test")

# 实现你的预测逻辑
predictions = self._make_predictions(test_data)

return predictions

def finetune(self, dataset):
"""
微调(可选)
"""
pass

配置使用自定义模型

1
2
3
4
5
6
model:
class: MyCustomModel
module_path: my_module.custom_model # 你的模块路径
kwargs:
param1: value1
param2: value2

四、回测系统详解

4.1 回测核心概念

Qlib的回测系统包含三个核心组件:

1
Strategy(策略)→ Executor(执行器)→ Account(账户)
  • Strategy:生成交易决策(买入/卖出哪些股票)
  • Executor:模拟订单执行(考虑滑点、手续费)
  • Account:管理资金和持仓

4.2 TopkDropout策略

最常用的策略,逻辑简单但有效:

1
2
3
4
5
6
7
8
9
from qlib.contrib.strategy import TopkDropoutStrategy

strategy_config = {
"topk": 50, # 持仓股票数量
"n_drop": 5, # 每次调仓替换数量
"signal": pred_score, # 预测分数(pd.Series)
}

strategy = TopkDropoutStrategy(**strategy_config)

策略逻辑

  1. 根据预测分数对股票排序
  2. 选择分数最高的topk只股票持仓
  3. 每期替换n_drop只分数下降最多的股票

4.3 回测执行器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from qlib.backtest import executor

executor_config = {
"time_per_step": "day", # 交易频率
"generate_portfolio_metrics": True, # 生成组合指标
}

# 交易所配置
exchange_config = {
"freq": "day",
"limit_threshold": 0.095, # 涨跌停限制
"deal_price": "close", # 成交价格
"open_cost": 0.0005, # 开仓成本(0.05%)
"close_cost": 0.0015, # 平仓成本(0.15%)
"min_cost": 5, # 最小手续费(5元)
}

4.4 完整回测示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from qlib.backtest import backtest
from qlib.contrib.evaluate import risk_analysis
from qlib.contrib.strategy import TopkDropoutStrategy

# 回测配置
backtest_config = {
"start_time": "2017-01-01",
"end_time": "2020-08-01",
"account": 100000000, # 初始资金:1亿
"benchmark": "SH000300", # 基准:沪深300
"exchange_kwargs": {
"freq": "day",
"limit_threshold": 0.095,
"deal_price": "close",
"open_cost": 0.0005,
"close_cost": 0.0015,
"min_cost": 5,
},
}

# 创建策略
strategy = TopkDropoutStrategy(
topk=50,
n_drop=5,
signal=predictions # 模型预测结果
)

# 创建执行器
executor_obj = executor.SimulatorExecutor(
time_per_step="day",
generate_portfolio_metrics=True
)

# 执行回测
portfolio_metric_dict, indicator_dict = backtest(
executor=executor_obj,
strategy=strategy,
**backtest_config
)

# 获取回测结果
report_normal, positions_normal = portfolio_metric_dict.get("day")

# 风险分析
analysis = risk_analysis(report_normal["return"], freq="day")
print(analysis)

4.5 回测结果分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from qlib.contrib.evaluate import risk_analysis

# 计算超额收益
excess_return_without_cost = risk_analysis(
report_normal["return"] - report_normal["bench"],
freq="day"
)

excess_return_with_cost = risk_analysis(
report_normal["return"] - report_normal["bench"] - report_normal["cost"],
freq="day"
)

# 输出关键指标
print("=" * 50)
print("策略表现分析")
print("=" * 50)
print(f"年化收益率: {analysis['annualized_return']:.4f}")
print(f"夏普比率: {analysis['sharpe_ratio']:.4f}")
print(f"最大回撤: {analysis['max_drawdown']:.4f}")
print(f"信息比率: {analysis['information_ratio']:.4f}")

五、完整工作流实战

5.1 一键运行:qrun

Qlib提供了qrun命令行工具,一行命令运行完整工作流:

1
2
3
4
5
# 下载配置文件示例
wget https://raw.githubusercontent.com/microsoft/qlib/main/examples/benchmarks/LightGBM/lightgbm_config.yaml

# 运行完整工作流
qrun lightgbm_config.yaml

5.2 完整代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
Qlib完整工作流示例
包含:数据准备 → 模型训练 → 回测分析
"""

import qlib
from qlib.utils import init_instance_by_config, flatten_dict
from qlib.workflow import R
from qlib.workflow.record_temp import SignalRecord, PortAnaRecord

# ==================== 1. 初始化Qlib ====================
qlib.init(provider_uri="~/.qlib/qlib_data/cn_data")

# 配置参数
MARKET = "csi300" # 沪深300
BENCHMARK = "SH000300" # 基准指数
EXP_NAME = "qlib_demo" # 实验名称

# ==================== 2. 定义任务配置 ====================
# 数据处理器配置
data_handler_config = {
"start_time": "2008-01-01",
"end_time": "2020-08-01",
"fit_start_time": "2008-01-01",
"fit_end_time": "2014-12-31",
"instruments": MARKET,
}

# 完整任务配置
task = {
"model": {
"class": "LGBModel",
"module_path": "qlib.contrib.model.gbdt",
"kwargs": {
"loss": "mse",
"colsample_bytree": 0.8879,
"learning_rate": 0.0421,
"subsample": 0.8789,
"lambda_l1": 205.6999,
"lambda_l2": 580.9768,
"max_depth": 8,
"num_leaves": 210,
"num_threads": 20,
},
},
"dataset": {
"class": "DatasetH",
"module_path": "qlib.data.dataset",
"kwargs": {
"handler": {
"class": "Alpha158",
"module_path": "qlib.contrib.data.handler",
"kwargs": data_handler_config,
},
"segments": {
"train": ("2008-01-01", "2014-12-31"),
"valid": ("2015-01-01", "2016-12-31"),
"test": ("2017-01-01", "2020-08-01"),
},
},
},
}

# ==================== 3. 模型训练 ====================
model = init_instance_by_config(task["model"])
dataset = init_instance_by_config(task["dataset"])

with R.start(experiment_name="train_model"):
R.log_params(**flatten_dict(task))
model.fit(dataset)
R.save_objects(trained_model=model)
rid = R.get_recorder().id
print(f"模型已保存,recorder_id: {rid}")

# ==================== 4. 回测配置 ====================
port_analysis_config = {
"executor": {
"class": "SimulatorExecutor",
"module_path": "qlib.backtest.executor",
"kwargs": {
"time_per_step": "day",
"generate_portfolio_metrics": True,
},
},
"strategy": {
"class": "TopkDropoutStrategy",
"module_path": "qlib.contrib.strategy.signal_strategy",
"kwargs": {
"topk": 50,
"n_drop": 5,
},
},
"backtest": {
"start_time": "2017-01-01",
"end_time": "2020-08-01",
"account": 100000000,
"benchmark": BENCHMARK,
"exchange_kwargs": {
"freq": "day",
"limit_threshold": 0.095,
"deal_price": "close",
"open_cost": 0.0005,
"close_cost": 0.0015,
"min_cost": 5,
},
},
}

# ==================== 5. 执行回测 ====================
with R.start(experiment_name="backtest_analysis"):
# 加载训练好的模型
recorder = R.get_recorder(recorder_id=rid, experiment_name="train_model")
model = recorder.load_object("trained_model")

# 生成预测信号
sr = SignalRecord(model, dataset, R.get_recorder())
sr.generate()

# 执行回测分析
par = PortAnaRecord(R.get_recorder(), port_analysis_config, "day")
par.generate()

print("回测完成!请查看实验记录获取详细结果。")

六、与其他量化框架对比

6.1 主流量化框架概览

框架 开发者 核心定位 Stars
Qlib Microsoft AI量化研究平台 14K+
Backtrader mementum 事件驱动回测 14K+
VnPy 社区 全栈量化交易 24K+
Zipline Quantopian 因子研究 16K+

6.2 详细对比分析

Qlib vs Backtrader

维度 Qlib Backtrader
核心定位 AI量化研究平台 事件驱动回测引擎
机器学习 ✅ 内置丰富模型库 ❌ 需自行集成
因子库 ✅ Alpha158/Alpha360 ❌ 需自己实现
回测方式 向量化+事件驱动 纯事件驱动
实盘交易 ⚠️ 需额外开发 ✅ 支持IB等接口
学习曲线 较陡峭 平缓
维护状态 ✅ 活跃维护 ⚠️ 2019年后停止更新

适用场景

  • Qlib:机器学习因子研究、截面选股策略
  • Backtrader:学习事件驱动概念、快速策略验证

Qlib vs VnPy

维度 Qlib VnPy
核心定位 AI量化研究 全栈量化交易
中国市场 ✅ 内置A股数据 ✅ 原生CTP支持
实盘交易 ⚠️ 较弱 ✅ 成熟实盘接口
GUI界面 ❌ 无 ✅ 完善GUI
机器学习 ✅ 核心优势 ⚠️ 集成较弱
策略类型 多因子选股 CTA趋势跟踪

适用场景

  • Qlib:学术研究、因子挖掘、ML策略
  • VnPy:CTA策略、期货实盘、国内市场

Qlib vs Zipline

维度 Qlib Zipline
Pipeline API ⚠️ 不同实现 ✅ 经典Pipeline
数据格式 自定义二进制 Bundle格式
因子研究 ✅ ML导向 ✅ 因子导向
动态股票池 ✅ 支持 ✅ 核心特性
维护状态 ✅ 活跃 ⚠️ 原版停止维护

6.3 选择建议

1
2
3
4
5
6
7
8
你的需求                          推荐框架
─────────────────────────────────────────────
学习量化/入门 → Backtrader
ML因子挖掘/学术研究 → Qlib
中国A股CTA策略/期货实盘 → VnPy
美股因子研究/动态选股 → Zipline-Reloaded
加密货币量化 → VnPy
多因子截面选股 → Qlib

6.4 组合使用策略

实际项目中,可以组合使用多个框架:

1
2
3
4
学习阶段 → 研究阶段 → 生产阶段
↓ ↓ ↓
Backtrader Qlib VnPy
(理解概念) (因子研究) (实盘部署)

七、进阶主题

7.1 强化学习模块

Qlib支持强化学习策略:

1
2
3
4
5
6
7
from qlib.rl.contrib.executor import SingleAssetOrderExecution

# RL组件
# - Simulator: 市场模拟器
# - State Interpreter: 状态解释器
# - Action Interpreter: 动作解释器
# - Reward Function: 奖励函数

7.2 超参数调优

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from qlib.model.trainer import task_train

# 定义参数搜索空间
task_config = {
"model": {
"kwargs": {
"learning_rate": {"_type": "choice", "_value": [0.01, 0.05, 0.1]},
"max_depth": {"_type": "choice", "_value": [6, 8, 10]},
}
}
}

# 自动调参
task_train(task_config)

7.3 模型集成

1
2
3
4
5
6
7
from qlib.model.ens import Ensemble

# 集成多个模型
ensemble = Ensemble(
models=[model_lgb, model_lstm, model_transformer],
method="mean" # 或 "vote", "stacking"
)

八、常见问题与解决方案

Q1: 数据从哪里获取?

1
2
# 使用Qlib内置数据下载工具
python -m qlib.run.get_data qlib_data

或使用第三方数据源(Tushare、AKShare)转换:

1
2
3
4
from qlib.data import D

# 将CSV转换为Qlib格式
D.dump_data(file_path="./my_data.csv", target_dir="./qlib_data")

Q2: 如何添加自定义因子?

1
2
3
4
5
6
from qlib.data.expr import Expression

# 定义自定义因子
@Expression.register("my_factor")
def my_factor(close, volume):
return close / volume.rolling(5).mean()

Q3: 回测速度慢怎么办?

  • 使用Alpha158而非Alpha360
  • 减少股票池大小
  • 使用更粗的时间粒度(day而非minute)
  • 启用数据缓存

Q4: 如何可视化结果?

1
2
3
4
from qlib.contrib.report import analysis_position

# 生成分析报告
analysis_position(report_normal, positions_normal)

总结

Microsoft Qlib是一个强大的AI量化投资平台,它的核心优势在于:

  1. 完整的ML Pipeline:从数据处理到模型训练到回测分析
  2. 丰富的内置资源:Alpha158因子库、多种ML模型
  3. 灵活的架构设计:模块化、可扩展、配置驱动
  4. 活跃的社区支持:微软持续维护更新

对于技术开发者来说,Qlib是进入量化投资领域的绝佳选择。它让你专注于策略研究本身,而不是被数据、特征、回测等基础设施所困扰。

下一步建议

  1. 安装Qlib,运行官方Quick Start
  2. 理解Alpha158因子库的构成
  3. 尝试不同的模型,比较效果
  4. 开发自定义策略,进行回测验证
  5. 结合实盘需求,选择合适的框架组合

参考资料