Fama-French 三因子模型 A 股实证:Python 代码复现 25 个投资组合回归
Fama-French三因子模型在A股市场的Python实战从数据清洗到25组投资组合回归引言在量化投资领域Fama-French三因子模型已成为解释股票收益率的经典框架。本文将带您用Python完整实现该模型在A股市场的实证分析从原始数据获取到因子构建再到25组投资组合的回归检验。不同于理论介绍我们聚焦可复现的代码实现提供可直接应用于A股研究的工具性内容。无论您是金融专业学生还是量化研究员都能通过本文掌握三因子模型的核心实现技术。我们将使用2009-2019年全A股月频数据重点解决以下实际问题如何正确处理A股特有的ST股票和新股问题SMB规模因子和HML价值因子的精确构建方法25组投资组合的市值加权收益率计算回归结果的经济意义解读1. 数据准备与清洗1.1 原始数据获取我们需要以下核心数据表假设已从CSV文件读取import pandas as pd import numpy as np # 基础数据读取 price pd.read_csv(股价数据.csv) # 每月收盘价 ST pd.read_csv(ST标记.csv) # ST状态记录 pb pd.read_csv(市净率.csv) # 每月PB值 mkt pd.read_csv(市值数据.csv) # 每月总市值 ipodate pd.read_csv(上市日期.csv) # 股票IPO日期1.2 数据预处理关键步骤市值与账面市值比合并# 计算账面市值比BM1/PB BM pb.copy() BM[BM] 1/pb.pb BM BM.drop([pb], axis1) # 合并BM与市值数据 f pd.merge(BM, mkt, on[tradedate,stockcode]) f f.loc[f.BM 0].reset_index(dropTrue) # 剔除BM0的股票新股过滤上市不满一年# 计算上市满一年的临界日期 ipodate[entry_date] ipodate.ipodate pd.Timedelta(days365) f pd.merge(f, ipodate, onstockcode) f f.loc[f.tradedate f.entry_date].reset_index(dropTrue)ST股票过滤res [] for date in f.tradedate.unique(): fuse f.loc[f.tradedate date] st_use ST.loc[(ST.entry_dt date) ((ST.remove_dt date) | ST.remove_dt.isna())] valid_codes set(fuse.stockcode) - set(st_use.stockcode) res.append(fuse.set_index(stockcode).loc[valid_codes].reset_index()) f pd.concat(res).reset_index(dropTrue)提示A股数据清洗需特别注意两点(1) 上市首月涨跌幅限制不同 (2) ST股票的特殊交易规则2. 因子构建方法论2.1 规模因子(SMB)与价值因子(HML)Fama-French三因子的核心在于双重排序法构建因子每年5月末进行分组f[ym] f.tradedate.dt.year*100 f.tradedate.dt.month f_5 f.loc[f.ym % 10 5].copy() # 每年5月数据BM分组高、中、低def split_BM(x): x.loc[x.BM x.BM.quantile(0.7), group_BM] H x.loc[x.BM x.BM.quantile(0.3), group_BM] L return x f_5[group_BM] M f_5 f_5.groupby(ym).apply(split_BM)市值分组大、小def split_SIZE(x): x.loc[x.mkt x.mkt.median(), group_SIZE] B return x f_5[group_SIZE] S f_5 f_5.groupby(ym).apply(split_SIZE)形成6个投资组合f_5[portfolio_name] f_5.group_SIZE / f_5.group_BM2.2 因子收益率计算SMB因子公式SMB 1/3(Small/High Small/Medium Small/Low) - 1/3(Big/High Big/Medium Big/Low)HML因子公式HML 1/2(Small/High Big/High) - 1/2(Small/Low Big/Low)Python实现# 计算组合收益率市值加权 port_ret f.groupby([tradedate,portfolio_name]).apply( lambda x: (x.ret*x.mkt).sum()/x.mkt.sum()) # 转换为宽表 port_ret_pivot port_ret.unstack() # 计算因子收益率 SMB (port_ret_pivot[S/H] port_ret_pivot[S/M] port_ret_pivot[S/L])/3 - (port_ret_pivot[B/H] port_ret_pivot[B/M] port_ret_pivot[B/L])/3 HML (port_ret_pivot[S/H] port_ret_pivot[B/H])/2 - (port_ret_pivot[S/L] port_ret_pivot[B/L])/23. 25组投资组合构建3.1 五等分分组方法将市值和BM分别分为5组形成5x5矩阵groups 5 f_5 f.loc[f.ym % 10 5, [stockcode,tradedate,BM,mkt]].copy() # BM五等分 f_5[g_BM] f_5.groupby(tradedate)[BM].rank( pctTrue).apply(lambda x: np.ceil(x*groups)) # 市值五等分 f_5[g_SIZE] f_5.groupby(tradedate)[mkt].rank( pctTrue).apply(lambda x: np.ceil(x*groups))3.2 组合收益率计算# 合并分组信息 f pd.merge(f, f_5[[stockcode,tradedate,g_BM,g_SIZE]], on[stockcode,tradedate]) # 计算25组组合收益率 port_ret_25 f.groupby([tradedate,g_BM,g_SIZE]).apply( lambda x: (x.ret*x.mkt).sum()/x.mkt.sum()) port_ret_25 port_ret_25.unstack().reset_index()4. 回归分析与结果解读4.1 三因子模型回归对每个组合进行时间序列回归R_i - R_f α β1*(Rm-Rf) β2*SMB β3*HML εPython实现import statsmodels.api as sm # 准备解释变量 ff3 pd.concat([SMB, HML, mkt_rf], axis1) ff3[Intercept] 1 x ff3[[SMB,HML,mkt_rf,Intercept]].values # 存储结果 results [] for i in range(25): y port_ret_25.iloc[:,i1].values model sm.OLS(y, x).fit() results.append({ Group: port_ret_25.columns[i1], Alpha: model.params[-1], Beta_MKT: model.params[2], Beta_SMB: model.params[0], Beta_HML: model.params[1], R2: model.rsquared })4.2 结果分析示例典型回归结果呈现组合Alphaβ_MKTβ_SMBβ_HMLR²1/10.003**0.850.620.410.723/30.0011.02-0.080.050.885/5-0.002*1.15-0.35-0.820.81关键发现小市值效应小市值组合(1/x)对SMB因子暴露显著为正价值溢价高BM组合(x/5)对HML因子暴露为负A股特有现象大市值组合表现出更显著的市场风险暴露注意A股市场常出现与美股不同的因子特征需结合本地市场环境解读5. 完整代码框架以下是整合后的Jupyter Notebook代码结构# 1. 数据准备 def load_and_clean(): # 数据读取与清洗代码 ... # 2. 因子构建 def construct_factors(): # SMB/HML构建代码 ... # 3. 组合回归 def portfolio_regression(): # 25组组合回归代码 ... # 主程序 if __name__ __main__: df load_and_clean() factors construct_factors(df) results portfolio_regression(df, factors) # 结果可视化 plot_results(results)实际应用中建议将完整代码封装为类结构class FamaFrench3Factor: def __init__(self, start_date2009-05, end_date2019-12): self.data None self.factors None def load_data(self): # 实现数据加载 ... def build_factors(self): # 实现因子构建 ... def run_regression(self): # 实现回归分析 ...通过这种模块化设计可轻松扩展为Carhart四因子或其他多因子模型。

