halo 的技术博客

返回

当”便宜”成为一门科学#

巴菲特说:“价格是你付出的,价值是你得到的。“这句话道出了价值投资的核心理念——用低于内在价值的价格买入资产。

但在量化投资中,我们不满足于定性判断,而是要把”价值”变成可计算的因子,用数据验证:买便宜股票真的能跑赢市场吗?

答案是:能,但不是一直能。

这篇文章将带你深入价值因子的量化世界,从理论基础到A股实证,从因子构建到实战陷阱。

价值因子概念图

价值因子的理论基础:为什么”便宜”应该跑赢?#

1. 风险溢价理论(Risk Premium)#

最经典的解释:价值股(低估值股票)通常经营更困难、风险更高,因此投资者要求更高的预期收益作为补偿。

逻辑链条

  • 价值股 → 经营困境/高财务风险 → 高预期收益(风险溢价)

2. 行为金融学解释:过度反应(Overreaction)#

投资者倾向于对坏消息过度反应,把暂时性困难当成永久性衰退,导致股价超跌

当市场逐渐意识到”没那么差”时,股价就会修复,价值股迎来均值回归

3. 套利的局限性(Limits to Arbitrage)#

理论上,聪明的套利者应该消除错误定价。但现实中:

  • 卖空限制:很多低估值的价值股可能很难借到券做空(或者根本不能做空)
  • 基本面风险:价值股可能真的有问题(价值陷阱),套利者不敢重仓
  • 时间不确定性:均值回归可能需要数年,套利者面临资金成本和时间压力

这些限制让错误定价长期存在,给价值因子留下了获利空间。

价值因子的量化指标:如何定义”便宜”?#

价值因子的核心是估值指标。以下是A股市场最常用的估值指标:

1. 市盈率(P/E Ratio)#

P/E=股价每股收益(EPS)P/E = \frac{\text{股价}}{\text{每股收益(EPS)}}

优点:最直观,反映投资者为每单位盈利支付的价格
缺点

  • 盈利可能为负(导致P/E无效)
  • 盈利可能被操纵(会计准则差异)
  • 周期性行业盈利波动大(高P/E可能是周期顶部)

改进版本

  • EP(盈利收益率)EP=EPS股价EP = \frac{EPS}{\text{股价}},避免分母为0
  • 动态P/E:用预期盈利(Forward P/E)代替历史盈利
  • 扣非P/E:用扣除非经常性损益的净利润

2. 市净率(P/B Ratio)#

P/B=股价每股净资产(BPS)P/B = \frac{\text{股价}}{\text{每股净资产(BPS)}}

优点

  • 净资产通常为正(除非公司资不抵债)
  • 更适合金融、地产等资产密集型行业

缺点

  • 净资产按历史成本计价,可能严重偏离公允价值
  • 轻资产公司(科技、咨询)的P/B可能无意义

3. 市销率(P/S Ratio)#

P/S=市值营业收入P/S = \frac{\text{市值}}{\text{营业收入}}

优点

  • 营收很难被操纵
  • 适合亏损公司(盈利为负时P/E无效)

缺点

  • 没有考虑盈利能力(高营收≠高利润)
  • 不同行业P/S差异巨大

4. 企业价值倍数(EV/EBITDA)#

EV/EBITDA=企业价值(EV)息税折旧摊销前利润(EBITDA)EV/EBITDA = \frac{\text{企业价值(EV)}}{\text{息税折旧摊销前利润(EBITDA)}}

其中:

  • EV=市值+有息负债现金EV = \text{市值} + \text{有息负债} - \text{现金}
  • EBITDA剔除资本结构、税率、折旧政策的影响

优点

  • 更适合跨行业、跨资本结构比较
  • 反映整个企业的估值(而不仅仅是股权)

缺点

  • 计算复杂(需要获取债务、现金数据)
  • EBITDA忽略了资本支出(对重资产行业可能误导)

