1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 运用Python分析公募基金【量化投资】

运用Python分析公募基金【量化投资】

时间:2018-09-01 20:28:36

相关推荐

运用Python分析公募基金【量化投资】

运用Python分析公募基金

1、背景

学校财富管理课程的期末论文是分析中国各种投资标的的收益,笔者分配到的研究的细分类别为:通过大集合转公募基金的方式,成立的公募基金的收益分析。Python在量化投资,尤其是投资的分析、策略回测等方面有着广泛的运用,所以笔者结合在政胤老师课程中学习的知识,运用Python对基金的收益进行分析。

2、数据来源

“巧妇难为无米之炊”,寻找高质量的数据是分析的第一步。本文的数据来自于Wind客户端。数据分为两个:

链接:/s/1JzJWxM9CyxTotldu5BjbjA 提取码:clki

3、数据分析

3.1 导入数据

defday_data(self):day_data=pd.read_csv(root_path+'/data/大集合转公募基金复权净值day.CSV',encoding='gbk')day_data.rename(columns={'Unnamed:0':'交易日期'},inplace=True)day_data['交易日期']=pd.to_datetime(day_data['交易日期'])#day_rtn.set_index('交易日期',inplace=True)day_data.dropna(axis=1,how='any',inplace=True)returnday_datadefindex_day_data(self):index_day_rtn=pd.read_csv(root_path+'/data/中国基金加权指数day.csv',encoding='gbk')index_day_rtn.rename(columns={'Unnamed:0':'交易日期'},inplace=True)index_day_rtn['交易日期']=pd.to_datetime(index_day_rtn['交易日期'])index_day_rtn['中国基金加权总指数']=index_day_rtn['中国基金加权总指数'].pct_change()returnindex_day_rtn

在导入数据时,我们发现有许多缺失值,这是因为大部分大集合在才转为公募基金,所以仅有几个月的收益。我们在此处采取最简单的数据清洗方式:将含有缺失值的基金删除。

这是整理后的数据:

3.2数据信息提取

观察数据,发现这些公募基金的名字既长又复杂,分析的时候一个一个输入名字肯定非常费时间。通过观察发现,这些基金的名字有个特点:基金名字的前两个或多个字,为基金公司的名字。如:海通的基金就命名为:海通量化价值精选一年持有B、海通海升六个月持有A等。

那么我们运用正则表达式,实现输入证券资管的名称,就得到其旗下的公募基金的名称。

defget_col_name(self):day_data=self.day_data()#匹配正则表达式pattern=pile('^%s'%pany)col_name=day_data.columns.tolist()choose_name=[]fornameincol_name:ifpattern.match(name):choose_name.append(name)print(choose_name)returnchoose_namedefcol_num(self):choose_name=self.get_col_name()num=len(choose_name)#print(num)returnnum

3.3 指数信息和基金信息按日期合并

defchoose_data(self):choose_name=self.get_col_name()day_data=self.day_data()day_data=day_data[['交易日期',choose_name[self.fund_num]]]day_data[choose_name[self.fund_num]]=day_data[choose_name[self.fund_num]].pct_change()day_rtn=day_data#和指数信息合并index_day_rtn=self.index_day_data()equity_day=pd.merge(day_rtn,index_day_rtn,on='交易日期',how='left')equity_day.dropna(axis=0,how='any',inplace=True)equity_day.rename(columns={choose_name[self.fund_num]:'涨跌幅','中国基金加权总指数':'指数涨跌幅'},inplace=True)returnequity_day

此处计算基金收益时运用了dataframe.pct_change()函数(Pandas dataframe.pct_change()函数计算当前元素与之前元素之间的百分比变化。默认情况下,此函数计算前一行的百分比变化)。

此处我们使用的是环比增长,假如想用对数收益率,则不可以使用dataframe.pct_change()函数。

3.4画收益率曲线

为了能够在以后的研究中,方便调用绘画收益率曲线的函数,我们新建一个专门存放自建函数的文档,将函数保存。

#===绘制收益率曲线#绘制策略曲线defdraw_equity_curve(df,data_dict,time=None,pic_size=[16,9],dpi=72,font_size=25,save_path='fig.jpg'):plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=False#plt.style.use('dark_background')plt.figure(figsize=(pic_size[0],pic_size[1]),dpi=dpi)plt.xticks(fontsize=font_size)plt.yticks(fontsize=font_size)forkeyindata_dict:iftime:plt.plot(df[time],df[data_dict[key]],label=key)else:plt.plot(df.index,df[data_dict[key]],label=key)plt.legend(fontsize=font_size)plt.grid()#plt.show(plt.savefig(save_path)

在主程序中调用绘画收益率曲线的函数:

defyield_curve(self):equity=self.choose_data()equity['equity_curve']=(equity['涨跌幅']+1).cumprod()equity['benchmark']=(equity['指数涨跌幅']+1).cumprod()equity=equity[['交易日期','equity_curve','benchmark','涨跌幅','指数涨跌幅']]returnequitydefdraw_curve(self,save_path=r'fig.jpg'):choose_name=self.get_col_name()equity=self.yield_curve()equity=equity.reset_index(drop=True)equity['交易日期']=pd.to_datetime(equity['交易日期'])draw_equity_curve(equity,time='交易日期',data_dict={choose_name[self.fund_num]:'equity_curve','中国基金加权总指数':'benchmark'},save_path=save_path)

