FRM模型十五:净值归因之Fama_French三因子模型

文章目录

    • 一、起源
    • 二、构建因子
    • 三、投资组合的净值归因
      • 1. 市场因子
      • 2. 规模因子
      • 3.价值因子
      • 4. 基于净值的归因方法
    • 三、代码实现

一、起源

在多因子模型推出之前,CAPM模型被视为资产定价的第一标准。随着市场不断发展,发现了越来越多CAPM模型无法解释的现象,包括盈利市值比效应、小市值效应等等。但这些单一异象并未动摇CAPM模型的地位,直到Fama-French三因子模型出现,拉开多因子模型的序幕。Fama三因子模型在CAPM的基础上加入了价值和规模两个因子,提出了三因子模型。
E ( r i ) = r f + β i , M K T E ( r m − r f ) + β i , S M B E ( S M B ) + β i , H M L E ( H M L ) E(r_{i})=r_{f}+\beta_{i,MKT}E(r_m-r_f)+\beta_{i,SMB}E(SMB)+\beta_{i,HML}E(HML) E(ri)=rf+βi,MKTE(rmrf)+βi,SMBE(SMB)+βi,HMLE(HML)

其中 E ( R i ) E(R_{i}) E(Ri)表示股票第i期的预期收益率, r f r_{f} rf是无风险收益率,为市场组合预期收益率, E ( S M B ) E(SMB) E(SMB) E ( H M L ) E(HML) E(HML)分别为规模因子(SMB)以及价值因子(HML)的预期收益率, β i , M K T \beta_{i,MKT} βi,MKT β i , S M B \beta_{i,SMB} βi,SMB β i , H M L \beta_{i,HML} βi,HML是个股在因子上的暴露。

通俗版解释:若该模型成立,那么个股的超额收益就能通过这三个因子预测出来,在选股时,只需要找到对应因子最大的股票,即可认为是“优质股”.

二、构建因子

选择BM和市值两个指标,进行独立双重排序。先按照市值将股票分为大市值组合小市值组,再按照BM的30%分位数和70%分位数分组,共6组,分别记为:S/H、S/M、S/L、B/H、B/M、B/L。再将每组的股票收益率按照市值加权得到6个投资组合,构建两个因子。

S M B = S H + S M + S L 3 − B H + B M + B L 3 SMB=\frac{SH+SM+SL}{3}-\frac{BH+BM+BL}{3} SMB=3SH+SM+SL3BH+BM+BL

H M L = S H + B H 2 − S L + B L 2 HML=\frac{SH+BH}{2}-\frac{SL+BL}{2} HML=2SH+BH2SL+BL

分析SMB和HML表达式可以看出,SMB是用三个小市值组合减去三个大市值组合,HML是用两个高BM组合减去两个低BM组合。

三、投资组合的净值归因

1. 市场因子

市场因子收益率为市场指数区间收益率减去同期的无风险收益率。

2. 规模因子

多头:对全 A 股市场的股票按照市值排序,取市值较小的 50%的股票等权重配置构成小盘风格组合。

空头:对全 A 股市场的股票按照市值排序,取市值较大的 50%的股票等权重配置构成大盘风格组合。

3.价值因子

多头:对全 A 股市场的股票按照市净率 PB(MRQ)和市值进行双重排序,选取市净率 PB(MRQ)较低的 30%的股票。根据市值中位数对该股票池分割,构成小市值低估值和大市值低估值组合。两个组合内部股票等权重配置,并且两个组合之间也等权重配置构成低估值组合。

空头:对全 A 股市场的股票按照市净率 PB(MRQ)和市值进行双重排序,选取市净率 PB(MRQ)较高的 30%的股票。根据市值中位数对该股票池分割,构成小市值高估值和大市值高估值组合。两个组合内部股票等权重配置,并且两个组合之间也等权配置重构成高估值组合。

4. 基于净值的归因方法

需提前确定的参数:

  1. 评估时间段:1M、3M、1Y、3Y、5Y
  2. 无风险收益率:一年定存利率、一年期国债收益率等
  3. 市场指数:沪深300指数、上证综指等