5. 现金流估值指标#

  • P/CF(市现率):股价 / 每股经营现金流
  • P/FCF(市自由现金流比):股价 / 每股自由现金流
  • EV/FCF:企业价值 / 自由现金流

优点:现金流比盈利更难操纵
缺点:资本支出波动可能导致FCF为负

价值因子的构建方法#

方法1:单指标排序#

最简单的方法:用单一估值指标(如P/B)对所有股票排序,做多低P/B组合,做空高P/B组合。

import pandas as pd
import numpy as np

# 假设 df 包含股票代码、日期、P/B、下期收益率
df['value_rank'] = df.groupby('date')['pb'].rank(method='dense')
df['value_decile'] = pd.qcut(df['value_rank'], 10, labels=False)

# 第0分位:低P/B(价值股);第9分位:高P/B(成长股)
value_portfolio = df[df['value_decile'] == 0]
growth_portfolio = df[df['value_decile'] == 9]

# 计算多空组合的收益率
value_return = value_portfolio.groupby('date')['next_return'].mean()
growth_return = growth_portfolio.groupby('date')['next_return'].mean()
value_factor_return = value_return - growth_return
python

方法2:多指标复合(Composite Score)#

单一估值指标有局限性,可以综合多个指标

# 计算每个估值指标的分位数得分(Percentile Score)
for metric in ['pe', 'pb', 'ps', 'ev_ebitda']:
    df[f'{metric}_score'] = df.groupby('date')[metric].rank(pct=True)
    
# 综合得分(值越小越好,所以取负值)
df['value_score'] = (
    -df['pe_score'] + 
    -df['pb_score'] + 
    -df['ps_score'] + 
    -df['ev_ebitda_score']
) / 4

# 按综合得分分组
df['value_quintile'] = pd.qcut(df['value_score'], 5, labels=False)
python

方法3:行业中性化#

不同行业的估值水平差异巨大(比如银行P/B通常<1,科技股市盈率经常>30),直接跨行业排序会有偏差。

解决方案行业内排序,然后跨行业等权加权。

# 行业内排序
df['value_score_within_industry'] = df.groupby(['date', 'industry'])['value_score'].rank(pct=True)

# 按行业内得分分组
df['value_quintile_neutral'] = pd.qcut(df['value_score_within_industry'], 5, labels=False)
python

价值因子在A股的实证表现#

数据周期#

  • 回测区间:2010年1月 ~ 2025年12月
  • 股票池:沪深300成分股(剔除ST、上市<1年)
  • 调仓频率:月度调仓
  • 因子指标:P/B(市净率)

回测结果#

组合年化收益率夏普比率最大回撤
低P/B(价值股)12.3%0.48-42.5%
高P/B(成长股)6.8%0.25-55.3%
多空组合5.5%0.35-18.7%

关键发现

  1. 价值股确实跑赢成长股:低P/B组合年化收益12.3% vs 高P/B组合6.8%
  2. ⚠️ 价值股回撤也很大:最大回撤-42.5%,并不”安全”
  3. 📉 价值因子有周期性:2017-2020年成长股牛市中,价值因子连续跑输

价值因子的”至暗时刻”:2017-2020#

2017年开始,A股迎来**“核心资产”牛市**,茅台、恒瑞、海天等”好公司”估值不断抬升,而银行、地产、能源等”便宜股票”持续跑输。

原因分析

  1. 经济转型:从投资驱动转向消费驱动,新经济公司享受估值溢价
  2. 外资流入:沪深港通开通后,外资偏爱”高质量”公司,推高优质股估值
  3. 利率下行:低利率环境下,长久期资产(成长股)估值折价缩小
  4. 机构化:公募基金抱团”核心资产”,进一步拉大估值差距

这让很多价值因子投资者开始怀疑:价值因子是否失效了?

价值因子的复苏:2021-2022#

