别再死盯K线了,我用微软Qlib撸了个A股因子择时系统,效果出奇地稳

3,719 阅读5分钟

别再死盯K线了,我用微软Qlib撸了个A股因子择时系统,效果出奇地稳

Qlib到底是什么?我为啥选它?

Qlib,是微软开源的一个量化研究框架,全名 Quantitative Library。看着名字挺吓人,但说白了,它就是帮你搞定「数据下载、特征工程、模型训练、回测」这些枯燥又重要的环节的一整套工具。

image.png

为什么我要用它?

说实话,一开始我也是怀疑的。毕竟开源项目,谁知道维护咋样。但后来我发现:Qlib 把A股支持得还挺好。数据能自动下,接口很顺,最关键——能很方便地玩因子+机器学习。

你可能在想:花姐,A股量化,通联万得也能做呀,干嘛用 Qlib?

答案很简单:自由度高。你想自己造数据,Qlib给你留了口子;你想玩个 LightGBM 或者 RNN,它都给你封装好了。用下来我的感受就是:这玩意儿是写给有点Python经验,但不想从零造轮子的量化开发者用的。


安装|不要跳过!不然你会想砸电脑

咱们得实话实说——Qlib 安装是个劝退点

尤其是搞A股版本的数据源,很多人一上来 pip install qlib 然后直接运行 sample,啪,报错一堆,瞬间怀疑人生🥲

我总结一下必须注意的几个点

  1. Python版本别乱装 官方推荐用这几个版本的Python

image.png

  1. 别用conda装Qlib!

    • 很多人用conda装环境,但 Qlib 的依赖管理不太友好,容易冲突。我推荐:直接用 venv + pip,别嫌麻烦。
  2. A股数据需要手动下载初始化

    • 默认装完 Qlib,是跑美股数据的。A股的得你自己跑下面这段代码:
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
  1. 配置环境变量

    • 有些人没配置 QLIB_DATA 路径,直接在代码里 import data 就挂了。搞定方式也不难:
import qlib
qlib.init(provider_uri="~/.qlib/qlib_data/cn_data", region="cn")

照着来,就能正常运行了。聪明的你,一定能发现:其实这些坑都不是“难”,而是“绕”😅。


因子择时|别把择时想得太复杂

好,我们切正题——如何用Qlib做一个A股的因子择时系统?

说白了,我们要做的事就是:

  1. 找出一些预判未来收益的因子(比如量价类、技术类、情绪类);
  2. 用这些因子做输入特征;
  3. 拿未来几天的收益当标签;
  4. 训练一个模型,预测下阶段谁涨谁跌;
  5. 根据打分做出择时决策。

听上去是不是挺熟悉?是的,这就是经典的 Alpha 模型选股逻辑。但我们可以把它拿来做择时:不是选个股,而是打分看大盘或指数未来涨跌概率


教学实战|来,搞一套超简单的 Alpha 模型

我们先从一个基础模型开始——比如,用简单的技术指标因子 + 未来5天收益作为目标。以沪深300为例,选股池先设成这个。

先看代码,咱一步步走:

Step 1:初始化 + 数据加载

import qlib
from qlib.config import REG_CN
from qlib.data import D

qlib.init(provider_uri="~/.qlib/qlib_data/cn_data", region=REG_CN)

然后选一批股票 + 时间范围:

instruments = 'csi300'
market = D.features(instruments, ['$close'], start_time='2024-01-01', end_time='2025-01-31')

你可能问,$close 是啥意思?这是 Qlib 的特有语法,$ 开头表示这是原始字段。跟你熟悉的 pandas 不太一样,得习惯。

Step 2:构造因子

为了示范,我们用3个简单因子(你也可以自己造):

import pandas as pd

df = D.features(
    instruments,
    ['$close', 'Ref($close, 1)', 'Ref($close, 5)'],
    start_time='2024-01-01', end_time='2025-01-31'
)

df['ret_5'] = (df['$close'] - df['Ref($close, 5)']) / df['Ref($close, 5)']
df['ret_1'] = (df['$close'] - df['Ref($close, 1)']) / df['Ref($close, 1)']
df['momentum'] = df['ret_1'] - df['ret_5']

这就是一个最简单的动量因子啦🎉

Step 3:定义标签

我们要预测未来5天的收益,所以:

from qlib.utils import get_date_range

dates = get_date_range('2024-01-01', '2025-01-31')
df['label'] = df.groupby(level=0)['$close'].shift(-5) / df['$close'] - 1

踩坑提醒💡:这里如果你忘了 .groupby(level=0),你会发现很多 shift 出来的数据对不上股票……


模型构建|用LightGBM搞一把

Qlib已经封装好了很多模型接口,咱直接用:

from qlib.contrib.model.gbdt import LGBModel
from qlib.contrib.data.handler import Alpha158
from qlib.workflow import R

handler = Alpha158(instruments='csi300', start_time='2024-01-01', end_time='2025-01-31')
model = LGBModel()

R.start(experiment_name="timing_demo")
model.fit(dataset=handler)

是不是很像“套路”?是的,但是这个套路非常实用。你要是愿意深入,还可以自己写 handler 和 dataset,Qlib都支持。


策略落地|怎么做择时?

这里我玩了个小技巧:

我们不是预测每只股票的涨跌,而是拿它们的打分分布来判断当前是否是一个好的入场时机。

也就是说:

  • 如果大部分票都被模型打高分,那我就入场;
  • 如果打分很低,那我空仓。

这其实是某种意义上的“横截面择时”。

核心代码逻辑是这样的:

def get_market_signal(model, dataset, threshold=0.6):
    preds = model.predict(dataset)
    top_scores = preds.groupby(level=0).apply(lambda x: x.quantile(0.8))
    signal = (top_scores > threshold).astype(int)
    return signal

你看这个 signal,其实就可以当成一个择时信号啦,配合回测引擎使用(比如你可以用Backtrader或者Qlib自带的portfolio回测)🔍

image.png


小结?不存在的~

我知道你在找总结段?没有,花姐不搞这一套🙃

因为量化这玩意儿,本就不是靠总结就能学会的。你得多试、多错、多问。

但我要告诉你一个结论:Qlib是一个值得你花时间研究的量化框架,尤其适合你想搞因子、玩模型,又不想被数据和代码搞死的场景。

这篇文章只是抛砖引玉,还想继续深入?想做“多因子组合策略”、“收益预测+行业轮动”?留言给我,下一篇咱接着写🔥

— 花姐