基于净值的多因子模型通过使用因子收益的时间序列对组合收益的时间序列进行线性回归运算,将组合的收益和风险分解在各因子上:
R p t − R F t = α + ∑ i = 0 n β i F i t + ϵ t R_{pt}-RF_{t}=\alpha+\sum_{i=0}^{n}\beta_{i}F_{it}+\epsilon_{t} RptRFt=α+i=0nβiFit+ϵt

其中 R p t R_{pt} Rpt为组合在t时间段的收益率, R F t RF_t RFt为t时间段的无风险收益率, F i t F_{it} Fit为因子i在t时间段的收益率。 β i \beta_{i} βi为待拟合的系数。 α \alpha α为待拟合的截距项。 ϵ t \epsilon_{t} ϵt为t时间的残差项。

三、代码实现

本代码基于wind数据提供的API,需先下载WIND并开通API权限。

from WindPy import w
import pandas as pd
import statsmodels.api as sm# 连接Wind的API接口
w.start() # 默认命令超时时间为120秒,如需设置超时时间可以加入waitTime参数,例如waitTime=60,即设置命令超时时间为60秒
w.isconnected() # 判断WindPy是否已经登录成功# 构建因子
def fama_three_factor(startDate, endDate, rfree_code, index_code, fund_code):# 基金数据fund = w.wsd(fund_code, fields=['return_m'], beginTime=startDate, endTime=endDate, usedf=True, Period='M')[1]# 市场因子free_data = w.wsd(rfree_code, fields=['close'], beginTime=startDate, endTime=endDate, usedf=True, Period='M',Fill='Previous')[1]index = w.wsd(index_code, fields=['pct_chg'], beginTime=startDate, endTime=endDate, usedf=True, Period='M')[1]df = pd.merge(free_data, index, on=free_data.index, left_index=True)df['MKT'] = df['PCT_CHG'] - df['CLOSE']df['y'] = fund['RETURN_M'] - df['CLOSE']# 规模因子SMB_list = []HML_list = []date = df.index.tolist()# 遍历每个交易日市值大小for i in date:stock_list = w.wset("sectorconstituent", date=i, windcode=index_code, usedf=True)[1]stock = stock_list['wind_code'].tolist()          # 获取指数成分股# 获取当前时点下,全部成分股收益率、市值returns1 = w.wss(stock, fields=['ev'], annualized=0, tradeDate=i, usedf=True)[1]returns2 = w.wss(stock, fields=['pb_mrq'], annualized=0, tradeDate=i, usedf=True)[1]returns = pd.merge(returns1, returns2, on=returns1.index,left_index=True,right_index=True)# 按照市值排序returns.sort_values(by=['EV'], ascending=True, inplace=True)# 取前50%作为Slist,取后50%作为BlistSlist = returns.head(int(len(returns) * 0.5)).index.tolist()Blist = returns.tail(int(len(returns) * 0.5)).index.tolist()# 计算SMBSmall = w.wsd(Slist, "pct_chg", i, i, "Period=M", usedf=True)[1]Big = w.wsd(Blist, "pct_chg", i, i, "Period=M", usedf=True)[1]SMB = Small.mean() - Big.mean()SMB_list.append(SMB.values[0])# 取选取市净率PB(MRQ)较低的30%的股票,市值中位数对该股票池分割returns.sort_values(by=['PB_MRQ'], ascending=True, inplace=True)# 取PB低的30%和PB高的30%Lowlist = returns.head(int(len(returns) * 0.3))Highlist = returns.tail(int(len(returns) * 0.3))# 按照市值继续分割:小市值低估值、大市值低估值Lowlist.sort_values(by=['EV'], ascending=True, inplace=True)Low_small_list = Lowlist.head(int(len(Lowlist) * 0.5)).index.tolist()Low_big_list = Lowlist.tail(int(len(Lowlist) * 0.5)).index.tolist()Highlist.sort_values(by=['EV'], ascending=True, inplace=True)High_small_list = Highlist.head(int(len(Highlist) * 0.5)).index.tolist()High_big_list = Highlist.tail(int(len(Highlist) * 0.5)).index.tolist()# 计算HMLHigh_small = w.wsd(High_small_list, "pct_chg", i, i, "Period=M", usedf=True)[1]High_big = w.wsd(High_big_list, "pct_chg", i, i, "Period=M", usedf=True)[1]Low_small = w.wsd(Low_small_list, "pct_chg", i, i, "Period=M", usedf=True)[1]Low_big = w.wsd(Low_big_list, "pct_chg", i, i, "Period=M", usedf=True)[1]HML = (High_small.mean() + High_big.mean())/2 - (Low_small.mean() + Low_big.mean())/2HML_list.append(HML.values[0])# 将规模因子合并至原数据集df['SMB'] = SMB_listdf['HML'] = HML_listdf = df[['y', 'MKT', 'SMB', 'HML']]return df# 计算beta
def cal_beta(df):# 添加常数项作为截距x = df[['MKT', 'SMB', 'HML']]y = df['y']X_with_intercept = sm.add_constant(x)# 构建模型并估计参数model = sm.OLS(y, X_with_intercept)results = model.fit().params# 输出贡献度print("市场因子贡献度%.4f" % (results['MKT']))print("规模因子贡献度%.4f" % (results['SMB']))print("价值因子贡献度%.4f" % (results['HML']))return results['MKT'], results['SMB'], results['HML']# 输入参数:开始时间、结束时间、无风险利率标准、市场指数、基金指数
startDate = '2023-01-01'
endDate = '2023-12-30'
rfree_code = "SHIBOR1M.IR"
index_code = "000300.SH"
fund_code = "167702.OF"
df = fama_three_factor(startDate, endDate, rfree_code, index_code, fund_code)
beta_MKT, beta_SMB, beta_HML = cal_beta(df)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/722030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java中的this

