Skip to content

8.5 分层回测:把股票按因子分组看收益

课前导读

本章目标

学完能解决什么困惑:不只看一个 RankIC 数字,还能把股票按因子高低分组,观察高分组和低分组未来收益是否真的拉开差距。 难度:中级入门,需要理解 pandas 分组、排序和平均值。 用时:约 40 分钟。


知识正文

一、从“按成绩分班”理解分层回测

上一节我们用考试成绩类比 RankIC。

这一节继续用学校的例子。

假设老师想知道“入学摸底考试”是否能预测后续学习表现。

除了看排名相关,老师还可以把全班学生按摸底成绩分成 5 组。

第一组是成绩最低的 20%。

第五组是成绩最高的 20%。

然后老师观察一个学期后的平均成绩。

如果第五组平均成绩明显高于第四组,第四组高于第三组,第三组高于第二组,第二组高于第一组,那么摸底成绩很可能有参考价值。

如果五组平均成绩乱跳,说明摸底成绩的解释力不稳定。

把这个想法放到 A 股因子研究里,就是分层回测。

你把同一天的股票按因子值从低到高分成几组。

再看每一组未来一段时间的平均收益。

如果高因子组长期跑赢低因子组,因子就更值得继续研究。

关键直觉

分层回测不是为了马上做实盘,而是为了看“因子高低”能不能把未来收益分出层次。层次越清楚,因子的研究价值越高。

二、先把“回测”两个字说清楚

本节标题里有“回测”。

但这里讲的是最小版分层检验。

它只回答一个问题:按因子分组后,未来收益有没有呈现高低差?

它不处理完整交易系统里的所有细节。

比如复杂调仓、组合优化、成交排队、资金容量、实盘监控,都不是本节重点。

新手阶段先不要被“完整回测引擎”吓住。

你只需要把分层回测当成一张更有结构的研究表。

这张表把股票分为 5 个篮子。

每个篮子记录未来收益。

最后比较篮子之间是否有规律。

三、分层回测的四个术语

术语通俗解释本节用法
股票池参与比较的一批股票例如沪深300或中证500成份股
分层按因子值高低分组常用5组或10组,新手先用5组
未来收益分组后下一段时间的收益例如未来20个交易日收益
单调性组别越高收益越高,或越低收益越高判断因子是否有清晰方向

分层回测里最重要的是“同一天比较”。

你在某个观察日,把当天股票池里的所有股票按因子排序。

然后切成 5 组。

每组包含大致相同数量的股票。

接着观察这些股票未来 20 个交易日的平均收益。

再把这个过程在多个观察日重复。

最后看每一层的平均表现。

mermaid
flowchart TD
    A[选择观察日和股票池] --> B[计算每只股票因子值]
    B --> C[按因子从低到高排序]
    C --> D[切成5个分层]
    D --> E[计算每层未来收益]
    E --> F[跨多个日期求平均]
    F --> G[观察高低层差距和单调性]

四、为什么只分 5 组

你可能会问:为什么不是 3 组、10 组、20 组?

答案是:新手先用 5 组最容易看清楚。

3 组太粗,可能看不出中间变化。

10 组更细,但每组股票数量变少,结果更容易受个别股票影响。

5 组像把温度计分成“很冷、偏冷、中等、偏热、很热”。

既能看方向,又不至于太细。

在 A 股样本里,如果你用沪深 300 做股票池,每组大约 60 只股票。

这个数量对入门研究比较友好。

如果你只看 30 只股票,每组只有 6 只,结论就会脆弱很多。

五、A 股案例:低估值因子的分层观察

假设你想研究一个简单的低估值因子。

估值可以先用 PE 粗略表示。

PE 越低,代表市场价格相对公司盈利越便宜。

但为了让“因子值越高越好”,我们不直接用 PE。

我们可以定义一个 value_score

value_score 越高,代表越便宜。

例如可以用 PE 的倒数,或把 PE 从低到高排名后转换成分数。

现在你在每个月最后一个交易日,对沪深 300 成份股计算 value_score

然后把股票分成 5 层。

未来 20 个交易日后,得到类似下面的平均收益表。

分层因子含义未来20日平均收益
第1层最不便宜0.2%
第2层偏不便宜0.5%
第3层中等0.8%
第4层偏便宜1.1%
第5层最便宜1.6%

这张表给人的第一感觉是:越便宜的组,未来平均收益越高。

这就是较好的单调性。

如果你多个月份重复后仍然类似,那么低估值因子值得继续研究。

但如果只有某一个月出现这种表,不能急着下结论。

还要看更长时间、不同市场环境、不同股票池。

现实提醒

A 股里低 PE 不一定都是便宜,也可能是公司盈利突然变差前的“表面便宜”。分层结果只能说明统计关系,不能替代基本面检查。

六、pandas 最小实现

假设你已经有一张 df

每一行代表某个观察日的一只股票。

字段包括:datecodevalue_scorefuture_20d_return

目标是按 value_score 分成 5 层。

python
import pandas as pd


labels = ["第1层最低", "第2层", "第3层", "第4层", "第5层最高"]


