內容來自:微信公眾號:python金融量化 已獲得授權
關注可了解更多的金融與Python乾貨。
#先引入後面可能用到的包(package)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#正常顯示畫圖時出現的中文
from pylab import mpl
#這裡使用微軟雅黑字體
mpl.rcParams['font.sans-serif']=['SimHei']
#畫圖時顯示負號
mpl.rcParams['axes.unicode_minus']=False
import seaborn as sns #畫圖用的
import tushare as ts
#Jupyter Notebook特有的magic命令
#直接在行內顯示圖形
%matplotlib inline
sh=ts.get_k_data(code='sh',ktype='D',
autype='qfq', start='1990-12-20')
#code:股票代碼,個股主要使用代碼,如『600000』
#ktype:'D':日數據;『m』:月數據,『Y』:年數據
#autype:復權選擇,默認『qfq』前復權
#start:起始時間
#end:默認當前時間
#查看下數據前5行
sh.head(5)
能看到的第一列是索引,對於pandas的數據結構,最後將索引設置為時間序列,方便後面可視化分析。
#將數據列表中的第0列'date'設置為索引
sh.index=pd.to_datetime(sh.date)
#畫出上證指數收盤價的走勢
sh['close'].plot(figsize=(12,6))
plt.title('上證指數1990-2018年走勢圖')
plt.xlabel('日期')
plt.show()
上面的指數走勢圖還是可以清晰看出,股指分別在2007年和2015年有兩波大牛市,然後又從高峰跌入谷底,目前處於下跌通道。真是辛辛苦苦28年,一夜回到解放前o(╥﹏╥)o
描述性統計#pandas的describe()函數提供了數據的描述性統計
#count:數據樣本,mean:均值,std:標準差
sh.describe().round(2)
結果如下表所示:
從上述結果可以看出,上證指數從1990年12月20日至2018年11月7日(最後交易日是當前運行時間),一共有6645個樣本,均值為1937.52點,標準差為1079.51點(波動還是比較大的),最大值是6092.06點。
#再查看下每日成交量
#2006年市場容量小,交易量比較小,我們從2007年開始看
sh.loc["2007-01-01":]["volume"].plot(figsize=(12,6))
plt.title('上證指數2007-2018年日成交量圖')
plt.xlabel('日期')
plt.show()
上圖的成交量反映了一個有趣的現象,2014-2015年的大牛市很可能是天量的交易推動起來的,因為這期間實體經濟並不景氣,央行多次降息降準,貨幣寬鬆,資金流入股市,銀行理財等影子銀行在這期間瘋狂擴張,場外加槓桿和配資主導了這一場牛市。感興趣的朋友可以結合貨幣供給、實體經濟指標、影子銀行等數據一起分析,進行交叉驗證。
均線分析#這裡的平均線是通過自定義函數,手動設置20,52,252日均線
#移動平均線:
ma_day = [20,52,252]
for ma in ma_day:
column_name = "%s日均線" %(str(ma))
sh[column_name] =sh["close"].rolling(ma).mean()
#sh.tail(3)
#畫出2010年以來收盤價和均線圖
sh.loc['2010-10-8':][["close",
"20日均線","52日均線","252日均線"]].plot(figsize=(12,6))
plt.title('2010-2018上證指數走勢圖')
plt.xlabel('日期')
plt.show()
#2005年之前的數據噪音太大,主要分析2005年之後的
sh["日收益率"] = sh["close"].pct_change()
sh["日收益率"].loc['2005-01-01':].plot(figsize=(12,4))
plt.xlabel('日期')
plt.ylabel('收益率')
plt.title('2005-2018年上證指數日收益率')
plt.show()
###這裡我們改變一下線條的類型
#(linestyle)以及加一些標記(marker)
sh["日收益率"].loc['2014-01-01':].plot(figsize=
(12,4),linestyle="--",marker="o",color="g")
plt.title('2014-2018年日收益率圖')
plt.xlabel('日期')
plt.show()
#分析下常見的幾個股票指數
stocks={'上證指數':'sh','深證指數':'sz','滬深300':'hs300',
'上證50':'sz50','中小板指':'zxb','創業板':'cyb'}
stock_index=pd.DataFrame()
for stock in stocks.values():
stock_index[stock]=ts.get_k_data(stock,ktype='D',
autype='qfq', start='2005-01-01')['close']
#stock_index.head()
#計算這些股票指數每日漲跌幅
tech_rets = stock_index.pct_change()[1:]
#tech_rets.head()
#收益率描述性統計
tech_rets.describe()
#結果不在此報告
#均值其實都大於0
tech_rets.mean()*100 #轉換為%
對上述股票指數之間的相關性進行可視化分析:
#jointplot這個函數可以畫出兩個指數的」相關性係數「,或者說皮爾森相關係數
sns.jointplot('sh','sz',data=tech_rets)
#成對的比較不同數據集之間的相關性,#而對角線則會顯示該數據集的直方圖
sns.pairplot(tech_rets.iloc[:,3:].dropna())returns_fig = sns.PairGrid(tech_rets.iloc[:,3:].dropna())
###右上角畫散點圖
returns_fig.map_upper(plt.scatter,color="purple")
###左下角畫核密度圖
returns_fig.map_lower(sns.kdeplot,cmap="cool_d")
###對角線的直方圖
returns_fig.map_diag(plt.hist,bins=30)
使用均值和標準分別刻畫股票(指數)的收益率和波動率,對比分析不同股票(指數)的收益-風險情況。
#構建一個計算股票收益率和標準差的函數
#默認起始時間為'2005-01-01'
def return_risk(stocks,startdate='2005-01-01'):
close=pd.DataFrame()
for stock in stocks.values():
close[stock]=ts.get_k_data(stock,ktype='D',
autype='qfq', start=startdate)['close']
tech_rets = close.pct_change()[1:]
rets = tech_rets.dropna()
ret_mean=rets.mean()*100
ret_std=rets.std()*100
return ret_mean,ret_std
#畫圖函數
def plot_return_risk():
ret,vol=return_risk(stocks)
color=np.array([ 0.18, 0.96, 0.75, 0.3, 0.9,0.5])
plt.scatter(ret, vol, marker = 'o',
c=color,s = 500,cmap=plt.get_cmap('Spectral'))
plt.xlabel("日收益率均值%")
plt.ylabel("標準差%")
for label,x,y in zip(stocks.keys(),ret,vol):
plt.annotate(label,xy = (x,y),xytext = (20,20),
textcoords = "offset points",
ha = "right",va = "bottom",
bbox = dict(boxstyle = 'round,pad=0.5',
fc = 'yellow', alpha = 0.5),
arrowprops = dict(arrowstyle = "->",
connectionstyle = "arc3,rad=0"))
stocks={'上證指數':'sh','深證指數':'sz','滬深300':'hs300',
'上證50':'sz50','中小板指數':'zxb','創業板指數':'cyb'}
plot_return_risk()
stocks={'中國平安':'601318','格力電器':'000651',
'招商銀行':'600036','恒生電子':'600570',
'中信證券':'600030','貴州茅臺':'600519'}
startdate='2018-01-01'
plot_return_risk()
df=ts.get_k_data('sh',ktype='D', autype='qfq',
start='2005-01-01')
df.index=pd.to_datetime(df.date)
tech_rets = df.close.pct_change()[1:]
rets = tech_rets.dropna()
#rets.head()
#下面的結果說明,我們95%的置信,一天我們不會損失超過0.0264...
rets.quantile(0.05)
-0.026496813699825043
構建蒙特卡洛模擬函數:
def monte_carlo(start_price,days,mu,sigma):
dt=1/days
price = np.zeros(days)
price[0] = start_price
shock = np.zeros(days)
drift = np.zeros(days)
for x in range(1,days):
shock[x] = np.random.normal(loc=mu * dt,
scale=sigma * np.sqrt(dt))
drift[x] = mu * dt
price[x] = price[x-1] + (price[x-1] *
(drift[x] + shock[x]))
return price
#模擬次數
runs = 10000
start_price = 2641.34 #今日收盤價
days = 252
mu=rets.mean()
sigma=rets.std()
simulations = np.zeros(runs)
for run in range(runs):
simulations[run] = monte_carlo(start_price,
days,mu,sigma)[days-1]
q = np.percentile(simulations,1)
plt.figure(figsize=(8,6))
plt.hist(simulations,bins=50,color='grey')
plt.figtext(0.6,0.8,s="初始價格: %.2f" % start_price)
plt.figtext(0.6,0.7,"預期價格均值: %.2f" %simulations.mean())
plt.figtext(0.15,0.6,"q(0.99: %.2f)" %q)
plt.axvline(x=q,linewidth=6,color="r")
plt.title("經過 %s 天后上證指數模擬價格分布圖" %days,weight="bold")
Text(0.5,1,'經過 252 天后上證指數模擬價格分布圖')
實際上蒙特卡洛模擬在期權定價裡面還是很有用的。我們借用期權定價裡對未來股票走勢的假定來進行蒙特卡洛模擬。
import numpy as np
from time import time
np.random.seed(2018)
t0=time()
S0=2641.34
T=1.0;
r=0.05;
sigma=rets.std()
M=50;
dt=T/M;
I=250000
S=np.zeros((M+1,I))
S[0]=S0
for t in range(1,M+1):
z=np.random.standard_normal(I)
S[t]=S[t-1]*np.exp((r-0.5*sigma**2)*dt+
sigma*np.sqrt(dt)*z)
s_m=np.sum(S[-1])/I
tnp1=time()-t0
print('經過250000次模擬,得出1年以後上證指數的
預期平均收盤價為:%.2f'%s_m)
經過250000次模擬,得出1年以後上證指數的預期平均收盤價為:2776.85
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.plot(S[:,:10])
plt.grid(True)
plt.title('上證指數蒙特卡洛模擬其中10條模擬路徑圖')
plt.xlabel('時間')
plt.ylabel('指數')
plt.show()
plt.figure(figsize=(10,6))
plt.hist(S[-1], bins=120)
plt.grid(True)
plt.xlabel('指數水平')
plt.ylabel('頻率')
plt.title('上證指數蒙特卡洛模擬')
Text(0.5,1,'上證指數蒙特卡洛模擬')
本文主要介紹了如何使用Python獲取股票數據,並進行簡單的統計分析和可視化,綜合運用了Python金融量化分析的Pandas、NumPy和Matplotlib等包。目前,A股處於至暗時刻,或許是學習和歷練的最好時機,涅槃重生的過程總是艱難的,但振翅飛翔的一刻值得你等待。
數據君開通了粉絲交流微信,歡迎添加交流