4. 因子计算:以市盈率(PE)、市净率(PB)为例,计算基础估值因子
好,咱们进入实战环节了。前面聊了那么多因子逻辑和框架,现在该动手算一算了。我个人习惯,学任何量化策略,先从最基础的估值因子入手。为什么?因为估值因子最直观,也最不容易出错。
今天咱们就拿市盈率(PE)和市净率(PB)开刀。这两个指标,说白了就是看一家公司到底贵不贵。你想想看,买菜都知道挑便宜的,买股票其实也一样。
4.1 市盈率(PE)的计算与处理
市盈率的公式很简单:PE = 股价 / 每股收益。但实际项目中,坑可不少。
我记得第一次做多因子模型时,直接从数据库拉了一堆PE数据就跑回测。结果呢?回测曲线漂亮得不像话,一上实盘就崩。后来排查了半天,发现是PE数据里混进了负值——有些公司亏损,每股收益是负数,PE就成了负的。负PE在因子模型里就是个灾难。
处理方式我一般有两种:
- 直接剔除: 把PE为负的股票从样本中拿掉。适合样本量大的情况。
- 截断处理: 设定一个上下限,比如PE在0到100之间。超出部分强制设为边界值。
来看代码实现:
import pandas as pd
import numpy as np
# 假设df是包含股票PE数据的DataFrame
def clean_pe(df, pe_col='pe_ttm'):
"""
清洗PE数据
"""
# 剔除负值
df = df[df[pe_col] > 0].copy()
# 截断处理:去掉极端值
lower = df[pe_col].quantile(0.01)
upper = df[pe_col].quantile(0.99)
df[pe_col] = df[pe_col].clip(lower, upper)
# 标准化:Z-score
mean = df[pe_col].mean()
std = df[pe_col].std()
df['pe_zscore'] = (df[pe_col] - mean) / std
return df
4.2 市净率(PB)的计算与处理
PB的公式:PB = 股价 / 每股净资产。这个指标在金融、地产行业特别管用。为什么?因为这些行业资产重,净资产能真实反映公司价值。
但PB也有坑。我记得有一次做银行股因子,发现PB特别低的银行反而表现不好。后来一查,原来是这些银行的不良贷款率太高,净资产里水分很大。所以,PB不能只看数字,还得结合资产质量。
PB的处理逻辑和PE类似:
def clean_pb(df, pb_col='pb_lf'):
"""
清洗PB数据
"""
# PB一般不会为负,但也要检查
df = df[df[pb_col] > 0].copy()
# 行业中性化处理
# 不同行业的PB差异巨大,直接比较没意义
df['pb_industry_median'] = df.groupby('industry')[pb_col].transform('median')
df['pb_relative'] = df[pb_col] / df['pb_industry_median']
# 标准化
mean = df['pb_relative'].mean()
std = df['pb_relative'].std()
df['pb_zscore'] = (df['pb_relative'] - mean) / std
return df
核心要点: 估值因子一定要做行业中性化处理。不同行业的PE、PB天然不同,科技股PE普遍高,银行股PB普遍低。如果不做行业中性化,你的因子选出来的全是行业偏好,而不是真正的估值优势。
4.3 估值因子的合成
单因子不够稳定,我习惯把PE和PB合成一个综合估值因子。合成方式有很多种,这里介绍最常用的等权合成:
def combine_value_factor(df):
"""
合成综合估值因子
"""
# 等权合成
df['value_factor'] = (df['pe_zscore'] + df['pb_zscore']) / 2
# 再次标准化
mean = df['value_factor'].mean()
std = df['value_factor'].std()
df['value_factor_std'] = (df['value_factor'] - mean) / std
return df
你可能会问:为什么是等权?其实不一定。我在项目中试过动态权重,效果时好时坏。对于初学者,等权是最稳妥的选择。等权意味着我们不主观判断哪个因子更重要,让数据自己说话。
4.4 本章知识体系
下面这张图展示了估值因子计算的核心流程,我画得比较简洁,但每一步都很关键:
4.5 实战中的注意事项
嗯,这里要特别强调几点:
- 数据频率要统一。 我见过有人用日频的股价和周频的财报数据算PE,结果对不上。建议统一用日频数据,财报数据用最新一期。
- 注意财报发布日期。 财报数据是有滞后性的。比如4月底才发一季报,但你用3月份的股价去算PE,用的还是去年的数据。这会导致因子失真。
- 不要过度优化。 有些新手喜欢给因子加各种变换,什么对数变换、平方变换。其实对于估值因子,简单的Z-score就够了。过度优化容易过拟合。
好了,估值因子的计算就讲到这里。PE和PB是最基础的,但也是最实用的。你把这个流程跑通了,后面学其他因子就会轻松很多。