3.5 评价指标

对于基金的收益,仅仅看收益率曲线,获得的评价较为主观,要客观比较收益的好坏,还要借助指标,比如:年化收益率、最大回撤等,更加复杂的还有夏普比率、Jensen指数等,需要的评价指标加入一下自定义的函数strategy_evaluate()即可。

#计算策略评价指标defstrategy_evaluate(equity):#===新建一个dataframe保存回测指标results=pd.DataFrame()#===计算累积净值results.loc[0,'累积净值']=round(equity['equity_curve'].iloc[-1],2)#===计算年化收益annual_return=(equity['equity_curve'].iloc[-1])**('1days00:00:00'/(equity['交易日期'].iloc[-1]-equity['交易日期'].iloc[0])*365)-1results.loc[0,'年化收益']=str(round(annual_return*100,2))+'%'#计算当日之前的资金曲线的最高点equity['max2here']=equity['equity_curve'].expanding().max()#计算到历史最高值到当日的跌幅,drowdwonequity['dd2here']=equity['equity_curve']/equity['max2here']-1#计算最大回撤,以及最大回撤结束时间end_date,max_draw_down=tuple(equity.sort_values(by=['dd2here']).iloc[0][['交易日期','dd2here']])#计算最大回撤开始时间start_date=equity[equity['交易日期']<=end_date].sort_values(by='equity_curve',ascending=False).iloc[0]['交易日期']#将无关的变量删除equity.drop(['max2here','dd2here'],axis=1,inplace=True)results.loc[0,'最大回撤']=format(max_draw_down,'.2%')results.loc[0,'最大回撤开始时间']=str(start_date)results.loc[0,'最大回撤结束时间']=str(end_date)returnresults.T

在主程序中调用业绩评价函数

defevaluate(self):equity=self.yield_curve()choose_name=self.get_col_name()#===计算策略评价指标rtn_data=strategy_evaluate(equity)rtn_data.rename(columns={0:choose_name[self.fund_num]},inplace=True)#print(rtn_data)returnrtn_data

3.6运行程序

在运行程序前,要在目录里面建好保存收益率曲线和收益率评价的文件夹,如图所示:

在company_name处输入基金公司的简称,num即返回基金公司下的基金数量,程序自动遍历其旗下基金,并将其收益曲线图存入chart,将其收益评价指标合并后存入sheet。

if__name__=='__main__':company_name='光大'analyse=Analyse(company=company_name,fund_num=0)num=analyse.col_num()df_ret_analyse=pd.DataFrame()foriinrange(num):name=analyse.get_col_name()[i]try:analyse=Analyse(company=company_name,fund_num=i)analyse.draw_curve(save_path=root_path+r'/result\chart/%s.jpg'%name)df=analyse.evaluate()df_ret_analyse=pd.concat([df_ret_analyse,df],axis=1)except:print(name+'数据错误')print(df_ret_analyse)df_ret_analyse.to_csv(root_path+f'/result\sheet\{company_name}retns.csv')

4、运行效果展示

在company_name处输入'光大',查看光大资管的公募基金收益情况。运行后,收益率曲线已经全部保存至/result/chart

点开其中一个查看:

收益指标则保存到了/result/sheet下:

5、完整代码

5.1 函数

importosimportmatplotlib.pyplotaspltimportpandasaspdimportnumpyasnp#===获取项目根目录_=os.path.abspath(os.path.dirname(__file__))#返回当前文件路径root_path=os.path.abspath(os.path.join(_,'..'))#返回根目录文件夹#===绘制收益率曲线#绘制策略曲线defdraw_equity_curve(df,data_dict,time=None,pic_size=[16,9],dpi=72,font_size=25,save_path='fig.jpg'):plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=False#plt.style.use('dark_background')plt.figure(figsize=(pic_size[0],pic_size[1]),dpi=dpi)plt.xticks(fontsize=font_size)plt.yticks(fontsize=font_size)forkeyindata_dict:iftime:plt.plot(df[time],df[data_dict[key]],label=key)else:plt.plot(df.index,df[data_dict[key]],label=key)plt.legend(fontsize=font_size)plt.grid()#plt.show(plt.savefig(save_path)#计算策略评价指标defstrategy_evaluate(equity):#===新建一个dataframe保存回测指标results=pd.DataFrame()#===计算累积净值results.loc[0,'累积净值']=round(equity['equity_curve'].iloc[-1],2)#===计算年化收益annual_return=(equity['equity_curve'].iloc[-1])**('1days00:00:00'/(equity['交易日期'].iloc[-1]-equity['交易日期'].iloc[0])*365)-1results.loc[0,'年化收益']=str(round(annual_return*100,2))+'%'#计算当日之前的资金曲线的最高点equity['max2here']=equity['equity_curve'].expanding().max()#计算到历史最高值到当日的跌幅,drowdwonequity['dd2here']=equity['equity_curve']/equity['max2here']-1#计算最大回撤,以及最大回撤结束时间end_date,max_draw_down=tuple(equity.sort_values(by=['dd2here']).iloc[0][['交易日期','dd2here']])#计算最大回撤开始时间start_date=equity[equity['交易日期']<=end_date].sort_values(by='equity_curve',ascending=False).iloc[0]['交易日期']#将无关的变量删除equity.drop(['max2here','dd2here'],axis=1,inplace=True)results.loc[0,'最大回撤']=format(max_draw_down,'.2%')results.loc[0,'最大回撤开始时间']=str(start_date)results.loc[0,'最大回撤结束时间']=str(end_date)returnresults.T