def add_layer(one_day: pd.DataFrame) -> pd.DataFrame:
    valid = one_day.dropna(subset=["value_score", "future_20d_return"]).copy()
    if len(valid) < 50:
        valid["layer"] = pd.NA
        return valid

    ranked = valid["value_score"].rank(method="first")
    valid["layer"] = pd.qcut(ranked, 5, labels=labels)
    return valid


layered = df.groupby("date", group_keys=False).apply(add_layer)

layer_return = (
    layered.dropna(subset=["layer"])
    .groupby(["date", "layer"], observed=True)["future_20d_return"]
    .mean()
    .reset_index()
)

avg_by_layer = layer_return.groupby("layer", observed=True)["future_20d_return"].mean()
print(avg_by_layer)

这段代码分成四步。

第一步,dropna 去掉缺失数据。

没有因子值或未来收益的股票,不应该参与当期分层。

第二步,rank(method="first") 先做排名。

这样即使有多个股票因子值一样,也能稳定分组。

第三步,pd.qcut 把排名切成 5 个数量接近的组。

因为我们对排名切分,所以每层股票数量更平均。

第四步,按 datelayer 分组,计算每层未来收益平均值。

最后再跨日期求平均,就能看到 5 层的整体表现。

七、看结果时不要只看最高层

很多新手只盯着第 5 层。

如果第 5 层收益高,就说因子有效。

这不够。

专业老师会追问:第 4 层是否也比第 3 层好?第 3 层是否也比第 2 层好?

投资者会追问:最高层收益是不是由一两只暴涨股票贡献?

量化开发会追问:缺失值、停牌、ST、上市不足股票有没有处理清楚?

所以分层回测要看三件事。

第一,看单调性。

理想情况是高分层平均收益逐步高于低分层。

不一定每次都完美,但长期不应完全乱跳。

第二,看高低差。

第 5 层减第 1 层的收益差,能帮助你观察因子区分能力。

这个差值只是研究指标,不代表新手可以直接做多做空。

A 股普通投资者做空工具和限制较多,本课程不把它当成实盘方案。

第三,看持续性。

如果分层只在某一年好,其他年份都不好,因子可能依赖特殊环境。

这时应该在研究日志里写清楚,而不是强行说它有效。

八、常见错误清单

错误一:把未来收益混进分层依据。

分层只能使用观察日已经知道的因子值。

未来收益只能在分组完成后用来评价。

错误二:因子方向没有统一。

如果 PE 原始值越低越好,但你按 PE 从高到低分层,就会把最贵股票放到最高层。

这会让结论反过来。

错误三:股票池变化不记录。

今天用沪深 300,明天用全市场,结果很难比较。

错误四:忽略样本数量。

每层股票太少时,某只股票的异常涨跌会严重影响平均值。

错误五:把分层检验当成实盘收益承诺。

分层检验只说明历史样本中的统计现象。

它不承诺未来,也不等于可以直接买入最高层。

九、把分层结果写成研究结论

建议你用固定格式写结论。

例如:

在 2018 至 2023 年的沪深 300 月度样本中,低估值分数从第 1 层到第 5 层的未来 20 日平均收益整体上升,第 5 层相对第 1 层有正差值。该因子具备继续研究价值,但需要进一步检查行业影响、财报可得性和交易成本。

这段结论有三个优点。

它说明了样本范围。

它说明了观察到的现象。

它也说明了限制。

这比一句“低估值有效”专业得多。


交互实验室

练习一:10 只股票分 5 层

下面是一张练习表。

假设因子值越高越好。

请你按因子值从低到高排序,每 2 只股票分成一层。

股票因子值未来20日收益应分层
A913.2%待填写
B35-1.5%待填写
C782.0%待填写
D500.1%待填写
E660.8%待填写
F20-2.2%待填写
G884.1%待填写
H44-0.4%待填写
I590.6%待填写
J721.4%待填写

操作步骤:

  1. 找出因子最低的 2 只股票,放入第 1 层。

  2. 接着找出次低的 2 只股票,放入第 2 层。

  3. 依次完成第 3、4、5 层。

  4. 计算每层未来 20 日收益平均值。

  5. 判断收益是否从第 1 层到第 5 层逐步提高。

练习二:写一段自己的分层结论

请用下面模板完成一句研究结论。

我研究的因子是:。 股票池是:。 分层数量是:。 未来收益窗口是:。 结果显示:____。 因此我的下一步是:继续研究 / 暂缓研究 / 调整因子方向。

写完后检查两点。

第一,你有没有说明样本范围。

第二,你有没有把“历史观察”误写成“未来一定赚钱”。


核心复盘

知识清单

  • [ ] 分层回测是把股票按因子高低分组,再比较各组未来收益。
  • [ ] 新手先用 5 组即可,既能看方向,又不至于每组样本太少。
  • [ ] 好因子通常应该让高低分层呈现较清楚的收益差和一定单调性。
  • [ ] 第 5 层减第 1 层的差值是研究观察,不等于普通投资者可以直接做多做空。
  • [ ] 分层只能用当时可见的因子值,未来收益只能用于事后评价。
  • [ ] 分层检验不是完整实盘回测,不承诺未来收益。

金句总结

“RankIC 看排序像不像,分层回测看队伍之间有没有拉开距离。”

本文档仅供学习交流用途,不构成任何投资建议。股市有风险,入市需谨慎。