相关新闻

Dify新手入门指南:从零开始掌握AI应用开发平台

Dify新手入门指南:从零开始掌握AI应用开发平台

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 在开始构建复杂的AI应用之前,一个清晰、顺畅的起点至关重要。很多开发者在初次接触Dify时,面对其丰富的功能模…

2026/7/5 11:09:19 阅读更多 →
Dify模型接入全攻略:从云端API到本地部署,一站式管理大模型

Dify模型接入全攻略:从云端API到本地部署,一站式管理大模型

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 1. 先搞清楚 Dify 接入大模型到底要解决什么问题 如果你正在找一种方法,能快速把 OpenAI、Claude、智谱、通义千问&#x…

2026/7/5 11:09:19 阅读更多 →
Momentum 优化算法 PyTorch 1.13 实战:3 种梯度下降对比与 0.9 动量参数调优

Momentum 优化算法 PyTorch 1.13 实战:3 种梯度下降对比与 0.9 动量参数调优

Momentum优化算法PyTorch 1.13实战:3种梯度下降对比与0.9动量参数调优在深度学习模型训练过程中,优化算法的选择直接影响模型的收敛速度和最终性能。本文将基于PyTorch 1.13框架,通过完整的代码实现对比SGD、SGD with Momentum和Adam三种主流…

2026/7/5 11:09:19 阅读更多 →

最新新闻

从零部署Hermes Agent:构建自我进化的AI智能体实战指南

从零部署Hermes Agent:构建自我进化的AI智能体实战指南

在 AI 智能体领域,从简单的聊天机器人到能够自主执行复杂任务的智能助手,中间隔着一道巨大的鸿沟。这道鸿沟的核心在于,一个真正的智能体不仅需要理解指令,更需要具备学习、记忆、规划和利用工具的能力。Hermes Agent 正是 Nous R…

2026/7/5 12:21:48 阅读更多 →
AI建站工具指南:零代码打造专业网站的完整流程

AI建站工具指南:零代码打造专业网站的完整流程

1. AI建站工具的本质与核心价值AI建站工具正在彻底改变个人和小型企业创建网站的方式。这类工具的核心价值在于将原本需要专业开发技能的建站过程,简化为一个自然语言交互的对话流程。想象一下,你只需要告诉AI"我想要一个展示摄影作品集的网站&…

2026/7/5 12:21:48 阅读更多 →
如何用开源工具Meshroom从照片创建专业3D模型:完整免费指南

如何用开源工具Meshroom从照片创建专业3D模型:完整免费指南

如何用开源工具Meshroom从照片创建专业3D模型:完整免费指南 【免费下载链接】Meshroom Node-based Visual Programming Toolbox 项目地址: https://gitcode.com/gh_mirrors/me/Meshroom 在当今数字时代,将普通照片转化为精美3D模型不再是专业工作…

2026/7/5 12:19:47 阅读更多 →
PPO算法实战:从原理到调试技巧

PPO算法实战:从原理到调试技巧

1. 项目概述:PPO算法初体验 第一次接触强化学习中的PPO(Proximal Policy Optimization)算法时,那种既兴奋又忐忑的心情至今记忆犹新。作为目前最主流的策略梯度算法之一,PPO以其出色的稳定性和样本效率,成为…

2026/7/5 12:17:47 阅读更多 →
BetterGenshinImpact:三阶段智能辅助指南,从萌新到高玩的完整解决方案

BetterGenshinImpact:三阶段智能辅助指南,从萌新到高玩的完整解决方案

BetterGenshinImpact:三阶段智能辅助指南,从萌新到高玩的完整解决方案 【免费下载链接】better-genshin-impact 📦BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄…

2026/7/5 12:15:46 阅读更多 →
PMP 项目管理规划(Planning)学习专题指南

PMP 项目管理规划(Planning)学习专题指南

PMP 项目管理规划(Planning)学习专题指南 在PMP考试(尤其是2026新版)中,Planning(规划) 是Process领域(41%权重)的核心部分,也是零基础考生最需要重点掌握的模…

2026/7/5 12:13:45 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