🚀 AI 一键生成 joinquant 策略代码

聚宽API因子做市值中性化后,为什么归因分析中市值暴露度依然很大?

joinquant | 发布时间: 2026/5/27
以下内容由 EasyQuant 生成。

问题描述

聚宽API上的中性化函数问题

我用roe同比和环比参数依次用聚宽api的函数做了去极值,对行业和市值中性化,标准化后,取因子打分前五的股票回测
按理来说做了对行业中性化之后,在归因分析中的因子分析中,对于市值的暴露度应该是很小的,但是实际暴露度还是很大(-1.81),这种现象是正常的么?

解决方案

您好!这种现象在量化回测中是非常正常且常见的。

虽然您使用了聚宽的 neutralize 函数对因子进行了行业和市值中性化,但最终归因分析中市值暴露度依然很大(-1.81,说明严重偏向小盘股),主要由以下几个原因导致:

1. Top N 选股的“截断效应”(最核心原因)

neutralize 函数的数学本质是线性回归。它保证的是在整个股票池的截面上,处理后的因子值与市值、行业因子的相关性为 0(即均值为0,正交)。
但是,当您只选取“打分前五”的股票时,您破坏了这种全样本的正交性。极高 ROE 增长的股票在现实中往往集中在小市值公司中。即使在全样本中剔除了市值的线性影响,排名前 5 的极端样本依然极大概率是小盘股。中性化保证的是全市场中性,而不是 Top 5 样本中性。

2. 股票池与归因基准的错配

归因分析中的风险暴露度是相对于**基准(通常是沪深300或中证500)**来计算的。
如果您是在“全A股”中进行的市值中性化,全A股的平均市值远小于沪深300。您选出的前5只股票,其市值可能符合全A股的平均水平,但相对于沪深300(大盘股集合)来说,依然会呈现出极大的负市值暴露(-1.81)。

3. 线性剔除无法解决非线性聚集

neutralize 只能剔除因子与市值之间的线性相关性。如果 ROE 增速与市值存在强烈的非线性关系(例如:只有市值小于50亿的公司,ROE增速才可能突破某个极高阈值),线性中性化后,打分最高的依然会是这些小市值公司。


如何解决或改善这个问题?

如果您希望您的最终持仓真正实现“市值中性”(即市值暴露度接近于0),单靠对因子值做 neutralize 然后 Top N 选股是做不到的。建议采用以下方法:

方法一:使用聚宽的组合优化器(推荐)

不要直接取 Top 5 等权买入,而是将选出的股票池(可以扩大到前50或100只)放入聚宽的 portfolio_optimizer 中,并加入风险暴露限制 BarraConstraintExposureConstraint

from jqlib.optimizer import portfolio_optimizer, BarraConstraint

# 限制市值暴露在 [-0.1, 0.1] 之间
constraint = BarraConstraint(size=[-0.1, 0.1])

# 目标为最大化您的因子打分
target = MaxScore(scores=your_factor_scores)

# 求解最优权重
optimized_weight = portfolio_optimizer(date=context.previous_date, 
                                       securities=stock_pool, 
                                       target=target, 
                                       constraints=[constraint])

方法二:扩大选股数量并分层

只选 5 只股票的偶然性太大,无法体现统计学上的中性。建议扩大选股数量(如选前 10% 的股票),或者在每个市值分层、每个行业内部去分别选取 Top N,这样构建的组合在市值和行业上的分布才会更接近基准。

方法三:统一股票池

确保您做中性化时的股票池(如 沪深300成分股)与您归因分析的基准完全一致。如果在沪深300内部做中性化并选股,市值暴露的偏差会显著减小。