4. 因子组合构建:等权组合、市值加权组合、因子值加权组合
好,咱们进入实战环节了。
前面几章我们聊了怎么选因子、怎么处理数据。但说实话,那些都只是准备工作。真正决定你策略能不能赚钱的,是这一步——因子组合构建。
我个人习惯把这一步叫做「把因子变成钱」。你想想看,你辛辛苦苦算出来一堆因子值,怎么把它们变成持仓?怎么分配权重?这里面的门道,比你想的要多。
4.1 为什么组合构建这么重要?
先讲个我踩过的坑。
几年前我做了一个多因子策略,回测曲线漂亮得不行。结果实盘一跑,直接亏了三个月。我查来查去,发现问题是出在权重分配上——我用的是等权组合,但某些小市值股票在因子值上表现特别好,权重被平均掉了,导致整个组合的收益被拖垮。
嗯,从那以后我就明白了:因子选得好,不如权重分得巧。
核心观点:组合构建决定了因子暴露的纯度。权重分配不合理,再好的因子也白搭。
4.2 三种主流加权方式
咱们今天重点讲三种:等权组合、市值加权组合、因子值加权组合。这三种方式,我敢说覆盖了市面上90%以上的量化策略。
4.2.1 等权组合
等权组合,说白了就是「一碗水端平」。不管股票市值大小,不管因子值高低,只要进了选股池,大家拿一样的权重。
优点:
- 简单粗暴,容易实现
- 天然分散风险,不会过度集中在某几只股票上
- 对小市值股票友好,不会因为市值小就被边缘化
缺点:
- 忽略了因子值的信息——因子值高的股票和因子值低的股票拿一样的权重,这不合理
- 调仓频率高的时候,交易成本会比较高
- 遇到极端行情,小市值股票可能带来较大回撤
我的经验:等权组合适合做基准对比。我每次开发新策略,都会先用等权组合跑一遍,看看因子本身有没有选股能力。如果等权组合都跑不赢基准,那后面再怎么优化权重也没用。
4.2.2 市值加权组合
市值加权,就是按照股票的流通市值来分配权重。市值大的股票拿得多,市值小的拿得少。
这种方式的逻辑是:市值大的公司流动性好,交易成本低,而且不容易被操纵。
优点:
- 流动性好,大资金进出方便
- 交易成本低,滑点小
- 跟主流指数编制方式一致,容易做对比
缺点:
- 容易过度集中在几只大市值股票上
- 因子暴露不纯——你本来想买因子值高的股票,结果因为市值加权,买了一大堆因子值一般的大盘股
- 小市值股票即使因子值再好,也拿不到多少权重
注意:市值加权组合有一个隐藏陷阱——它天然偏向大盘股。如果你用的因子本身在小市值股票上表现更好,那市值加权会严重削弱因子的效果。我曾经因为这个原因,把一个年化收益20%的策略硬生生做成了10%。
4.2.3 因子值加权组合
这才是我们今天的主角。
因子值加权,就是根据因子值的大小来分配权重。因子值越高,权重越大。说白了,就是「优等生多拿资源」。
常见的加权方式:
- 线性加权:权重 = 因子值 / 因子值总和
- 平方加权:权重 = 因子值² / 因子值²总和(放大因子值差异)
- 排名加权:先对因子值排名,再用排名来算权重(减少极端值影响)
优点:
- 因子暴露最纯,能最大化利用因子信息
- 灵活性强,可以根据因子特性调整加权方式
- 理论上收益最高(如果因子有效的话)
缺点:
- 容易集中在少数几只因子值极高的股票上,风险集中
- 对因子值质量要求高——如果因子值有噪声,权重分配就会出问题
- 调仓时可能产生较大的交易成本
我的建议:因子值加权组合适合「高置信度」的因子。如果你对因子的有效性很有信心,那就大胆用因子值加权。如果还在测试阶段,建议先用等权或排名加权,保守一点。
4.3 三种方式的对比
我整理了一个表格,方便你直观对比:
| 维度 | 等权组合 | 市值加权组合 | 因子值加权组合 |
|---|---|---|---|
| 因子暴露纯度 | 低 | 低 | 高 |
| 分散程度 | 高 | 低(集中在大盘股) | 中(集中在高因子值股票) |
| 流动性 | 中 | 高 | 低(可能包含小市值) |
| 交易成本 | 中 | 低 | 高 |
| 理论收益 | 中 | 低 | 高 |
| 实现难度 | 低 | 低 | 中 |
4.4 实战代码示例
光说不练假把式。我写了一段Python代码,演示三种加权方式的实现。你直接拿去用就行。
import pandas as pd
import numpy as np
# 假设我们有一个DataFrame,包含股票代码、因子值和市值
df = pd.DataFrame({
'stock': ['A', 'B', 'C', 'D', 'E'],
'factor_value': [1.2, 0.8, 2.1, 0.5, 1.5],
'market_cap': [100, 200, 50, 300, 150] # 单位:亿
})
# 选股:取因子值排名前3的股票
df_selected = df.nlargest(3, 'factor_value')
# 1. 等权组合
df_selected['weight_equal'] = 1 / len(df_selected)
# 2. 市值加权组合
df_selected['weight_market'] = df_selected['market_cap'] / df_selected['market_cap'].sum()
# 3. 因子值加权组合(线性加权)
df_selected['weight_factor'] = df_selected['factor_value'] / df_selected['factor_value'].sum()
print("三种加权方式对比:")
print(df_selected[['stock', 'factor_value', 'market_cap',
'weight_equal', 'weight_market', 'weight_factor']])
小技巧:实际项目中,我一般不会直接用因子值做线性加权。因为因子值可能有极端值。我习惯先做一次「缩尾处理」(winsorize),把极端值拉回来,然后再算权重。这样能避免某只股票因为一次异常数据就拿到过高的权重。
4.5 知识体系结构图
下面这张图,帮你理清三种加权方式的核心逻辑:
4.6 我的选择建议
说了这么多,到底该用哪种?
我个人有个「三阶段法则」:
- 研究阶段:用等权组合。快速验证因子有没有选股能力,别在权重上浪费时间。
- 回测阶段:用因子值加权组合。最大化因子暴露,看看理论收益天花板在哪。
- 实盘阶段:用市值加权组合或因子值加权组合的改良版。考虑流动性、交易成本、风险控制等现实因素。
避坑指南:我曾经在实盘里直接用了因子值加权组合,结果遇到一只小市值股票因子值特别高,权重占了30%。结果那股票因为一则利空消息连续跌停,我整个组合回撤了8%。从那以后,我实盘都会加一个「权重上限」——单只股票权重不超过10%。
好了,这一章的内容就到这里。三种加权方式各有优劣,关键是根据你的策略阶段和风险偏好来选。记住:没有最好的加权方式,只有最合适的。