5.2主程序

importpandasaspdimportrefrom基金收益分析.func.myfuncimport*classAnalyse(object):def__init__(self,company='海通',fund_num=0):pany=companyself.fund_num=fund_numpassdefday_data(self):day_data=pd.read_csv(root_path+'/data/大集合转公募基金复权净值day.CSV',encoding='gbk')day_data.rename(columns={'Unnamed:0':'交易日期'},inplace=True)day_data['交易日期']=pd.to_datetime(day_data['交易日期'])#day_rtn.set_index('交易日期',inplace=True)day_data.dropna(axis=1,how='any',inplace=True)returnday_datadefindex_day_data(self):index_day_rtn=pd.read_csv(root_path+'/data/中国基金加权指数day.csv',encoding='gbk')index_day_rtn.rename(columns={'Unnamed:0':'交易日期'},inplace=True)index_day_rtn['交易日期']=pd.to_datetime(index_day_rtn['交易日期'])index_day_rtn['中国基金加权总指数']=index_day_rtn['中国基金加权总指数'].pct_change()returnindex_day_rtndefget_col_name(self):day_data=self.day_data()#匹配正则表达式pattern=pile('^%s'%pany)col_name=day_data.columns.tolist()choose_name=[]fornameincol_name:ifpattern.match(name):choose_name.append(name)print(choose_name)returnchoose_namedefcol_num(self):choose_name=self.get_col_name()num=len(choose_name)#print(num)returnnumdefchoose_data(self):choose_name=self.get_col_name()day_data=self.day_data()day_data=day_data[['交易日期',choose_name[self.fund_num]]]day_data[choose_name[self.fund_num]]=day_data[choose_name[self.fund_num]].pct_change()day_rtn=day_data#和指数信息合并index_day_rtn=self.index_day_data()equity_day=pd.merge(day_rtn,index_day_rtn,on='交易日期',how='left')equity_day.dropna(axis=0,how='any',inplace=True)equity_day.rename(columns={choose_name[self.fund_num]:'涨跌幅','中国基金加权总指数':'指数涨跌幅'},inplace=True)returnequity_daydefyield_curve(self):equity=self.choose_data()equity['equity_curve']=(equity['涨跌幅']+1).cumprod()equity['benchmark']=(equity['指数涨跌幅']+1).cumprod()equity=equity[['交易日期','equity_curve','benchmark','涨跌幅','指数涨跌幅']]returnequitydefdraw_curve(self,save_path=r'fig.jpg'):choose_name=self.get_col_name()equity=self.yield_curve()equity=equity.reset_index(drop=True)equity['交易日期']=pd.to_datetime(equity['交易日期'])draw_equity_curve(equity,time='交易日期',data_dict={choose_name[self.fund_num]:'equity_curve','中国基金加权总指数':'benchmark'},save_path=save_path)defevaluate(self):equity=self.yield_curve()choose_name=self.get_col_name()#===计算策略评价指标rtn_data=strategy_evaluate(equity)rtn_data.rename(columns={0:choose_name[self.fund_num]},inplace=True)#print(rtn_data)returnrtn_dataif__name__=='__main__':company_name='光大'analyse=Analyse(company=company_name,fund_num=0)num=analyse.col_num()df_ret_analyse=pd.DataFrame()foriinrange(num):name=analyse.get_col_name()[i]try:analyse=Analyse(company=company_name,fund_num=i)analyse.draw_curve(save_path=root_path+r'/result\chart/%s.jpg'%name)df=analyse.evaluate()df_ret_analyse=pd.concat([df_ret_analyse,df],axis=1)except:print(name+'数据错误')print(df_ret_analyse)df_ret_analyse.to_csv(root_path+f'/result\sheet\{company_name}retns.csv')

6、结语

此处的分析作为分析的一个框架,可以添加更多的有趣的研究内容,比如:对基金的收益数据可以计算其期望,方差,峰度,偏度等指标,对收益率也可以计算夏普比率等指标。可以更加深入的分析基金的收益的变动。

最后强烈推荐。政胤老师的python课程,科班程序员出生的帅帅老师,代码写的非常规范,初学者可以少走弯路。并且政胤老师的答疑非常及时,仔细回复每个问题,笔者每次遇到网上查询不到答案的问题时,都会马上请教政胤老师,节省了许多自己debug的时间!(友情推送)

总之,无论是初学者从头学习,还是老手查漏补缺,找一位专家答疑,政胤的课程都物超所值。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。