基金归因Brinson模型

基金归因Brinson模型,第1张

基金归因Brinson模型

本文是使用wind 数据接口和python语言进行brinson 模型分析的一个简单尝试,为了使本文代码运行起来,必须有wind 量化平台的支持,其中的WindPy 是wind自己的python程序包。

一、程序注释

1、数据获取
#基准成分内容注解
总体思路是利用wind各种数据接口生成如下数据文件,其中行业分类使用的是wind 一级行业分类标准
##目标基金前五十大重仓股注解
公募基金年报和半年报都会披露所有股票尺长,我们选择基金的前五十大持仓进行分析,最后生成如下数据文件
2、Brinson 归因分析
然后合并两部分数据,用brinson模型分析,下面都是Brinson模型的内容。具体的数学公式为

二、程序源码
from WindPy import *
import pandas as pd
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
from scipy.stats.mstats import winsorize

w.start()
#基准成分
e,df_bench=w.wset("indexconstituent", "date=20210630;windcode=000300.SH", usedf=True)
df_bench.index=df_bench['wind_code']
st_list=list(df_bench['wind_code'])

#行业收益ri
e,df_return=w.wsd(st_list, "close", "ED-2Q", "2021-06-30", "Period=Q", usedf=True)
df_return.index=['2020-12-31', '2021-03-31', '2021-06-30']
df_return=df_return.T
df_return['收益率']=df_return['2021-06-30']/df_return['2020-12-31']-1
df_ri=pd.concat([df_bench,df_return],axis=1)
industry_js=[]
return_js=[]
for j in list(set(df_ri['industry'])):
    df_rij=df_ri[df_ri['industry']==j]
    df_rij['权重*收益率']=df_rij['i_weight']*df_rij['收益率']
    return_j=(df_rij['权重*收益率'].sum())/(df_rij['i_weight'].sum())
    industry_js.append(j)
    return_js.append(return_j)
df_industry=pd.Dataframe({"industry":industry_js,"rbi":return_js})
df_industry.set_index(['industry'], inplace=True)

#行业权重wbi
grouped=df_bench['i_weight'].groupby(df_bench['industry'])
df_weight=(grouped.sum()/100).to_frame()
df_weight.rename(columns={'i_weight':'wbi'},inplace=True)
df_weight
 
#基准数据
df_benchdata=pd.concat([df_industry,df_weight],axis=1)
df_benchdata
#目标基金前五十大重仓股
df_fund_sts=pd.Dataframe()
for i in range(1,51):
    e,df_fund_st=w.wss("003751.OF", "prt_topstockcode,prt_topstockname,prt_topstockvalue", "rptDate=20210630;order="+str(i), usedf=True)
    df_fund_sts=pd.concat([df_fund_sts,df_fund_st],axis=0)

def func(x):
    if x[0]=='6':
        val=x+'.SH'
    else:
        val=x+'.SZ'
    return val
           
df_fund_sts['wind_code']=df_fund_sts['PRT_TOPSTOCKCODE'].apply(lambda x:func(x))
df_fund_sts
stf_list=list(df_fund_sts['wind_code'])
#股票所属行业
wind_codes=[]
industrys=[]
for i in stf_list:
    wind_codes.append(i)
    industry=w.wsd(i, "industry2", "2021-06-30", "2021-06-30", "industryType=2;industryStandard=1;Fill=Previous").Data[0][0]
    industrys.append(industry)

df_industry = pd.Dataframe({"wind_code":wind_codes,"行业":industrys})
df_industry.set_index(['wind_code'], inplace=True)
df_fund_sts.set_index(['wind_code'], inplace=True)
df_w=pd.concat([df_fund_sts,df_industry],axis=1)
#个股收益
e,df_return=w.wsd(stf_list, "close", "ED-2Q", "2021-06-30", "Period=Q", usedf=True)
df_return.index=['2020-12-31', '2021-03-31', '2021-06-30']
df_return=df_return.T
df_return['收益率']=df_return['2021-06-30']/df_return['2020-12-31']-1
#行业权重计算
df_ri=pd.concat([df_w,df_return],axis=1)
grouped=df_ri['PRT_TOPSTOCKVALUE'].groupby(df_ri['行业'])
df_weight=grouped.sum().to_frame()
df_weight=df_weight/df_weight.sum()
df_weight.rename(columns={'PRT_TOPSTOCKVALUE':'wfi'},inplace=True)
#行业收益率计算
industry_js=[]
return_js=[]
for j in list(set(df_ri['行业'])):
    df_rij=df_ri[df_ri['行业']==j]
    df_rij['权重*收益率']=df_rij['PRT_TOPSTOCKVALUE']*df_rij['收益率']
    return_j=(df_rij['权重*收益率'].sum())/(df_rij['PRT_TOPSTOCKVALUE'].sum())
    industry_js.append(j)
    return_js.append(return_j)
df_industry=pd.Dataframe({"行业":industry_js,"rfi":return_js})
df_industry.set_index(['行业'], inplace=True)
df_funddata=pd.concat([df_industry,df_weight],axis=1)
df_funddata
#数据合并
df_data=pd.concat([df_benchdata,df_funddata],axis=1)
#单期Brinson模型
#数据缺失值替换
t=df_data.fillna(value=0)
#开始计算
t['Q1']=t['rbi']*t['wbi']
t['Q2']=t['rbi']*t['wfi']
t['Q3']=t['rfi']*t['wbi']
t['Q4']=t['rfi']*t['wfi']
result = pd.Dataframe()
result['板块配置'] = t['Q2']-t['Q1']-(t['wfi']-t['wbi'])*sum(t['Q1'])
result['板块内选股'] = t['Q3']-t['Q1']
result['交互收益'] = t['Q4']-t['Q3']-t['Q2']+t['Q1']
result['总超额收益'] = t['Q4']-t['Q1']
result.loc['合计'] = result.apply(lambda x:x.sum(),axis=0)
AR=result.loc['合计','板块配置']
SR=result.loc['合计','板块内选股']+result.loc['合计','交互收益']
total_R=result.loc['合计','总超额收益']
print('AR={:.2%},SR={:.2%},总超额收益={:.2%}'.format(AR,SR,total_R))

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5670572.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存