跳到主要内容

因子投资基础

因子投资是现代量化投资的核心方法论,通过识别和组合影响资产收益的共同因子来构建投资组合。本章将介绍因子投资的基本概念、常用因子和因子分析方法。

因子投资概述

什么是因子?

因子是影响资产收益的共同驱动因素。不同资产对同一因子的敏感度不同,这种敏感度称为因子暴露。

以最简单的市场因子为例:股票收益可以分解为市场收益和个股特异收益。市场因子反映了整体市场的系统性风险,所有股票都受其影响,但影响程度不同。Beta系数就是股票对市场因子的暴露度。

因子投资的核心思想是:资产的收益可以被有限数量的因子所解释。通过理解这些因子,我们可以更好地预测收益、管理风险、构建投资组合。

因子的分类

风格因子:反映资产特征的风格维度,是最常用的因子类型。

  • 价值因子:估值较低的股票倾向于获得超额收益
  • 动量因子:过去表现好的股票倾向于继续表现好
  • 质量因子:财务稳健的公司倾向于获得超额收益
  • 规模因子:小市值股票倾向于跑赢大市值股票
  • 波动因子:低波动股票风险调整后收益更高

宏观因子:反映宏观经济环境的影响。

  • 增长因子:GDP增长、工业产出等
  • 通胀因子:CPI、PPI等
  • 利率因子:国债收益率、利差等
  • 流动性因子:货币供应量、信用利差等

另类因子:基于非传统数据构建的因子。

  • 情绪因子:投资者情绪、分析师预期等
  • 网络因子:搜索热度、社交媒体讨论等
  • 卫星数据:零售客流、油罐储量等

经典因子模型

CAPM模型

资本资产定价模型(CAPM)是最简单的因子模型,只有一个市场因子。

公式:E(Ri)=Rf+βi(E(Rm)Rf)E(R_i) = R_f + \beta_i (E(R_m) - R_f)

其中 RfR_f 是无风险利率,E(Rm)RfE(R_m) - R_f 是市场风险溢价,βi\beta_i 是股票对市场因子的敏感度。

import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression

def calculate_beta(stock_returns, market_returns):
"""
计算股票Beta

参数:
stock_returns: 股票收益率序列
market_returns: 市场收益率序列

返回:
Beta值
"""
X = market_returns.values.reshape(-1, 1)
y = stock_returns.values

model = LinearRegression()
model.fit(X, y)

return model.coef_[0]

def calculate_alpha(stock_returns, market_returns, risk_free_rate):
"""
计算Jensen's Alpha

参数:
stock_returns: 股票收益率序列
market_returns: 市场收益率序列
risk_free_rate: 无风险利率

返回:
Alpha值
"""
excess_returns = stock_returns - risk_free_rate
market_excess = market_returns - risk_free_rate

X = market_excess.values.reshape(-1, 1)
y = excess_returns.values

model = LinearRegression()
model.fit(X, y)

return model.intercept_

Fama-French三因子模型

Fama和French在CAPM基础上增加了规模因子和价值因子,形成三因子模型。

公式:RiRf=α+βMKT(RmRf)+βSMBSMB+βHMLHML+ϵR_i - R_f = \alpha + \beta_{MKT}(R_m - R_f) + \beta_{SMB}SMB + \beta_{HML}HML + \epsilon

其中:

  • SMB(Small Minus Big):规模因子,小市值组合收益减大市值组合收益
  • HML(High Minus Low):价值因子,高账面市值比组合收益减低账面市值比组合收益
def fama_french_regression(stock_returns, market_returns, smb_returns, hml_returns, risk_free_rate):
"""
Fama-French三因子回归

参数:
stock_returns: 股票收益率
market_returns: 市场因子
smb_returns: 规模因子
hml_returns: 价值因子
risk_free_rate: 无风险利率

返回:
回归结果字典
"""
excess_returns = stock_returns - risk_free_rate
market_excess = market_returns - risk_free_rate

X = np.column_stack([
market_excess.values,
smb_returns.values,
hml_returns.values
])
y = excess_returns.values

model = LinearRegression()
model.fit(X, y)

return {
'alpha': model.intercept_,
'beta_market': model.coef_[0],
'beta_smb': model.coef_[1],
'beta_hml': model.coef_[2],
'r_squared': model.score(X, y)
}

五因子模型

Fama和French后来又增加了盈利因子和投资因子,形成五因子模型。

公式:RiRf=α+βMKT(RmRf)+βSMBSMB+βHMLHML+βRMWRMW+βCMACMA+ϵR_i - R_f = \alpha + \beta_{MKT}(R_m - R_f) + \beta_{SMB}SMB + \beta_{HML}HML + \beta_{RMW}RMW + \beta_{CMA}CMA + \epsilon

其中:

  • RMW(Robust Minus Weak):盈利因子,高盈利组合收益减低盈利组合收益
  • CMA(Conservative Minus Aggressive):投资因子,低投资组合收益减高投资组合收益

常用因子构建

价值因子

价值因子基于估值指标构建,核心假设是估值低的股票被低估,未来会有更好的表现。

