作者:量化小白Literacy
题图:量化小白Literacy微信公众号
首先祝大家节日快乐!今天连载一篇简单的技术文!上期我们介绍了根据私募基金的净值如何绘制动态回撤图并根据动态回撤图对基金的运行情况进行分析,本期我们介绍一下如何使用python代码简单计算某个指数、板块或者全部A股的历史PE或者PB等。
前几期连载内容可查看如下参考:
私募基金数量化绩效评价体系(一)
私募基金数量化绩效评价体系(二)风险类指标
私募基金数量化绩效评价体系(三)风险调整收益
私募基金数量化绩效评价体系(四)选股择时及业绩持续性指标
私募基金数量化绩效评价体系(五)-Stutzer index的计算
私募基金数量化绩效评价体系(六)-Hurst指数的计算
私募基金数量化绩效评价体系(七)-如何绘制动态回测图?
本文呈现的结果如下(在本文的框架下读者可以修改计算的板块对象、PE还是PB指标,分位点的绘制等):

本文的代码提供两种情境下的解决方案:
1、如果读者具有wind终端的使用权限,可以安装python接口,直接调用以下代码,根据需求设定一下行业数据集代码或者全A数据集代码即可以计算。
2、如果读者不具备wind终端的使用权限,没关系,本公众号可以提供历史数据供读者使用,并使用下面的绘图代码同样可以得出相应的结果。
代码如下:
# -*- coding: utf-8 -*-import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport openpyxlimport timestart = time.time()plt.rcParams['font.sans-serif']=['SimHei'] # 避免绘制图形时中文文本乱码pd.set_option('display.float_format',lambda x: '%.5f'%x) # 浮点类型保留5位小数pd.set_option('display.max_rows', 30) # 显示的最多行数plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号plt.rcParams['font.size'] = 15 #设置图像中默认字体# Windpy读取数据、准备数据阶段# 封装函数,读取数据,给定日期读取全部A股在特定日期的PE值from WindPy import ww.start()def extract_pe(sec_id,date):codes=w.wset("sectorconstituent","date={};sectorid={}".format(date,sec_id)) #取数数据集代码codes=codes.Data[1]_,pedata=w.wss(codes,"windcode,sec_name,pe_ttm,pb_lf","tradeDate={};ruleType=3".format(date),usedf=True)pedata['date']=datereturn pedatasec_id='a001010100000000' # 全部A股#读取2019-4-30到2020-8-31的数据pedata=pd.DataFrame()for i in pd.date_range('2019-04-30','2020-08-31',freq='M'):df=extract_pe(sec_id,i.strftime('%Y-%m-%d'))pedata=pd.concat([pedata,df])pedata.rename(columns={'WINDCODE':'code','SEC_NAME':'name','PE_TTM':'pe','PB_LF':'pb'},inplace=True)pedata['date']=pd.to_datetime(pedata['date']) # 循环读取数据#与已有的2014-1-31 到2019-3-31日数据合并pedata0=pd.read_excel('pe_data.xlsx') # 现有数据读入pe_ttm=pd.concat([pedata,pedata0],ignore_index=True) # 合并数据,丢弃原始的无意义的indexpe_ttm.sort_values(by='date',ascending=True,inplace=True)pe_ttm.dropna(inplace=True) # 清理缺失值pe_ttm.drop(columns=['pb'],inplace=True) #剔除无关的变量print('数据准备完毕...')end1=time.time()print("数据准备耗时 : %.03f seconds" %(end1-start))# 准备处理阶段# 按月计算每月所有A股的平均PE,需要剔除那些PE<0或PE比较异常的数据data_grouped=pe_ttm.groupby('date') # 按月将数据分组def filter(group):group=group[(group['pe']>0) & (group['pe']<group['pe'].quantile(0.95))]return group.mean() # 定义一个函数,按月首先筛选出合适的数据,其次进行数据的聚合pe_ttm_mean=data_grouped.apply(filter) # 应用定义号的函数,按每个分组对象进行重复计算,最后得出每月的结果print('数据处理完毕...')end2=time.time()print("数据处理耗时 : %.03f seconds" %(end2-end1))#绘制图像q_arr=pe_ttm_mean.quantile(list(np.arange(11)/10)).values # 计算分位数q_arr.reshape(len(q_arr)) # 将多维结果转为一维q_list=list(q_arr.reshape(len(q_arr))) # 取出分位数的数值,结果为list,便于绘制平行线pe_ttm_mean.plot(color='k',title='全A等权重PE',rot=90,figsize=(10,6),fontsize=12,linewidth=2)font={'family':'Times New Roman','weight':'normal','size':12}plt.xlabel('month',font)plt.ylabel('等权PE',font)plt.xticks(ticks=pd.date_range(pe_ttm_mean.index[0],pe_ttm_mean.index[-1],freq='Q'))pd.plotting.register_matplotlib_converters()plt.hlines(q_list[0:5],pe_ttm_mean.index[0],pe_ttm_mean.index[-1],color='r',linestyle='dashed',linewidth=1)plt.hlines(q_list[5:],pe_ttm_mean.index[0],pe_ttm_mean.index[-1],color='g',linestyle='dashed',linewidth=1)print('图形绘制完毕...')end3=time.time()print("程序执行完毕,一共耗时: %.03f seconds" %(end3-start))
版权声明:文章版权归原作者所有,部分文章由作者授权本平台发布,若有其他不妥之处的可与小编联系。
