Qlib实战:如何用表达式过滤器(ExpressionDFilter)快速筛选A股及可转债交易标的

在量化投资领域,高效筛选符合特定条件的交易标的是策略开发的关键环节。Qlib作为专业的AI量化平台,其ExpressionDFilter功能为研究人员提供了强大的动态筛选能力。本文将深入探讨如何利用这一工具构建灵活、高效的标的筛选系统。

1. Qlib基础环境配置与数据准备

Qlib的安装相对简单,但需要注意其依赖项较多。建议使用conda创建独立的Python环境:

conda create -n qlib_env python=3.8
conda activate qlib_env
pip install pyqlib

数据准备是使用Qlib的第一步。对于A股市场数据,可以通过以下命令获取:

python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn

初始化Qlib环境时,需要指定数据路径和地区:

from qlib.constant import REG_CN
import qlib

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

2. 核心API:D.instruments与D.features详解

Qlib提供了两个核心API用于数据查询:

  • D.instruments:获取符合特定条件的证券列表
  • D.features:获取指定证券的特征数据

典型应用场景对比:

功能D.instrumentsD.features
主要用途证券筛选数据获取
返回类型证券列表DataFrame
常用参数market, filter_pipeinstruments, fields
性能特点快速筛选详细数据

获取贵州茅台(600519)收盘价数据的示例:

from qlib.data import D

data = D.features(["sh600519"], ["$close"], start_time="20200101")
print(data.head())

3. ExpressionDFilter高级应用技巧

ExpressionDFilter是Qlib中最强大的筛选工具之一,其核心参数rule_expression支持丰富的表达式语法。

3.1 基础筛选条件

筛选收盘价低于130元的证券:

from qlib.data.filter import ExpressionDFilter

expression_filter = ExpressionDFilter(rule_expression="$close<130")
instruments = D.instruments(market="all", filter_pipe=[expression_filter])

3.2 复杂表达式构建

Qlib支持多种运算符和函数:

  • 比较运算符:>, <, >=, <=, ==, !=
  • 逻辑运算符:&, |, ~
  • 数学函数:Ref, Mean, Std, Max, Min

常用表达式示例:

筛选条件表达式写法
今日收盘高于昨日$close>Ref($close,1)
5日均线上穿10日均线Mean($close,5)>Mean($close,10)
成交量突破20日均量$volume>1.5*Mean($volume,20)

3.3 多条件组合筛选

构建复合筛选条件:

from qlib.data.filter import ExpressionDFilter

# 收盘价在100-130元之间且成交量大于20日均量
expression = "($close>100) & ($close<130) & ($volume>Mean($volume,20))"
filter_pipe = [ExpressionDFilter(rule_expression=expression)]
instruments = D.instruments(market="all", filter_pipe=filter_pipe)

4. 实战:可转债筛选系统构建

可转债市场具有独特的交易特性,Qlib可以高效实现专业筛选逻辑。

4.1 自定义数据导入

对于特殊品种如可转债,需要先导入自定义数据:

python scripts/dump_bin.py dump_all \
    --csv_path ./cb_quotes \
    --qlib_dir ./data/cb_data \
    --include_fields open,close,high,low,volume,factor \
    --symbol_field_name ts_code \
    --date_field_name trade_date

4.2 典型可转债筛选策略

双低策略实现:

# 双低值 = 价格 + 溢价率*100
expression = "($close + $premium_rt*100) < 130"
cb_filter = ExpressionDFilter(rule_expression=expression)
cb_list = D.instruments(market="all", filter_pipe=[cb_filter])

回售保护策略:

# 价格低于回售触发价且剩余年限小于2年
expression = "($close<$put_price) & ($remaining_years<2)"
cb_filter = ExpressionDFilter(rule_expression=expression)

4.3 与外部系统集成

将Qlib筛选结果与MongoDB中的持仓数据结合:

from pymongo import MongoClient

# 从Qlib获取筛选结果
expression = "$close<120"
filter_pipe = [ExpressionDFilter(rule_expression=expression)]
cb_list = D.list_instruments(instruments=D.instruments(filter_pipe=filter_pipe))

# 查询MongoDB中的持仓数据
client = MongoClient("mongodb://localhost:27017/")
db = client["quant"]
holdings = db.holdings.find({"symbol": {"$in": cb_list}})

5. 性能优化与高级技巧

5.1 筛选效率提升

  • 使用market参数缩小筛选范围
  • 避免过于复杂的表达式
  • 合理设置时间范围

性能对比测试:

筛选条件证券数量执行时间(ms)
全市场4000+1200
仅主板2000+600
特定行业300+150

5.2 表达式调试技巧

使用D.features验证表达式:

# 测试表达式是否正确
test_data = D.features(["sh600519"], ["$close", "Ref($close,1)"])
print(test_data)

5.3 自定义指标筛选

通过register_all添加自定义指标:

from qlib.data.dataset import register_all

# 定义自定义指标
def my_indicator(df):
    return df["$close"] / df["$volume"]
    
register_all({"my_ind": my_indicator})

# 使用自定义指标筛选
expression = "my_ind > 0.001"
filter_pipe = [ExpressionDFilter(rule_expression=expression)]

在实际项目中,我发现将常用筛选条件封装成函数可以大幅提高开发效率。例如,可以创建一个专门用于可转债筛选的工具类,包含各种常见策略的实现。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