#请多指教:代码作者的知乎首页:https://www.zhihu.com/people/kasefondue/posts
##引入所需使用的包
import pandas as pd
import os
import time
import datetime
import tushare as ts
import matplotlib
import matplotlib.pyplot as plt
ts.set_token('此处填写你的token')
##指定工作路径
os.chdir('D:\教学\金融量化分析python\指数的顶与底')
pro = ts.pro_api()
##修复制图中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei'] #修复中文乱码
plt.rcParams['axes.unicode_minus'] = False #修复负号乱码
##定义函数,该函数可以直接实现自动化下载数据-清洗数据-合并数据-添加分位数-绘图-导出
def get_data1(startime,endtime,i):
##基本思路是用180天为间隔下载tushare数据,从而避免一天天下载数据可能导致的访问量超载
gap=180
##制定空dataframe
datalist=pd.DataFrame()
datalist_c=pd.DataFrame()
##设计时间变量,stime和etime实现对输入时间(字符格式)的时间元组化,strf则是再次字符化,Dtime和DDtime则是用于中间下载数据所用的中间变量,相当于一个桥的作用
stime=datetime.datetime.strptime(startime,'%Y/%m/%d') ##stime为时间元祖
etime=datetime.datetime.strptime(endtime,'%Y/%m/%d') ##etime为时间元祖
strf_stime=stime.strftime('%Y%m%d')
strf_etime=etime.strftime('%Y%m%d')
Dtime=stime
DDtime=stime+datetime.timedelta(days=gap)
print('Downloading',i)
while Dtime<=etime:
strf_Dtime=Dtime.strftime('%Y%m%d')
strf_DDtime=DDtime.strftime('%Y%m%d')
df=pro.index_dailybasic(start_date=strf_Dtime,end_date=strf_DDtime, ts_code=i,fields='trade_date,ts_code,turnover_rate,pe,pb')
datalist=pd.concat([datalist,df],axis=0) ##滚动合并数据
df=pro.index_daily (ts_code=i,start_date=strf_Dtime,end_date=strf_DDtime,fields='trade_date,close')
datalist_c=pd.concat([datalist_c,df],axis=0) ##滚动合并数据
Dtime+=datetime.timedelta(days=gap)
DDtime+=datetime.timedelta(days=gap)
##由于最后剩下的数据一定是不满180天的,设定以下代码来下载余下的数据,基本思路和上面相同
RTime=Dtime-datetime.timedelta(days=gap)
strf_RTime=RTime.strftime('%Y%m%d')
print('Downloading Remaining Data between',strf_RTime,'and',strf_etime)
df=pro.index_dailybasic(start_date=strf_RTime,end_date=strf_etime, ts_code=i,fields='trade_date,ts_code,turnover_rate,pe,pb')
datalist=pd.concat([datalist,df],axis=0)
df=pro.index_daily (ts_code=i,start_date=strf_RTime,end_date=strf_etime,fields='trade_date,close')
datalist_c=pd.concat([datalist_c,df],axis=0)
##重设索引为trade_date
datalist.set_index(['trade_date'], inplace=True)
datalist_c.set_index(['trade_date'], inplace=True)
##有些数据表可以完美合并,有些不可以(可能由于dailybasic和daily获取的数据时间上不能完全重叠),因此设计以下合并方法,try为完美合并,except为不完美合并的解决方案
try:
datalist_New=pd.concat([datalist,datalist_c],axis=1)
datalist_New.reset_index(drop=False, inplace=True) #重设索引值
except:
datalist_New=pd.merge(datalist,datalist_c,left_on=['trade_date'],right_on=['trade_date'])
datalist_New.reset_index(drop=False, inplace=True) #重设索引值 drop是删除原有索引,这里不删除,因为原有索引是trade_date,很重要
datalist_New = datalist_New.dropna() #删除空数据
datalist_New = datalist_New.drop_duplicates(['ts_code','trade_date'],keep='last') #删除冗余数据,如果ts_code和tradedate相同,只保留最后(新)的数据
datalist_New.reset_index(drop=True, inplace=True) #重设索引值
datalist_New=datalist_New.rename(columns={'trade_date':'date'}) ##重命名trade_date一列为date
print('Finished Data-Washing of',i)
datalist_New.to_csv('D:\教学\金融量化分析python\指数的顶与底\\'+i+'.csv')
print('Finished exporting',i,'between',strf_stime,'and',strf_etime)
time.sleep(0.2) #防止访问量超载
##开始画图,以下循环实现批量时间元组化字符串时间
n=0
while n
x=str(datalist_New.date[n])
datalist_New.date[n]=datetime.datetime.strptime(x,'%Y%m%d')
n+=1
##设立字典转df,实现后面需要的自动化的映射
dic={'list_name':['datalist_New.turnover_rate','datalist_New.pe','datalist_New.pb','datalist_New.close'],'name':['turnover_rate','PE','PB','ClosePrice']}
df_dic=pd.DataFrame(dic,index=[1,2,3,4])#转化为df
df_dic=df_dic.set_index(['list_name'],drop=True)#更改索引
n=[datalist_New.turnover_rate,datalist_New.pe,datalist_New.pb,datalist_New.close]
##自动化绘图模块
q=0
plt.figure(figsize=(21,15))
for z in n:
plt.subplot(2,2,q+1)
plt.scatter(x=datalist_New.date,y=z,c='b',marker='.',s=15,label=df_dic.iloc[q,0])#z在df_doc里面对应'name'栏里的数值,(0,0)对应的是'turnover_rate'
plt.xticks(fontsize=13)
plt.xlabel('Time',fontsize=13)
plt.yticks(fontsize=13)
plt.ylabel(df_dic.iloc[q,0],fontsize=13)
plt.grid()
plt.title(df_dic.iloc[q,0]+' of '+i,fontsize=13)
#计算分位数
a=z.quantile(0.1)
b=z.quantile(0.25)
c=z.quantile(0.5)
d=z.quantile(0.75)
e=z.quantile(0.9)
plt.axhline(y=a,c='c',ls='-',lw=2,label='10percentile')
plt.axhline(y=b,c='g',ls='-',lw=2,label='25percentile')
plt.axhline(y=c,c='r',ls='-',lw=2,label='50percentile')
plt.axhline(y=d,c='m',ls='-',lw=2,label='75percentile')
plt.axhline(y=e,c='y',ls='-',lw=2,label='90percentile')
plt.legend(loc=0,fontsize=13)
q+=1
plt.savefig(r'D:\教学\金融量化分析python\指数的顶与底\\'+i+'.png')#保存图片
print('Exported PNG of',i)
##以下为执行代码,代入函数:
list_stockindex=['000001.SH','399001.SZ','399006.SZ','000016.SH','000905.SH','399005.SZ']
for i in list_stockindex:
get_data1('2005/01/01','2020/05/01',i)
print('Finished the whole Process')
#第一次写的python project,请多指正!
#如果喜欢,请留下你的鼓励,谢谢!
#代码作者的知乎首页:https://www.zhihu.com/people/kasefondue/posts
#更多文章可参见知乎专栏。