在Java中,this 是一个关键字,用于引用当前对象。它可以用于访问当前对象的实例变量和方法。this 关键字通常在以下情况下使用:区分实例变量和局部变量:当实例变量和局部变量名称相同时,可以使用 this 关键字来引用实例…

【linux】crontab定时任务介绍

1.简介2.crontab语法3.crontab限制4.crontab配置文件5.crontab格式介绍 1.简介 Linux crontab 是用来定期执行程序的命令。 当安装完成操作系统之后,默认便会启动此任务调度命令。 crond 命令每分钟会定期检查是否有要执行的工作,如果有要执行的工作便…

u-boot的DM驱动模型

0、本文基于U-Boot 2022.01-v2.07版本进行分析。 1、u-boot编译流程简要分析 2、u-boot启动流程简要分析 3、u-boot增加自定义命令 4、u-boot的DM驱动模型 4.1、参考资料 Uboot中的DM驱动模型:这篇文章详细介绍了DM驱动模型的原理。 本文重点整理了几个数据结构…

超详细的Scrapy框架的基本使用教程

Scrapy的介绍 scrapy的工作流程(重点!!!) 如下图所示: 爬虫: 负责向引擎提供要爬取网页的URL,引擎会把这个URL封装成request对象并传递给调度器,把引擎传递过来的resp…

常用区块链安全关键名词和攻击方法解释

文章目录 一、重点名词解释1.1 钱包(Wallet)1.2 冷钱包(Cold Wallet)1.3 热钱包 (Hot Wallet)1.4 公钥(Public Key)1.5 私钥(Private Key)1.6 助记词(Mnemonic)1.7 Keystore1.8 公链(Public Blockchain)1.9 交易所 Exchange1.10 节…

API 常用的序列化协议详解

目录 JSON (JavaScript Object Notation) XML (Extensible Markup Language) Protocol Buffers (Protobuf) MessagePack Thrift Avro 小结 API(Application Programming Interface,应用程序编程接口)在软件开发中扮演着至关重要的角色…

leetcode 673.最长递增子序列的个数

上一题只需要知道最长递增子序列的长度就行了,那样的话直接一个dp就完事了,但是呢,这里说了需要记录这个最长长度递增子序列的个数,这下的话,如果你想用原先的思路,其实可以,但是要能做到计数的…

vue3 (六)自定义指令

1.定义自定义指令: app.directive(pos,{mounted(el,bunding){el.style[bunding.arg] bunding.value px;}, updated(el,bunding){el.style[bunding.arg] bunding.value px;} }) app.directive(指令名,{ mounted(el,bunding){}, updated(el,bunding){} }) 如果只…

安卓app软件开发的费用

