8.6 多因子组合:加权、打分、排序
课前导读
本章目标
学完能解决什么困惑:理解为什么单个因子不够稳定,并能用方向统一、权重、综合分三步做出最简单的多因子打分卡。 难度:中级入门,需要理解因子、排序、pandas 派生列。 用时:约 45 分钟。
知识正文
一、从“综合成绩单”理解多因子
单因子像只看一门考试。
如果只看数学成绩,你可能会选出计算能力强的学生。
但一个学生是否适合参加综合竞赛,还要看语文表达、英语阅读、稳定性、团队合作。
投资也类似。
只看低估值,可能买到“便宜但经营变差”的公司。
只看高成长,可能买到“增长很快但价格太贵”的公司。
只看动量,可能买到“短期很强但已经过热”的股票。
多因子组合,就是把几个有逻辑、有检验记录的因子放在同一张成绩单上。
每个因子负责观察一个角度。
最后给每只股票一个综合分。
综合分不是神奇水晶球。
它只是帮助你更有纪律地排序观察对象。
关键直觉
多因子不是“因子越多越好”,而是“不同角度互相补充”。重复计算同一类信息,只会让模型看起来复杂,实际更偏科。
二、最小可用多因子只做三件事
新手不需要一开始就做复杂模型。
最小可用版多因子只做三件事。
第一,方向统一。
所有因子都要变成“分数越高越好”。
第二,分数标准化。
不同因子的单位不同,不能直接相加。
PE 是倍数,ROE 是百分比,动量也是百分比。
必须先变成可比较的分数。
第三,加权求和。
按事先写清楚的权重,把多个因子分数合成一个总分。
然后按总分从高到低排序。
flowchart TD
A[准备多个因子] --> B[确认每个因子方向]
B --> C[转换成0到100分]
C --> D[设定权重]
D --> E[计算综合分]
E --> F[按综合分排序]
F --> G[形成观察名单]这套流程的目标是形成观察名单。
它不是直接下单指令。
真正投资前,你仍然需要看风险、流动性、公告、仓位和交易计划。
三、因子方向统一:先别急着相加
方向统一是多因子最容易被忽略的一步。
举例说,ROE 越高通常越好。
过去 60 日动量越高,可能代表趋势越强。
但 PE 不一样。
在常见理解中,PE 越低越便宜。
如果你把 PE 原始值直接加入总分,就会让高 PE 股票得高分。
这显然和“低估值更好”的想法相反。
所以我们要把 PE 转成“低 PE 得高分”。
| 原始因子 | 原始方向 | 统一后的分数方向 |
|---|---|---|
| PE | 越低越便宜 | PE 越低,估值得分越高 |
| ROE | 越高盈利能力越强 | ROE 越高,质量得分越高 |
| 过去60日涨幅 | 越高短期越强 | 涨幅越高,动量得分越高 |
方向统一后,所有分数都变成同一句话:分数越高,越符合这个角度的偏好。
这时再相加才有意义。
常见误区
不要把 PE、ROE、60日涨幅这些原始数字直接相加。它们单位不同、方向不同、数量级也不同,直接相加会得到没有解释意义的结果。
四、分数标准化:用排名变成 0 到 100 分
为了让不同因子可以放在同一张表里,我们可以用排名百分位。
通俗说,就是看一只股票在当天股票池里排在什么位置。
如果某只股票 ROE 排在前 10%,质量分就应该比较高。
如果某只股票 PE 排在最低 10%,估值得分也应该比较高。
这样做有三个好处。
第一,单位统一。
不管原始因子是倍数还是百分比,最后都变成 0 到 100 分。
第二,极端值影响变小。
某只股票 PE 特别高,不会因为数值巨大直接压倒其他因子。
第三,容易解释。
你可以告诉自己:这只股票质量得分 85,说明它在同日股票池里质量位置靠前。
五、权重不要拍脑袋
权重就是每个因子在总分里占多少。
例如:质量 40%,估值 35%,动量 25%。
这并不表示质量一定永远最重要。
它只是你当前研究假设的一部分。
权重至少要有理由。
理由可以来自三类证据。
第一,投资逻辑。
如果你的目标是选择较稳健的公司,质量权重可以高一些。
第二,单因子检验。
前两节的 RankIC 和分层结果,可以帮助你判断哪些因子更稳定。
第三,风险控制。
如果某个因子波动很大,即使收益高,也不一定给过高权重。
新手最安全的起点是等权重。
例如三个因子各占三分之一。
等你积累了更多检验记录,再逐步调整。
千万不要反复调权重,只为了让历史结果最好看。
那样很容易把偶然性当成规律。
六、避免重复计算同一类信息
多因子组合不是堆越多字段越专业。
如果你同时放入 PE、PB、PS,可能三个都在表达“估值便宜不便宜”。
如果你同时放入 ROE、净利率、毛利率,可能都在表达“盈利质量”。
如果你同时放入 20 日涨幅、30 日涨幅、60 日涨幅,可能都在表达“近期强弱”。
重复信息会让某一类观点被放大。
这就像成绩单里数学算了三次,语文只算一次。
最后综合分看似客观,其实严重偏科。
所以初学者建议每类先选一个代表。
| 角度 | 可以先选的代表因子 | 暂时不要重复堆叠 |
|---|---|---|
| 估值 | PE 或 PB 选择一个 | PE、PB、PS 全部同时高权重 |
| 质量 | ROE 或经营现金流质量 | ROE、净利率、毛利率全部重复 |
| 动量 | 过去60日涨幅 | 20日、30日、60日涨幅一起重仓 |
以后你可以研究因子之间的相关性。
但本节只要求你先形成“不要重复算同一类信息”的意识。
七、A 股案例:三因子打分卡
假设你要在沪深 300 中准备一个观察名单。
你决定先用三个因子。
估值因子:PE 越低越好。
质量因子:ROE 越高越好。
动量因子:过去 60 日涨幅越高越好。
你给出的初始权重是:估值 35%,质量 40%,动量 25%。
这个权重的含义是:你更看重公司赚钱质量,其次看估值是否合理,再参考近期走势。
一张简化打分卡可以这样写:
| 股票 | 估值得分 | 质量得分 | 动量得分 | 综合分 | 排名 |
|---|---|---|---|---|---|
| 600519 贵州茅台 | 62 | 92 | 70 | 76.1 | 2 |
| 600036 招商银行 | 80 | 75 | 55 | 71.8 | 3 |
| 000333 美的集团 | 76 | 82 | 78 | 79.0 | 1 |
| 601398 工商银行 | 88 | 60 | 45 | 66.1 | 4 |
综合分的计算方式是:
以美的集团这一行为例:
这个分数说明它在这张简化表里综合排名最高。
但这不等于它一定可以买。
它只是进入下一步观察。
下一步还要检查公告、流动性、风险事件、行业环境和自己的交易计划。
八、pandas 示例:生成综合分
假设你的表格 df 包含 date、code、pe_ttm、roe、momentum_60d。
下面代码演示如何在每个日期内打分。
import pandas as pd
valid = df.dropna(subset=["pe_ttm", "roe", "momentum_60d"]).copy()
valid = valid[valid["pe_ttm"] > 0].copy()
valid["value_score"] = valid.groupby("date")["pe_ttm"].transform(
lambda s: s.rank(pct=True, ascending=False) * 100
)
valid["quality_score"] = valid.groupby("date")["roe"].transform(
lambda s: s.rank(pct=True, ascending=True) * 100
)
valid["momentum_score"] = valid.groupby("date")["momentum_60d"].transform(
lambda s: s.rank(pct=True, ascending=True) * 100
)
valid["total_score"] = (
valid["value_score"] * 0.35
+ valid["quality_score"] * 0.40
+ valid["momentum_score"] * 0.25
)
ranked = valid.sort_values(["date", "total_score"], ascending=[True, False])
watch_list = ranked.groupby("date").head(20)
print(watch_list[["date", "code", "total_score"]])逐步解释一下。
第一步,删除缺失值。
没有 PE、ROE 或动量数据的股票,暂时无法完整打分。
第二步,剔除 PE 小于等于 0 的样本。
亏损公司 PE 可能没有正常解释意义,新手先记录并排除。
第三步,估值得分用 ascending=False。
因为 PE 越低越好,所以低 PE 股票要得到更高的百分位分数。
第四步,质量和动量用 ascending=True。
因为 ROE 越高越好,过去 60 日涨幅越高也代表动量越强。
第五步,按权重求综合分。
最后取每个日期综合分前 20 名,作为观察名单。
请注意,这个名单只是研究产物。
它不是自动买入列表。
九、从老师、投资者、开发者三重视角检查
从老师视角看,你要能解释每个因子为什么放进来。
如果你说不清 PE、ROE、动量分别代表什么,就先不要组合。
从投资者视角看,你要知道综合分高不等于风险低。
高分股票也可能遇到业绩变脸、行业政策变化、流动性变差。
从量化开发视角看,你要保证每一步可复现。
同一日期、同一股票池、同一权重,应该能得到同一份排序。
如果今天手工改一下权重,明天又临时换一个因子,研究就会变成情绪驱动。
多因子最怕“看似科学,实际随意”。
所以每一次组合都要写下版本号和理由。
例如:
| 项目 | 记录 |
|---|---|
| 模型版本 | 三因子打分卡 v1 |
| 股票池 | 沪深300 |
| 因子 | PE、ROE、过去60日涨幅 |
| 权重 | 估值35%、质量40%、动量25% |
| 方向 | 全部转为分数越高越好 |
| 用途 | 生成观察名单,不直接下单 |
| 下一步 | 做单因子和分层复查 |
这张记录可以帮你避免“改过什么自己都忘了”。
交互实验室
三因子打分卡:手工完成一版
请用下面表格完成一次手工打分。
假设你已经把三个因子都转换成 0 到 100 分。
权重为:估值 35%,质量 40%,动量 25%。
| 股票 | 估值得分 | 质量得分 | 动量得分 | 综合分 | 是否进入观察名单 |
|---|---|---|---|---|---|
| A公司 | 90 | 55 | 40 | 待计算 | 待判断 |
| B公司 | 60 | 88 | 70 | 待计算 | 待判断 |
| C公司 | 75 | 72 | 82 | 待计算 | 待判断 |
| D公司 | 45 | 95 | 60 | 待计算 | 待判断 |
| E公司 | 82 | 66 | 50 | 待计算 | 待判断 |
操作步骤:
用公式计算每只股票综合分。
按综合分从高到低排序。
选择前 2 名作为观察名单。
写下为什么它们入选。
再写下一个风险提醒:它们为什么仍然不能直接买入。
你可以使用这个句式:
我选择 ____ 和 ____ 进入观察名单,因为它们综合分排名靠前。其中 ____ 的优势主要来自质量,____ 的优势主要来自估值。但这只是因子打分结果,仍需检查公告、行业和交易计划。
练习二:检查重复信息
请看下面这组因子。
- PE
- PB
- ROE
- 净利率
- 过去20日涨幅
- 过去60日涨幅
请把它们分成“估值、质量、动量”三类。
然后每类只保留一个代表因子。
写下你的选择理由。
如果你发现自己想把所有因子都放进去,请停一下。
多因子模型的第一步不是做加法,而是做取舍。
核心复盘
知识清单:
- [ ] 多因子组合是把不同角度的因子放进同一张成绩单。
- [ ] 所有因子必须先统一成“分数越高越好”。
- [ ] 不同单位的原始因子不能直接相加,应先转成排名百分位等可比较分数。
- [ ] 权重需要来自投资逻辑、检验记录或风险考虑,不能为了历史结果好看反复试出来。
- [ ] PE、PB、PS 等相似因子可能重复表达估值信息,不能盲目堆叠。
- [ ] 综合分排序只能生成观察名单,不等于买入指令。
金句总结
“多因子不是把所有理由塞进模型,而是让少数清楚的理由按同一把尺子排队。”