心塞,昨晚快要写完的时候 crash 了,不明原因显示 “Unreadable Notebook”,只好重新再写。。。。。(大哭脸)
聚宽的技术大大有什么解决办法吗
import pandas as pd import numpy as npfrom jqdata import *from IPython.display import displayfrom ipywidgets import *import seaborn as snsimport matplotlib.pyplot as plt
历史走势对比¶
我们首先尝试对比沪深300成分股沪深300指数的走势,来熟悉 widgets 的功能。
#-# 数据准备#-stocks = get_index_stocks('000300.XSHG') # 获取沪深300所有成分股,但历史成分股是变化的,这里获取的是当前的成分股情况dates = get_all_trade_days() # 获取所有交易日,装入start,endstart, end = [], []for i in dates:d = i.isoformat()start.append(d)end.append(d)
#-# 走势对比图#-def p(stock, start, end):df_price = get_price('000300.XSHG', start_date=start, end_date=end, fields='close')df_stock = get_price(stock, start_date=start, end_date=end, fields='close')df = pd.concat([df_price, df_stock], axis=1) df.columns = ['000300.XSHG',stock] df.plot(secondary_y='000300.XSHG',color=['b','yellow'], figsize=(14,5)) plt.title('%s & 000300 historical trends' % stock,fontsize=20)print start + "——" + end# p('000001.XSHE','2010-01-01','2015-01-01')
下面开始召唤帅逼 widgets。
#-# 将 stock start end 分别用 widgets 的 select 功能实现# 并装入一个 box#-container = widgets.HBox() # HBox children组件横排放置的boxstock_list = widgets.Select(options=stocks, description='stock_list', width=200, fon_size=20, margin=5)start_date = widgets.Select(options=start, description='start_date', width=200, fon_size=20, margin=5) end_date = widgets.Select(options=end, description='end_date', width=200, fon_size=20, margin=5) container.children = (stock_list, start_date, end_date)
#-# 使用 interactive 功能 将 widgets 模块和数据进行link互动#-i = interactive(p,stock = stock_list, start = start_date, end = end_date)display(container)
2008-05-07——2016-12-30
召唤成功,然后就可以手动选择目标股票以及起止日期,来观察目标股票于沪深300的走势对比情况,是不是很任性?
行业相关性对比¶
接下来再让帅逼带我们飞得更远一点,我们试试用 widgets 展示行业的相关性:
但问题是,如何衡量各行业的表现情况,如何能够获得行业指数当然是最好的。但是在聚宽的数据库中,行业划分用的是一套系统(只能获得行业成分股信息),在指数数据中的行业指数又是另一套系统,他们无法相互对应。所以楼主只好自己整理了下申万一级分类的15个行业从2010年到2016年的指数数据(下载见正文链接)。
[u'申万农林牧渔', u'申万采掘', u'申万化工', u'申万钢铁', u'申万有色金属', u'申万电子', u'申万家用电器',u'申万食品饮料', u'申万纺织服装', u'申万轻工制造', u'申万医药生物', u'申万公用事业', u'申万交通运输',u'申万休闲服务', u'申万综合']
因为主题的原因,这里不对行业进行平稳性检验、相关性模型分析等,只使用简单的皮尔斯相关系数 corr 来对比各行业相关性。(其实楼主也不会。。。。)
indicates = pd.read_csv('申万一级行业指数.csv')indicates.head()
ticker | secShortName | tradeDate | closeIndex | turnoverVol | turnoverValue | CHGPct | |
---|---|---|---|---|---|---|---|
0 | 801010 | 申万农林牧渔 | 2010-01-04 | 2058.27 | 74726 | 935388 | 0.00875 |
1 | 801010 | 申万农林牧渔 | 2010-01-05 | 2081.28 | 55721 | 668003 | 0.01118 |
2 | 801010 | 申万农林牧渔 | 2010-01-06 | 2048.70 | 45147 | 557775 | -0.01565 |
3 | 801010 | 申万农林牧渔 | 2010-01-07 | 1999.31 | 53747 | 587362 | -0.02411 |
4 | 801010 | 申万农林牧渔 | 2010-01-08 | 2018.81 | 37226 | 420383 | 0.00975 |
#-# 数据读取、筛选、整理#-indicates = pd.read_csv('申万一级行业指数.csv')indicates = indicates[['secShortName','tradeDate','CHGPct']]indicates = indicates.pivot(index='tradeDate', columns='secShortName', values='CHGPct')indicates.head()
secShortName | 申万交通运输 | 申万休闲服务 | 申万公用事业 | 申万农林牧渔 | 申万化工 | 申万医药生物 | 申万家用电器 | 申万有色金属 | 申万电子 | 申万纺织服装 | 申万综合 | 申万轻工制造 | 申万采掘 | 申万钢铁 | 申万食品饮料 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
tradeDate | |||||||||||||||
2010-01-04 | -0.00665 | -0.00657 | -0.00598 | 0.00875 | -0.00808 | -0.00378 | -0.01292 | -0.00229 | 0.02230 | -0.00027 | 0.00480 | 0.00399 | -0.00949 | -0.01001 | -0.00126 |
2010-01-05 | 0.01141 | 0.01083 | 0.00733 | 0.01118 | 0.00755 | 0.00399 | -0.01234 | 0.03184 | 0.02283 | 0.00729 | 0.00791 | 0.00632 | 0.03296 | -0.00438 | 0.00385 |
2010-01-06 | -0.00404 | -0.00677 | -0.00095 | -0.01565 | -0.01277 | 0.00010 | -0.02200 | 0.00398 | 0.00052 | -0.00094 | -0.00180 | -0.00377 | 0.00200 | 0.00859 | -0.01334 |
2010-01-07 | -0.01879 | 0.00460 | -0.02106 | -0.02411 | -0.02391 | -0.02431 | -0.03256 | -0.01190 | -0.02341 | -0.02467 | -0.01409 | -0.01736 | -0.01665 | -0.03041 | -0.02443 |
2010-01-08 | 0.00783 | 0.01450 | 0.00730 | 0.00975 | -0.00267 | 0.00634 | 0.01707 | -0.01059 | 0.02406 | 0.00534 | 0.01421 | 0.01033 | -0.01342 | 0.00304 | 0.00023 |
先画个图来观察下:
indicates.plot(figsize=(50,12))
<matplotlib.axes._subplots.AxesSubplot at 0x7fae28592390>
然后再来尝试下相关性热力图。
不过 seaborn 中文一直显示框框,真的是要逼死强迫症,楼主暂时没找到简便的解决方法,求教大神~
而且貌似后面的帅哥 widgets 也不认识中文,好吧,那我们就来秀一秀英文。
indicates.columns
Index([u'申万交通运输', u'申万休闲服务', u'申万公用事业', u'申万农林牧渔', u'申万化工', u'申万医药生物', u'申万家用电器', u'申万有色金属', u'申万电子', u'申万纺织服装', u'申万综合', u'申万轻工制造', u'申万采掘', u'申万钢铁', u'申万食品饮料'], dtype='object', name=u'secShortName')
#-# 将 columns 名称换为英文#-I_am_yingwen = ['Transportation','Leisureservice','Publicservice','Agriculture','Chemical','Medical','Electrical','Metal','Electronic','Clothes','Integrated','Lightindustry','Mining','Steel','Food']indicates.columns = I_am_yingwen
#-# 计算各行业相对其他行业的相关系数,并保存到 DataFrame 中#-n = indicates.shape[1] # 15个行业corr_matrix = np.zeros((n,n)) # 15 X 15 的空数据集for i in range(n):for j in range(n):corr = pd.Series.corr(indicates.iloc[:,i],indicates.iloc[:,j]) # 计算相关系数 corr_matrix[i,j] = corr # 将相关系数填入数据集corr_df = pd.DataFrame(corr_matrix,index=indicates.columns,columns=indicates.columns)
#-# 相关性热力图#-sns.heatmap(corr_df*100,cmap= plt.cm.Greys, annot= True)
<matplotlib.axes._subplots.AxesSubplot at 0x7fae230f7c10>
一眼看出食品饮料跟其他行业的相关性是最低的。
同时,纺织业、综合业和轻工业之间的相关度最高。
而且整体的行业相关度在65%以上,这样我们使用 widgets 的效果可能并不会太好,还是来看看吧~
#-# 作图函数#-def corr_p(industry):tmp = corr_df[[industry]].drop(industry,axis=0).sort(industry,ascending=False) # 截取行业数据,并排序tmp = tmp.reset_index()tmp.columns = ['industry','corr'] fig = plt.figure(figsize=(10, 6)) # 做相关性分布直方图ax = fig.add_subplot(111)sns.set_color_codes("pastel")sns.barplot(x='corr',y='industry',data=tmp, color="b")plt.title('Correlationship between %s and other industries' % industry ,fontsize=20)ax.set_xlim(left=0.6, emit=True, auto=True)# ax.set(xlim=(0.6))sns.despine(left=True, bottom=True)# corr_p('Food')
再次召唤 widgets
#-# 使用 Dropdown 组件#-w_industry = widgets.Dropdown(options=I_am_yingwen,description='industry_select:',border_radius=4)interact(corr_p,industry=w_industry)
讨论¶
seaborn 无法显示中文的问题。
本来楼主在做历史走势对比的时候,用的也是 widgets 的 Dropdown 组件,但是 stock,以及日期的数据太长,Dropdown 菜单又无法滚动,不知道有么有办法可以解决这个问题,
用 widgets 还可以做很多有趣的东西,尤其是在数据处理和可视化方面,本篇楼主只是抛砖引玉~大伙再接再厉。
然后可能是widgets库不兼容吗?楼主在再写一遍的时候,又有几次提示notebook dead,吓死宝宝了,大家做好防范。