常用的估值指标:

  • 市盈率(P/E):股价/每股收益
  • 市净率(P/B):股价/每股净资产
  • 市销率(P/S):市值/营业收入
  • 企业价值倍数(EV/EBITDA):企业价值/息税折旧摊销前利润
def build_value_factor(df):
"""
构建价值因子

参数:
df: 包含估值指标的DataFrame

返回:
价值因子得分(越高越便宜)
"""
# 方法1:单一指标
value_factor = 1 / df['PE'] # PE倒数,越大越便宜

# 方法2:多指标综合
# 先标准化各指标
df['PE_score'] = (df['PE'] - df['PE'].mean()) / df['PE'].std()
df['PB_score'] = (df['PB'] - df['PB'].mean()) / df['PB'].std()
df['PS_score'] = (df['PS'] - df['PS'].mean()) / df['PS'].std()

# 综合得分(负号表示越低越便宜)
value_factor = -(df['PE_score'] + df['PB_score'] + df['PS_score']) / 3

return value_factor

动量因子

动量因子基于历史价格表现构建,核心假设是过去表现好的股票会继续表现好。

常用的动量指标:

  • 过去N个月收益率(排除最近一个月,避免短期反转)
  • 相对强度指标
  • 价格动量排名
def build_momentum_factor(prices, lookback=12, skip=1):
"""
构建动量因子

参数:
prices: 价格序列(DataFrame,每列一只股票)
lookback: 回看期(月)
skip: 跳过最近N月(避免短期反转)

返回:
动量因子得分
"""
# 计算过去lookback个月收益,跳过最近skip个月
# 假设数据是日频,转换为月度
monthly_prices = prices.resample('M').last()

# 动量 = (P_t / P_{t-lookback-skip}) - 1
momentum = monthly_prices.shift(skip) / monthly_prices.shift(lookback + skip) - 1

return momentum

质量因子

质量因子基于财务质量指标构建,核心假设是财务稳健的公司更有可能获得超额收益。

常用的质量指标:

  • ROE(净资产收益率)
  • ROA(总资产收益率)
  • 毛利率、净利率
  • 资产负债率
  • 经营现金流/净利润
def build_quality_factor(df):
"""
构建质量因子

参数:
df: 包含财务指标的DataFrame

返回:
质量因子得分
"""
# 标准化各指标
df['ROE_score'] = (df['ROE'] - df['ROE'].mean()) / df['ROE'].std()
df['ROA_score'] = (df['ROA'] - df['ROA'].mean()) / df['ROA'].std()
df['Margin_score'] = (df['NetMargin'] - df['NetMargin'].mean()) / df['NetMargin'].std()

# 低负债率得分高
df['Leverage_score'] = -(df['DebtRatio'] - df['DebtRatio'].mean()) / df['DebtRatio'].std()

# 综合得分
quality_factor = (df['ROE_score'] + df['ROA_score'] + df['Margin_score'] + df['Leverage_score']) / 4

return quality_factor

规模因子

规模因子基于市值构建,核心假设是小市值股票有更高的预期收益(规模溢价)。

def build_size_factor(df):
"""
构建规模因子

参数:
df: 包含市值的DataFrame

返回:
规模因子得分(越小市值得分越高)
"""
# 市值对数
log_size = np.log(df['MarketCap'])

# 标准化后取负(小市值得分高)
size_factor = -(log_size - log_size.mean()) / log_size.std()

return size_factor

波动因子

波动因子基于历史波动率构建,核心假设是低波动股票风险调整后收益更高(低波动异象)。

def build_volatility_factor(returns, window=252):
"""
构建波动因子

参数:
returns: 收益率序列
window: 计算窗口

返回:
波动因子得分(低波动得分高)
"""
# 计算历史波动率
volatility = returns.rolling(window=window).std() * np.sqrt(252)

# 标准化后取负(低波动得分高)
vol_factor = -(volatility - volatility.mean()) / volatility.std()

return vol_factor

因子分析

IC值

IC(Information Coefficient)是因子值与未来收益的相关系数,衡量因子的预测能力。

def calculate_ic(factor_values, forward_returns):
"""
计算IC值

参数:
factor_values: 因子值(截面数据)
forward_returns: 未来收益

返回:
IC值
"""
# Pearson相关系数
ic = factor_values.corr(forward_returns)

return ic

def calculate_ic_series(factor_df, returns_df, periods=252):
"""
计算IC时间序列

参数:
factor_df: 因子数据(日期x股票)
returns_df: 收益数据(日期x股票)
periods: 计算周期

返回:
IC序列
"""
ic_series = []
dates = factor_df.index[:-periods]

for date in dates:
factor = factor_df.loc[date]
future_return = returns_df.loc[date:].iloc[1:periods+1].sum()

ic = calculate_ic(factor, future_return)
ic_series.append({'date': date, 'IC': ic})

return pd.DataFrame(ic_series).set_index('date')