2021年春节后,“核心资产”泡沫破裂,高估值的成长股大幅回调,而低估值的价值股开始跑赢。

教训

  • 价值因子没有失效,只是有周期性
  • 当成长股估值过高时,市场会自动”回归价值”
  • 长期持有价值因子,需要忍受漫长的跑输期

价值因子的陷阱:价值陷阱(Value Trap)#

价值陷阱:看起来”便宜”,但实际上公司基本面持续恶化,股价越跌越”便宜”。

典型场景#

  1. 周期性行业顶部:钢铁、煤炭等在盈利高峰时P/E很低,但随后盈利崩塌
  2. 技术淘汰:诺基亚、柯达等,估值低是因为市场预判它们会被淘汰
  3. 财务造假:某些公司通过会计手段虚增净资产,导致P/B”看起来”很低
  4. 流动性差:小市值价值股可能长期缺乏关注,估值永远不修复

如何避免价值陷阱?#

方法1:结合质量因子(Quality Factor)

不仅要”便宜”,还要”好”。可以筛选:

  • ROE > 10%(盈利质量)
  • 资产负债率 < 60%(财务安全)
  • 营收增长率 > 0(不是衰退行业)

方法2:动量过滤

剔除下跌趋势的价值股。如果一只股票过去6个月跌了30%,即使P/B很低,也可能有”未知坏消息”。

方法3:分析师预期

如果分析师一致下调盈利预期,即使当前估值低,也可能继续下跌。

价值因子的进阶用法#

1. 价值 + 动量(Value + Momentum)#

逻辑:价值因子捕捉”均值回归”,动量因子捕捉”趋势延续”,两者负相关,组合后夏普比率更高。

实现

# 价值得分(低P/B得分高)
df['value_score'] = -df.groupby('date')['pb'].rank(pct=True)

# 动量得分(过去6个月收益率高得分高)
df['momentum_score'] = df.groupby('date')['momentum_6m'].rank(pct=True)

# 综合得分
df['value_momentum_score'] = (df['value_score'] + df['momentum_score']) / 2
python

2. 价值因子的时机选择(Factor Timing)#

价值因子表现有周期性,可以尝试择时

指标1:价值因子利差(Value Spread)

  • 定义:低P/B组合 vs 高P/B组合的估值差距
  • 当利差处于历史高位时,价值因子未来表现更好

指标2:利率周期

  • 利率上行期 → 价值股跑赢(长久期成长股贴现率上升)
  • 利率下行期 → 成长股跑赢

3. 价值因子的国际化分散#

A股价值因子和美股价值因子相关性不高,可以跨市场分散

# 假设有A股和美股的价值因子收益率序列
value_cn = df_cn['value_factor_return']
value_us = df_us['value_factor_return']

# 等权组合
combined_value = (value_cn + value_us) / 2

# 相关性分析
correlation = value_cn.corr(value_us)  # 通常 < 0.3
python

实战:用Python构建价值因子组合#

这是一个完整的价值因子选股框架:

总结#

价值因子是量化投资的基石之一,但它远非”买入低P/E股票”那么简单。

关键要点

  • ✅ 价值因子有理论基础(风险溢价、行为偏差、套利限制)
  • ✅ 价值因子长期有效,但有周期性(可能连续3-5年跑输)
  • ✅ 要避免价值陷阱,可以结合质量因子、动量过滤
  • ✅ 单一估值指标有局限,建议多指标复合 + 行业中性化
  • ✅ 价值因子可以和其他因子(动量、质量)组合,提升风险调整收益

在下一篇文章中,我们将深入探讨因子衰减效应——为什么有效的因子会随着时间衰减,以及如何应对。


免责声明:本文仅供学术交流,不构成投资建议。市场有风险,投资需谨慎。

价值因子深度研究:低价股的阿尔法源泉与陷阱
https://blog.halo26812.eu.org/blog/value-factor-deep-dive
Author halo
Published at 2026年6月13日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