python 基金绩效归因

本文介绍了基金绩效归因的四种模型:CAPM、T-M、H-M和C-L模型,通过这些模型分析基金的超额收益来源,包括择股和择时能力。以兴全合润混合基金为例,运用线性回归方法,结果显示该基金在样本期内具有正向的择股能力,但在C-L模型中显示出负向的择时能力。这些模型为基金评价提供了基础,但也有局限性,如分析维度单一和对基准依赖性强。
摘要由CSDN通过智能技术生成

python 基金绩效归因

1 前言

       随着社会经济的发展和投资意识的不断增强,人们已经不满足于银行存款和余额宝等低收益率的理财产品,开始将目光聚焦到基金上。
       绩效评估可以分为三个部分,分别为择股、择时和交互作用。从最基本的使用定量指标刻画组合表现的绩效衡量到深层次的组合超额收益分解的绩效归因,最终形成成熟的绩效评价,对组合或基金的超额收益的可持续性进行评价。绩效归因有因子分析及回归拟合两类方法,本文介绍了几种简单的因子分析方法,对于策略尤其是基金的评价方面具有实践意义(回归拟合法以后有空再写)。

2 模型介绍

2.1 CAPM模型

       CAPM,全称 Capital Asset Pricing Model,译为资本资产定价模型,是由 Treynor, Sharpe, Lintner, Mossin 几人分别提出。搭建于 Markowitz 的现代资产配置理论(MPT)之上,该模型用简单的数学公式表述了资产组合收益率与无风险利率以及市场组合收益率之间的关系。在这个公式中,任何风险资产组合的超额收益都可以被分为两个部分:非市场收益α和市场风险敞口收益β。
                             r s r_s rs - r f r_f rf = α + β( r m r_m rm - r f r_f rf) + ϵ
       其中, r s r_s rs 表示投资组合收益率; r f r_f rf 表示无风险利率; r m r_m rm 表示市场组合收益率;α表示个股选择带来的超额收益,这部分收益无法由市场风险解释;β表示组合在市场中暴露的风险敞口。
       因此,当α显著大于0时,说明该基金管理人具有正向的择股能力。当β>1时,说明资产组合的风险波动比市场组合大;当0<β<1时,说明资产组合的风险波动比市场组合小。

2.2 T-M模型

       T-M,全称Treynor - Mazuy Model,是由Treynor和Mazuy于1966年共同提出。该模型在CAPM模型的基础上增加了市场超额收益的二阶项。
               r s r_s rs - r f r_f rf = α + β 1 β_1 β1( r m r_m rm - r f r_f rf) + β 2 β_2 β2( r m r_m rm - r f r_f rf) 2 ^2 2+ ϵ
       当α显著大于0时,说明该基金管理人具有正向的择股能力。当 β 2 β_2 β2显著大于0时,说明该基金管理人具有正向的择时能力。

