在量化因子研究领域,除了传统的收益与风险指标,市场流动性及其协同变化也逐渐成为挖掘阿尔法的关键维度。近期,兴业证券郑兆磊老师在一篇高频流动性因子研报中系统性地介绍了一类名为APBeta的因子。这类因子旨在捕捉个股与市场整体在收益率和流动性变化上的协同性,为因子库提供了新的思路。本文将从公式推导、代码实现出发,并结合详细的绩效分析,探讨其中一种特别的因子构造方式——将两个高相似性因子做差后,其分层回测表现得到了显著提升。
APBeta因子的定义与计算逻辑
原研报共定义了四个APBeta因子(APBeta1至APBeta4),它们具有相似的数学结构,但关注的协同关系各有侧重。其核心公式基于协方差与方差的比率构建,具体定义如下:
APBeta1 = Σ(Ri,t - R̄i,t)(Rm,t - R̄m,t) / Σ(Rm,t - ΔAmihud_ILLIQm,t - (Rm,t - ΔAmihud_ILLIQm,t))²
APBeta2 = Σ(ΔAmihud_ILLIQi,t - ΔAmihud_ILLIQ̄i,t)(Rm,t - R̄m,t) / Σ(Rm,t - ΔAmihud_ILLIQm,t - (Rm,t - ΔAmihud_ILLIQm,t))²
APBeta3 = Σ(Ri,t - R̄i,t)(ΔAmihud_ILLIQm,t - ΔAmihud_ILLIQ̄m,t) / Σ(Rm,t - ΔAmihud_ILLIQm,t - (Rm,t - ΔAmihud_ILLIQm,t))²
APBeta4 = Σ(ΔAmihud_ILLIQi,t - ΔAmihud_ILLIQ̄i,t)(ΔAmihud_ILLIQm,t - ΔAmihud_ILLIQ̄m,t) / Σ(Rm,t - ΔAmihud_ILLIQm,t - (Rm,t - ΔAmihud_ILLIQm,t))²
其中:
Ri,t 表示股票 i 在时间 t 的收益率。
Rm,t 表示全市场在时间 t 的收益率。
ΔAmihud_ILLIQi,t 和 ΔAmihud_ILLIQm,t 分别代表个股和全市场层面的Amihud非流动性指标的变化率。
- 上横线(如
R̄i,t)表示在计算窗口内的样本均值。
这四个指标在构造上具有一致性,但经济含义不同:
- APBeta1 和 APBeta4 分别度量个股与市场在收益率、流动性变化上的协同性。
- APBeta2 和 APBeta3 则分别度量市场涨跌时个股流动性的协同变化,以及市场流动性变化时个股收益的协同表现。
值得注意的是,APBeta4 的构造与前文常见的流动性贝塔(Liqbeta)因子高度相似,实际测算中两者相关性超过0.95,因此后续分析可将其视为同一因子。原研报主要对APBeta4进行了深入探究。然而,在笔者进行的实证测试中发现,APBeta1 和 APBeta3 在特定合成方式下展现出了更值得关注的特性。
Python代码实现
在计算时,我们使用成交额(money)、成交量(vol)和换手率(tr)分别计算Amihud非流动性指标,因此最终得到6个基础因子:ap_beta1_vol, ap_beta3_vol, ap_beta1_money, ap_beta3_money, ap_beta1_tr, ap_beta3_tr。以下为关键计算函数的核心代码:
def process_single_day(self, idx):
file_name = self.files[idx]
date_str = file_name.split('.')[0]
if idx < 243 or pd.to_datetime(date_str) >= pd.to_datetime('2026-01-01'):
return pd.DataFrame({})
full_path = os.path.join(self.file_pth, file_name)
data = BaseDataLoader.load_data(full_path, fields=['volume', 'close', 'open', 'turnover'])
rtn = data.to_dataframe('close') / data.to_dataframe('open') - 1
vol = data.to_dataframe('volume')
money = data.to_dataframe('turnover')
data.to_dataframe('volume')
tmp_cap = self.cap.iloc[idx - 243].reindex(data.codes)
tr = vol / tmp_cap.values.reshape(1, -1)
vol = (np.log(rtn.abs() / vol)).diff()
money = (np.log(rtn.abs() / money)).diff()
tr = (np.log(rtn.abs() / tr)).diff()
res = []
for data in [vol, money, tr]:
tmp = data.replace(np.inf, np.nan)
tmp = tmp.replace(-np.inf, np.nan)
mkt_vol = tmp.mean(axis=1)
mkt_rtn = rtn.mean(axis=1)
denominator = (np.square(mkt_rtn - mkt_vol - (mkt_rtn.mean() - mkt_vol.mean()))).sum()
ap_beta1 = (rtn - rtn.mean().values.reshape(1, -1)) * ((mkt_rtn - mkt_rtn.mean()).values.reshape(-1, 1))
ap_beta1 = ap_beta1.sum()/ denominator
# ap_beta2 = (tmp - tmp.mean().values.reshape(1, -1)) * ((mkt_rtn - mkt_rtn.mean()).values.reshape(-1, 1))
# ap_beta2 = ap_beta2.sum() / denominator
ap_beta3 = (rtn - rtn.mean().values.reshape(1, -1)) * ((mkt_vol- mkt_vol.mean()).values.reshape(-1, 1))
ap_beta3 = ap_beta3.sum()/ denominator
res.append(ap_beta1)
res.append(ap_beta3)
#
# ap_beta4 = (tmp - tmp.mean().values.reshape(1, -1)) * ((mkt_vol- mkt_vol.mean()).values.reshape(-1, 1))
# ap_beta4 = ap_beta4.sum() / denominator
res = pd.concat(res, axis=1)
res.columns = ['ap_beta1_vol', 'ap_beta3_vol', 'ap_beta1_money', 'ap_beta3_money', 'ap_beta1_tr', 'ap_beta3_tr']
res['datetime'] = pd.to_datetime(date_str) + timedelta(hours=15)
return res
代码严格遵循公式定义,依次计算不同流动性度量下的APBeta1和APBeta3因子。在因子合成阶段,测试发现对原始因子序列进行平滑或波动率调整会产生不同效果。
因子评价与绩效分析
首先观察六个基础因子的相关性。一个明显的规律是:所有三个APBeta1因子(ap_beta1_vol, ap_beta1_money, ap_beta1_tr)彼此之间的相关性为1.0;所有三个APBeta3因子彼此之间的相关性也为1.0;而任意一个APBeta1因子与任意一个APBeta3因子之间的相关性稳定在0.5左右。这种高相关性模式提示我们,或许可以通过因子间的线性组合来挖掘更有效的信息。
在测试了多种合成方法(如滚动标准差、滚动均值)后,发现ap_beta3_money因子经过21日滚动标准差合成后,IC(信息系数)表现最佳。然而,本文重点探讨的是一个IC并非最高,但分层回测表现更为突出的组合因子:使用过去21个交易日的均值合成的 ap_beta1_money 减去 ap_beta1_tr。
1. IC分析
该组合因子的IC表现整体一般。其Rank IC时间序列在零轴附近宽幅震荡,21日移动平均线稍显平滑但同样围绕零轴波动。IC累加曲线显示,最大累计IC和最小累计IC均长期处于负值区域,并未形成稳定的向上趋势。
从分年度和分月度视角看:
- 年度IC均值:2018至2024年间均为负值,范围在-0.01至-0.045之间,其中2021年最低。
- 月度IC均值:不同年份各月份的IC均值波动较大,未表现出稳定的月度季节性规律。
- 年度ICIR:同样在所有年份均为负值,表明因子稳定性欠佳。
2. 因子收益率分析
因子收益率(做多因子值最大组、做空最小组)的时间序列波动剧烈。其21日移动平均线虽然平滑了部分噪音,但整体仍呈震荡格局。因子收益率的累加曲线在测试期内(约80天)经历了显著回撤后有所回升,但未呈现长期稳健的上升趋势。
3. 换手率分析
在分组回测中,该因子的换手率特征如下:
- 平均换手率:五个组别(group_0到group_4,group_0为因子值最小组)的换手率在0.60到0.75之间。中间组(group_2和group_3)的换手率相对更高。
- 平均行业换手率:各组在不同行业间的调整频率在0.22到0.25之间,组间差异不大。
4. 分层回测表现
尽管IC等传统评价指标不突出,但该组合因子在分层回测中展现了良好的单调性和区分度。
- 纯多头分层:从2018年到2025年,五条净值曲线呈现出清晰的单调排序。因子值最大的group_4组合累计收益最高,group_3次之,依此类推,因子值最小的group_0组合收益最低。各组曲线分离明显,未出现交叉。
- 多空对冲组合:做多group_4、做空group_0的多空组合净值曲线在大部分时间里显著高于其他组间对冲组合(如group_3-group_0),进一步验证了因子的选股能力。
作为对比,IC表现更优的ap_beta3_money(21日标准差合成)在分层回测中呈现出不同的特征:其净值曲线表现为中间组(group_2)的表现最佳,两端组(group_0和group_4)的表现反而较弱,单调性不及前述的组合因子。
结论与思考
本次实践揭示了一个有趣的现象:两个高度相似(相关性为1)的因子ap_beta1_money和ap_beta1_tr,在经过简单的差值运算后,其分层回测的单调性与区分度得到了显著提升,尽管其IC等传统指标并未同步改善。这提示在因子研究与组合构建中,除了关注单个因子的统计特性,因子间的代数组合可能挖掘出更深层次的风险收益特征。
值得注意的是,这种“化腐朽为神奇”的效果可能具有一定的偶然性或过拟合风险。例如,使用ap_beta3_money - ap_beta3_tr或ap_beta1_money - ap_beta1_vol进行同样的操作,并未获得同等优异的回测结果。这要求我们在欣喜之余保持谨慎。最终的结论需要样本外数据的持续验证,例如观察该组合因子在2025年及之后的表现。
此外,研报中定义的APBeta2和APBeta4因子未在本文代码中实现,它们是否也存在类似的“减法则”优化空间,是一个值得读者自行探索的方向。量化因子的研究与创新,正是在不断试错、验证与思考中向前推进的。
参考资料
[1] apbeta因子,一大堆相似性很高的因子相减之后,分层回测再次炸裂提升!, 微信公众号:mp.weixin.qq.com/s/JQV1aEJ7cTC74ebJiKpaZA
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。