def analyze_ic(ic_series):
"""
分析IC序列

参数:
ic_series: IC序列

返回:
IC分析结果
"""
return {
'IC_mean': ic_series.mean(),
'IC_std': ic_series.std(),
'ICIR': ic_series.mean() / ic_series.std(), # IC信息比率
'IC_positive_ratio': (ic_series > 0).mean(), # IC为正的比例
'IC_t_stat': ic_series.mean() / (ic_series.std() / np.sqrt(len(ic_series)))
}

IC值的解读:

  • |IC| > 0.05:因子有较强的预测能力
  • |IC| > 0.03:因子有一定的预测能力
  • |IC| < 0.03:因子预测能力较弱
  • ICIR > 0.5:因子稳定性较好
  • ICIR > 1.0:因子稳定性优秀

分组回测

将股票按因子值分组,比较各组的收益表现。

def factor_group_backtest(factor_values, returns, n_groups=5):
"""
因子分组回测

参数:
factor_values: 因子值
returns: 收益率
n_groups: 分组数量

返回:
各组收益统计
"""
# 按因子值分组
factor_values = factor_values.dropna()
labels = ['G' + str(i+1) for i in range(n_groups)]
groups = pd.qcut(factor_values, n_groups, labels=labels)

# 计算各组收益
group_returns = {}
for label in labels:
stocks = groups[groups == label].index
group_returns[label] = returns[stocks].mean()

return pd.Series(group_returns)

def factor_group_analysis(factor_df, returns_df, n_groups=5):
"""
因子分组分析(时间序列)

参数:
factor_df: 因子数据(日期x股票)
returns_df: 收益数据(日期x股票)
n_groups: 分组数量

返回:
各组累计收益
"""
all_group_returns = []

for date in factor_df.index[:-1]:
factor = factor_df.loc[date]
next_return = returns_df.loc[factor_df.index[factor_df.index.get_loc(date) + 1]]

group_ret = factor_group_backtest(factor, next_return, n_groups)
group_ret.name = date
all_group_returns.append(group_ret)

group_returns_df = pd.DataFrame(all_group_returns)

# 计算累计收益
cumulative_returns = (1 + group_returns_df).cumprod()

return cumulative_returns

因子正交化

多个因子之间可能存在相关性,需要正交化处理以消除共线性。

from sklearn.linear_model import LinearRegression

def orthogonalize_factor(target_factor, other_factors):
"""
因子正交化

参数:
target_factor: 目标因子
other_factors: 其他因子(需要正交化的因子)

返回:
正交化后的因子
"""
# 用其他因子回归目标因子
X = other_factors.values
y = target_factor.values

model = LinearRegression()
model.fit(X, y)

# 残差即为正交化后的因子
residual = y - model.predict(X)

return pd.Series(residual, index=target_factor.index)

多因子模型构建

因子组合方法

def combine_factors(factor_dict, weights=None):
"""
组合多个因子

参数:
factor_dict: 因子字典 {因子名: 因子值}
weights: 因子权重字典

返回:
综合因子得分
"""
if weights is None:
weights = {name: 1/len(factor_dict) for name in factor_dict}

combined = pd.Series(0, index=list(factor_dict.values())[0].index)

for name, factor in factor_dict.items():
# 标准化
factor_std = (factor - factor.mean()) / factor.std()
# 加权
combined += weights[name] * factor_std

return combined

def equal_weight_portfolio(factor_scores, n_stocks=50):
"""
等权重组合构建

参数:
factor_scores: 因子得分
n_stocks: 持仓股票数量

返回:
选出的股票列表
"""
# 选择得分最高的n只股票
selected = factor_scores.nlargest(n_stocks).index.tolist()

# 等权重
weights = pd.Series(1/n_stocks, index=selected)

return weights

因子权重优化

from scipy.optimize import minimize

def optimize_factor_weights(factor_returns, cov_matrix, target_return=None):
"""
优化因子权重(均值方差优化)

参数:
factor_returns: 因子收益历史数据
cov_matrix: 因子协方差矩阵
target_return: 目标收益

返回:
最优权重
"""
n_factors = len(factor_returns.columns)

# 目标函数:最小化方差
def portfolio_variance(weights):
return weights @ cov_matrix @ weights

# 约束条件
constraints = [
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1} # 权重和为1
]

if target_return:
expected_returns = factor_returns.mean()
constraints.append({
'type': 'eq',
'fun': lambda w: w @ expected_returns - target_return
})

# 边界条件
bounds = tuple((0, 1) for _ in range(n_factors))

# 初始权重
initial_weights = np.array([1/n_factors] * n_factors)

# 优化
result = minimize(
portfolio_variance,
initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints
)

return result.x

小结

因子投资是量化投资的核心方法论,本章介绍了因子的基本概念、常用因子类型、因子分析方法和多因子模型构建。因子投资的关键在于:

  1. 选择有经济学逻辑支撑的因子
  2. 通过IC分析验证因子的预测能力
  3. 处理因子之间的相关性
  4. 合理组合多个因子

因子投资不是简单的因子堆砌,而是需要深入理解每个因子背后的经济学逻辑,以及因子在不同市场环境下的表现。下一章将介绍机器学习在量化交易中的应用。