2.3 H-M模型

       H-M,全称Henriksson - Merton Model,是由Henriksson和Merton于1981年共同提出。该模型在T-M模型的基础上进行改进。
            r s r_s rs - r f r_f rf = α + β 1 β_1 β1( r m r_m rm - r f r_f rf) + β 2 β_2 β2( r m r_m rm - r f r_f rf) I r m > r f I_{r_m>r_f} Irm>rf+ ϵ
       其中:
                                    I r m > r f = { 1 , 当 r m > r f 0 , 其 它 I_{r_m>r_f} = \begin{cases} 1, 当r_m>r_f\\ 0, 其它 \end{cases} Irm>rf={1rm>rf0
       当α显著大于0时,说明该基金管理人具有正向的择股能力。当 β 2 β_2 β2显著大于0时,说明该基金管理人具有正向的择时能力。

2.4 C-L模型

       C-L,全称Chang - Lewellen Model,是由Chang和Lewellen于1984年共同提出。该模型与H-M模型对择时能力的定义一致。
     r s r_s rs - r f r_f rf = α + β 1 β_1 β1( r m r_m rm - r f r_f rf) I r m < r f I_{r_m<r_f} Irm<rf+ β 2 β_2 β2( r m r_m rm - r f r_f rf) I r m > r f I_{r_m>r_f} Irm>rf+ ϵ
       当α显著大于0时,说明该基金管理人具有正向的择股能力。当 β 2 β_2 β2> β 1 β_1 β1时,说明该基金管理人具有正向的择时能力。

3 实证分析

3.1 数据说明

       本文以兴全合润混合(LOF)基金(163406)为例,样本期为2019年12月1日到2020年2月29日共58个交易日。市场组合收益率为沪深300指数日收益率,无风险利率为国债指数日收益率,持有股票为下图所示的十只股票,仓位根据这十只股票占基金净值比按比例分配。数据来源于tushare数据库,官网链接:https://tushare.pro
在这里插入图片描述

3.2 结果

模型名称α β 1 β_1 β1 β 2 β_2 β2 R 2 R^2 R2
CAPM0.3173**1.2452***0.775
T - M0.3448**1.2009***-0.01090.776
H - M0.4145**1.3032***-0.20760.778
C - L0.4145**1.3032***1.0957***0.778

       注: ∗ ∗ ∗ *** ∗ ∗ ** ∗ * 分别表示相应变量在 1%、5% 和 10% 水平下显著。
       从上表可以看出,无论是什么模型,该基金管理人在样本期内具有正向的择股能力。在C - L模型中, β 2 β_2 β2小于 β 1 β_1 β1 ,且系数显著,说明该基金管理人在样本期内具有负向的择时能力。

4 总结

       T-M模型、H-M模型以及C-L模型都是基于CAPM改良而来,采取的线性回归方法,其本质是将基金与市场基准比较,量化基金的选股及择时能力,缺点是分析维度较为单一,归因结果不够细致,对于基准的选择有较强依赖性。此外,本文所选基金持仓数据为2021年第四季度公布的信息,所选样本期为2019年12月1日至2020年2月29日,得到的结果并不能说明该基金经理水平较低。本文仅供交流学习参考,不构成任何投资建议。炒股有风险,投资需谨慎。

完整代码

import tushare as ts
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf

pro = ts.pro_api('你的token')
data = pd.DataFrame()
df1 = pro.index_daily(ts_code='399300.SZ', start_date='20191201', end_date='20200229')
df2 = pro.index_daily(ts_code='000012.SH', start_date='20191201', end_date='20200229')
df3 = pro.daily(ts_code='600690.SH', start_date='20191201', end_date='20200229')
df4 = pro.daily(ts_code='600703.SH', start_date='20191201', end_date='20200229')
df5 = pro.daily(ts_code='600309.SH', start_date='20191201', end_date='20200229')
df6 = pro.daily(ts_code='300413.SZ', start_date='20191201', end_date='20200229')
df7 = pro.daily(ts_code='600745.SH', start_date='20191201', end_date='20200229')
df8 = pro.daily(ts_code='688099.SH', start_date='20191201', end_date='20200229')
df9 = pro.daily(ts_code='603707.SH', start_date='20191201', end_date='20200229')
df10 = pro.daily(ts_code='600754.SH', start_date='20191201', end_date='20200229')
df11 = pro.daily(ts_code='002415.SZ', start_date='20191201', end_date='20200229')
df12 = pro.daily(ts_code='000739.SZ', start_date='20191201', end_date='20200229')

#600745.SH这只股票在样本期内有停牌
tt = df7['trade_date'].tolist()
dff3 = pd.DataFrame([[0 for x in range(11)]],columns=df3.columns.values)
for i in range(len(df3)):
    if df3.iloc[i,1] not in tt:
        dff1 = df7.loc[:i]
        dff2 = df7.loc[i+1:]
        df7 = dff1.append(dff3, ignore_index = True).append(dff2, ignore_index = True)

hr_rate = df3['pct_chg'].tolist()
sa_rate = df4['pct_chg'].tolist()
wh_rate = df5['pct_chg'].tolist()
mg_rate = df6['pct_chg'].tolist()
wt_rate = df7['pct_chg'].tolist()
jc_rate = df8['pct_chg'].tolist()
jy_rate = df9['pct_chg'].tolist()
jj_rate = df10['pct_chg'].tolist()
hk_rate = df11['pct_chg'].tolist()
pl_rate = df12['pct_chg'].tolist()

fenmu = 6.38+4.72+4.57+3.81+3.74+3.48+3.47+3.42+3.11+3.07
rs = np.array(hr_rate)*6.38/fenmu+np.array(sa_rate)*4.72/fenmu+np.array(wh_rate)*4.57/fenmu+\
     np.array(mg_rate)*3.81/fenmu+np.array(wt_rate)*3.74/fenmu+np.array(jc_rate)*3.48/fenmu+\
     np.array(jy_rate)*3.47/fenmu+np.array(jj_rate)*3.42/fenmu+np.array(hk_rate)*3.11/fenmu+\
     np.array(pl_rate)*3.07/fenmu
data['time'] = df1['trade_date'].tolist()
data['rm'] = df1['pct_chg'].tolist() #市场基准收益率
data['rf'] = df2['pct_chg'].tolist() #无风险利率
data['rs'] = rs #投资组合收益率
data.to_excel('数据1.xlsx',index=False)

df = pd.read_excel('数据1.xlsx',engine='openpyxl',sheet_name='Sheet1')
data=pd.DataFrame()
rm = df['rm'].tolist()
rf = df['rf'].tolist()
rs = df['rs'].tolist()
y = np.array(rs)-np.array(rf)
x1 = np.array(rm)-np.array(rf)
x2 = [a**2 for a in x1]
I1 = []
for i in range(len(rm)):
    if rm[i] > rf[i]:
        I1.append(1)
    else:
        I1.append(0)
x3 = np.multiply(np.array(x1),np.array(I1))
I2 = []
for i in range(len(rm)):
    if rm[i] < rf[i]:
        I2.append(1)
    else:
        I2.append(0)
x4 = np.multiply(np.array(x1),np.array(I2))
data['y'] = y
data['x1'] = x1
data['x2'] = x2
data['x3'] = x3
data['x4'] = x4
est1 = smf.ols(formula='y ~ x1', data=data).fit() #CAPM
print(est1.summary())
est2 = smf.ols(formula='y ~ x1+x2', data=data).fit() #TM
print(est2.summary())
est3 = smf.ols(formula='y ~ x1+x3', data=data).fit() #HM
print(est3.summary())
est4 = smf.ols(formula='y ~ x4+x3', data=data).fit() #CL
print(est4.summary())


### 使用Python进行基金业绩归因分析 #### SHAP库用于解释模型预测 SHAP (SHapley Additive exPlanations) 是一种基于博弈论的方法,可以用来解释机器学习模型的输出。通过计算特征的重要性来理解哪些因素对基金业绩有重要影响[^1]。 ```python import shap import xgboost as xgb from sklearn.model_selection import train_test_split # 假设已经准备好数据集 X 和 y X_train, X_test, y_train, y_test = train_test_split(X, y) model = xgb.XGBRegressor() model.fit(X_train, y_train) explainer = shap.Explainer(model) shap_values = explainer.shap_values(X_test) # 绘制Summary Plot展示各因子对于基金收益的影响程度 shap.summary_plot(shap_values, X_test) ``` 此代码片段展示了如何利用`xgboost`训练回归模型并使用`shap`包中的`summary_plot()`函数绘制图表,从而直观地显示各个属性对基金表现的具体贡献度。 为了更全面地执行基金业绩归因分析,还可以考虑以下几个方面: - **获取高质量的数据源**:确保所使用的市场指数、宏观经济指标以及其他可能影响投资组合价值的信息都是最新且可靠的。 - **构建合理的绩效评估体系**:除了简单的收益率之外,还应关注风险调整后的回报率(如夏普比率)、最大回撤等关键性能指标。 - **应用多元统计方法**:例如线性回归、主成分分析(PCA),甚至是更为复杂的神经网络架构都可以帮助识别不同资产类别之间的关系模式以及它们各自对总体业绩变化趋势的作用机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值