我们公司总结的开发价格根据安卓APP,苹果APP行业的报价,开发的APP软件费用主要受到两个方面的影响。安卓和苹果APP软件应用的复杂性,第二个是定制开发的APP软件,开发成本和人员的投入成本,以下就是不同的报价费用是怎么…

面试经典150题【51-60】

文章目录 面试经典150题【51-60】71.简化路径155.最小栈150.逆波兰表达式求值224.基本计算器141.环形链表2.两数相加21.合并两个有序链表138.随机链表的复制19.删除链表的倒数第N个节点82.删除链表中的重复元素II 面试经典150题【51-60】 71.简化路径 先用split(“/”)分开。然…

10. Nginx进阶-Return

简介 什么是Return? nginx的return指令是用于在nginx配置文件中进行重定向或返回特定的HTTP响应码的指令。 它可以根据不同的条件来执行不同的操作,如重定向到其他URL、返回指定的HTTP响应码或自定义响应内容等。 Return适用范围 return指令只能在se…

四平方和 刷题笔记

/* 四平方和 直接暴力搜索 可能会超时 使用二分辅助搜索 先枚举出 c*cd*d并存入数组 用式子算出 a*ab*b还剩下多少查找sum数组里面是否存在符合条件的数 查找方式使用二分搜索 当逼近答案后 检查一下是否为所需的数 如果是 直接输出 */ #include <cstring> #includ…

rabbitmq基础(1)

1、背景 能实现消息队列的框架软件有很多&#xff0c;kafka、rabbitmq、RocketMq、activeMq、Redis&#xff08;非专业&#xff09;&#xff0c;各有各的特点和优缺点。但是之前的公司数据需求规模并非很大&#xff0c;所以采用rabbitmq作为消息队列。 2、rabbitMq的基础架构…

大批量接口请求的前端优化

接到一个需求&#xff0c;需要做一个运维的功能&#xff0c;对公司下平台子系统做一个开关界面&#xff0c;要求可以大批量对系统进行修改。这样大批量的修改&#xff0c;如果有个老哥手一抖点了全选&#xff0c;那可能同时会发送几十上百个接口&#xff0c;对浏览器和服务器都…

C++面试宝典【配文档,全方面学习】

原word文档[链接: https://pan.baidu.com/s/1CKnm7vHDmHSDskAgxgZgKA?pwdr4wv 提取码: r4wv 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v5的分享] 一、C / C基础 1、简述C的内存分区&#xff1f; 一个C、C程序的内存分区主要有5个…

使用html网页播放多个视频的几种方法

前言 因为项目测试需要&#xff0c;我需要可以快速知道自己推流的多路视频流质量&#xff0c;于是我想到可以使用html网页来播放视频&#xff0c;实现效果极其简单&#xff0c;方法有好几种&#xff0c;以下是几种记录&#xff1a; 注意&#xff1a;测试过&#xff0c;VLC需要使…

Java:类加载器

参考 JavaGuide 简介 类加载器的主要作用是加载Java类的字节码即.class文件到JVM中。每个Java类都有一个引用指向加载它的类加载器。数组类是JVM直接生成而非加载的。根据需要动态加载&#xff0c;已加载的类放到ClassLoader中&#xff0c;相同二进制名称的类只会被加载一次…

C++从零开始的打怪升级之路(day43)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于多态的知识点 1.多态的概念及定义&#xff0c;…

[Python] 添加重试机制来处理某些可能出现异常的函数

在 Python 中&#xff0c;如果你想要添加重试机制来处理某些可能出现异常的函数&#xff0c;可以使用 retry 装饰器。虽然 Python 标准库中没有提供内置的 retry 装饰器&#xff0c;但你可以使用第三方库 tenacity 来实现这个功能。 tenacity 是一个流行的 Python 库&#xff…

Ubuntu18.04运行ORB-SLAM3

ORB-SLAM3复现(ubuntu18) 文章目录 ORB-SLAM3复现(ubuntu18)1 坐标系与外参Intrinsic parameters2 内参Intrinsic parameters2.1 相机内参① 针孔模型Pinhole② KannalaBrandt8模型③ Rectified相机 2.2 IMU内参 3 VI标定—外参3.1 Visual calibration3.2 Inertial calibration…