本文是使用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))
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)