在量化投资领域,数据标注(Labeling)是构建机器学习模型的核心环节之一。对于A股市场的T+1交易制度,正确的标签定义直接关系到模型预测的有效性。本文将深入探讨如何在Qlib框架下,针对A股市场特性定制高效的机器学习标签。
A股市场实行T+1交易制度,即当日买入的股票需等到下一个交易日才能卖出。这一制度对标签定义提出了特殊要求。假设我们在T日做出交易决策,实际买入发生在T+1日,最早卖出时间为T+2日。因此,合理的收益率标签应反映T+1买入、T+2卖出的收益情况。
Qlib中常见的标签表达式为:
python复制Ref($close, -2)/Ref($close, -1) - 1
这个表达式的含义是:
Ref($close, -1):T+1日的收盘价(买入价)Ref($close, -2):T+2日的收盘价(卖出价)注意:在实盘交易中,还需考虑交易成本(佣金、印花税等),但基础标签通常先不考虑这些因素
根据不同的交易策略,可以设计多种持有期标签:
python复制Ref($close, -2)/Ref($close, -1) - 1
python复制Ref($close, -4)/Ref($close, -1) - 1
python复制Ref($close, -6)/Ref($close, -1) - 1
python复制Ref($close, -21)/Ref($close, -1) - 1
不同持有期标签的比较:
| 持有期 | 表达式示例 | 适用策略类型 | 波动性 |
|---|---|---|---|
| 1日 | Ref($close, -2)/Ref($close, -1)-1 | 高频套利 | 高 |
| 3日 | Ref($close, -4)/Ref($close, -1)-1 | 短线趋势 | 中高 |
| 5日 | Ref($close, -6)/Ref($close, -1)-1 | 波段交易 | 中 |
| 20日 | Ref($close, -21)/Ref($close, -1)-1 | 中长期投资 | 低 |
除了连续型收益率标签,分类标签在量化策略中也很常见:
python复制# 涨跌分类
If(Ref($close, -2)/Ref($close, -1)-1 > 0, 1, 0)
python复制# 三分类:大涨、持平、大跌
If(Ref($close, -2)/Ref($close, -1)-1 > 0.01, 2,
If(Ref($close, -2)/Ref($close, -1)-1 < -0.01, 0, 1))
python复制# 排除涨停后第二天无法买入的情况
Mask(Ref($close, -2)/Ref($close, -1)-1,
Ref($high, -1)/Ref($close, -2)-1 < 0.095)
python复制# 使用成交量判断是否停牌
Mask(Ref($close, -2)/Ref($close, -1)-1,
Ref($volume, -1) > 0)
相对于市场指数的超额收益:
python复制(Ref($close, -2)/Ref($close, -1) - 1) -
(Ref($index_close, -2)/Ref($index_close, -1) - 1)
使用夏普比率风格的标签:
python复制Mean(Ref($close, -2)/Ref($close, -1)-1, 5) /
Std(Ref($close, -2)/Ref($close, -1)-1, 5)
python复制# 放量上涨
If(And(Ref($close, -2)/Ref($close, -1)-1 > 0,
Ref($volume, -1)/Mean($volume, 20) > 1.5), 1, 0)
python复制from qlib.data.dataset.loader import QlibDataLoader
labels = ['Ref($close, -2)/Ref($close, -1) - 1']
label_names = ['1day_return']
data_loader_config = {
"label": (labels, label_names)
}
data_loader = QlibDataLoader(config=data_loader_config)
df = data_loader.load(instruments='csi300',
start_time='2020-01-01',
end_time='2023-12-31')
python复制multi_labels = [
'Ref($close, -2)/Ref($close, -1) - 1', # 1日收益
'Ref($close, -4)/Ref($close, -1) - 1', # 3日收益
'If(Ref($close, -2)/Ref($close, -1)-1 > 0, 1, 0)' # 涨跌分类
]
label_names = ['1day_return', '3day_return', 'up_down']
data_loader_config = {
"label": (multi_labels, label_names)
}
python复制from qlib.contrib.data.handler import Alpha158
class MyLabelHandler(Alpha158):
def get_label_config(self):
return (
[
'Ref($close, -2)/Ref($close, -1) - 1',
'Ref($close, -4)/Ref($close, -1) - 1'
],
['1day_return', '3day_return']
)
设计好的标签需要评估其质量:
优化方向:
在实际项目中,我通常会先测试3-5种不同的标签定义方式,通过上述评估方法选择表现最稳定的一种作为最终标签。特别是在A股市场,不同持有期标签在不同市场环境下表现差异很大,需要充分测试。