4. Qlib数据表达式引擎入门
任务目标
用 Qlib 的表达式引擎(Expression Engine)在已有行情数据上计算两类技术指标:移动平均(MA)与收益率(Return),并验证表达式结果与手工计算一致。
环境与依赖
- Python 3.8+,已安装
pyqlib(pip install pyqlib)。 - 已通过
python -m qlib.run.get_data或qlib.init准备好一份本地数据(本案例使用qlib_data/cn_data作为示例路径,请按实际路径替换)。
核心思路
Qlib 表达式引擎把字符串表达式(如 Mean($close, 5)、$close/Ref($close,1)-1)解析为算子并作用在行情字段上。字段以 $ 前缀引用,算子通过 qlib.data.ops 注册。我们只需初始化数据、构造表达式、调用 D.features 即可得到指标序列。
完整代码
import qlib
from qlib.data import D
# 1. 初始化 Qlib,指向本地数据目录
qlib.init(provider_uri="qlib_data/cn_data", region="cn")
# 2. 定义标的与时间区间
instruments = ["SH600000"]
fields = ["$close"]
# 3. 构造表达式:5日均线、10日均线、日收益率
exprs = {
"ma5": "Mean($close, 5)",
"ma10": "Mean($close, 10)",
"ret1": "$close / Ref($close, 1) - 1",
}
# 4. 通过表达式引擎计算指标
df = D.features(
instruments=instruments,
fields=list(exprs.values()),
start_time="2020-01-01",
end_time="2020-03-31",
freq="day",
)
df.columns = list(exprs.keys())
print(df.tail())
# 5. 验证:与 pandas 手工计算对比
import pandas as pd
close = D.features(instruments, fields, "2020-01-01", "2020-03-31", freq="day")
close.columns = ["close"]
manual = pd.DataFrame({
"ma5": close["close"].rolling(5).mean(),
"ma10": close["close"].rolling(10).mean(),
"ret1": close["close"].pct_change(),
})
diff = (df - manual).abs().max()
print("最大偏差:\n", diff)
assert (diff.fillna(0) < 1e-8).all(), "表达式结果与手工计算不一致"
print("验证通过:表达式引擎结果与手工计算一致")
运行方式
python expr_demo.py
验证方法与通过条件
- 脚本末尾的
assert通过,说明Mean、Ref等算子结果与 pandas 手工计算在数值上一致(阈值 1e-8)。 - 若断言失败,检查
provider_uri是否指向真实数据目录,以及标的代码是否存在于该数据集中。 - 常见问题:
Mean前 4 个交易日为NaN(窗口不足),属正常现象,对比时用fillna(0)处理。