label的技巧:对收益率打标的4种方法
由small_q创建,最终由small_q 被浏览 341 用户
在我们找到一堆因子后,下一步就是把这些因子打好标,丢入模型,让模型去寻找因子和标签的映射规律。
标签就是你要解决的问题,标签应该是和因子强相关的。随意的打标会增加模型预测的难度,而过于傻瓜的打标会限制因子的发挥。
普遍做法:n个周期后的收益率作为标签
普遍做法是用n个周期后的收益率作为标签🏷️,这里作为label的收益率是连续的。但实际上你label的方式应该紧扣你的策略,你要考虑到品种的流动性、交易的频率、交易的时间级别、有没有手续费/返还等等。
举几个例子,比如你按照日级别交易,那可以直接用每日的收益率作为label。如果你用期权作为交易工具,或者是做市商,那么相比于下一个时间会涨跌多少,你会更关心收益率的波动会不会超过一定阈值,或者说涨跌会有多大的幅度,这时候就更适用对收益率分箱。
当然在label之前,你要看看原始的收益率分布图,如果是像下面尖峰肥尾的长相,要先对收益率做log和去除异常值处理。
处理完后,收益率更接近正态分布了:\n
接下来我们一起捋一捋label的几种方式。
2分类打标法
第一种方式,也是最简单的label方式,就是2分类打标法,把上涨的收益率标记成1,下跌的收益率标记成0。简单是简单,但是缺点也很显著:它没有区分涨跌的幅度差异,涨0.01%和涨1000%会被贴上同样的标签。
# 获取上涨和下跌的index
idx_pos = data[data['return'] > 0].index
idx_neg = data[data['return'] < 0].index
# 打标
data.loc[idx_pos, 'Label'] = 1
data.loc[idx_neg, 'Label'] = 0
三重打标法
第二种方法即量化交易中的数据预处理:对金融时序数据重采样,新打标法和分数差分法,也就是Marcos López de Prado在那本金融数据机器学习书中第三章提出的「三重打标法」,这个方法会设置一个阈值,只有超过这个阈值才打上标签。
这种做法是不是有点眼熟?在因子的处理中,你应该也用到过类似的做法——连续变量离散化,也就是因子的分箱,这里把收益率也做了同样的离散化操作。
三重打标法虽然改进了二元打标法,但依然是以固定的阈值label,所以它的前提假设是市场没有结构性变化,也没有波动率聚集的现象。而现实中市场是动态演变的,震荡行情和趋势行情的阈值设置一定是要有所区别的。改进的方法是对市场的波动率做区分,动态的去确定这个阈值。
# 获取不同阈值水平的index
idx_lower = data[data['return'] < -threshold].index
idx_middle = data[abs(data['return']) <= threshold].index
idx_upper = data[data['return'] > threshold].index
# 打标
data.loc[idx_lower, 'Label'] = -1
data.loc[idx_middle, 'Label'] = 0
data.loc[idx_upper, 'Label'] = 1
分数位打标法
第三种是分位数打标法,具体做法是设定一个滚动的窗口,把窗口内的收益率划分成不同的分位数。
不同于前面完全忽视市场状态,死板把收益率阈值定死的做法,滚动窗口让我们只关注当前的市场状态,动态地将回报率分成不同的bucket,自适应地契合市场的变化。
def get_qcuts(series, quantiles):
q = pd.qcut(series, q=quantiles, labels=False, duplicates='drop')
return q[-1]
data['Label'] = data.rolling(window).apply(lambda x: get_qcuts(x, quantiles), raw=True)