在用python的matplotlib和numpy庫繪製股票K線均線的整合效果(含從網絡接口爬取數據和驗證交易策略代碼)一文裏,我講述了經過爬蟲接口獲得股票數據並繪製出K線均線圖形的方式,在本文裏,將在此基礎上再引入成交量效果圖,並結合量價理論,給出並驗證一些交易策略。html
美國的股市分析家葛蘭碧(Joe Granville)在他所著的《股票市場指標》一書裏提出著名的「量價理論」。「量價理論」的核心思想是,任何對股價的分析,若是離開了對成交量的分析,都將是無本之木,無水之源,由於成交量的增長或萎縮都表現出必定的股價趨勢。python
成交量是指時間單位內已經成交的股數或總手數。成交量能反應出股市交易中的供求關係,其中道理是比較淺顯易懂的,當股票供不該求時,你們爭相購買,成交量就很大了,反之當供過於求時,則說明市場交易冷淡,成交量必然萎縮。網絡
廣義的成交量包括成交股數(Volumn或Vol)、成交金額(AMOUNT,時間單位內已經成交的總金額數)和換手率(TUN,股票天天成交量除以股票的流通總股本所得的比率),而狹義則是指成交股數。咱們用yahoo接口獲得的數據裏,有表示成交股數的Volumn列,其中的單位是「手」,一手爲100股,在本部分裏,咱們是經過Volumn列數據繪製股票的成交量信息。less
在K線和均線整合成交量的效果圖裏,出於美觀的考慮,咱們對整合的效果提出了以下三點要求。函數
第一,繪製上下兩個子圖,上圖放K線和均線,下圖放成交量效果。post
第二,上下兩個子圖共享x軸,也就是說,二者x軸的刻度標籤和間隔應該是同樣的。url
第三,經過柱狀圖來繪製成交量圖,若是當天股票上漲,成交量圖是紅色,下跌則是綠色。 spa
在以下的drawKMAAndVol.py案例,咱們將實現增長成交量圖的效果。code
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas as pd 4 import matplotlib.pyplot as plt 5 from mpl import candlestick_ochl 6 from matplotlib import MultipleLocator 7 #根據指定代碼和時間範圍,獲取股票數據 8 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk') 9 #設置大小,共享x座標軸 10 figure,(axPrice, axVol) = plt.subplots(2, sharex=True, figsize=(15,8)) 11 #調用方法,繪製K線圖 12 candlestick_ochl(ax = axPrice, opens=df["Open"].values, closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values, 13 width=0.75, colorup='red', colordown='green') 14 axPrice.set_title("600895張江高科K線圖和均線圖")#設置子圖標題 15 df['Close'].rolling(window=3).plot(ax=axPrice,color="red",label='3天均線') 16 df['Close'].rolling(window=5).plot(ax=axPrice,color="blue",label='5天均線') 17 df['Close'].rolling(window=10).plot(ax=axPrice,color="green",label='10天均線') 18 axPrice.legend(loc='best') #繪製圖例 19 axPrice.set_ylabel("價格(單位:元)") 20 axPrice.grid(True) #帶網格線 21 #以下繪製成交量子圖 22 #直方圖表示成交量,用for循環處理不一樣的顏色 23 for index, row in df.iterrows(): 24 if(row['Close'] >= row['Open']): 25 axVol.bar(row['Date'],row['Volume']/1000000,width = 0.5,color='red') 26 else: 27 axVol.bar(row['Date'],row['Volume']/1000000,width = 0.5,color='green') 28 axVol.set_ylabel("成交量(單位:億手)")#設置y軸標題 29 axVol.set_title("600895張江高科成交量")#設置子圖的標題 30 axVol.set_ylim(0,df['Volume'].max()/100000000*1.2)#設置y軸範圍 31 xmajorLocator = MultipleLocator(5) #將x軸主刻度設置爲5的倍數 32 axVol.xaxis.set_major_locator(xmajorLocator) 33 axVol.grid(True) #帶網格線 34 #旋轉x軸的展現文字角度 35 for xtick in axVol.get_xticklabels(): 36 xtick.set_rotation(15) 37 plt.rcParams['font.sans-serif']=['SimHei'] 38 plt.show()
從第8行到第20行,咱們一方面是從csv文件裏讀取數據,另外一方面在第一個子圖裏繪製了K線和均線圖。這部分的代碼和以前很類似,不過請你們注意兩個點。htm
第一,在第10行裏,不只設置了繪圖區域的大小,更經過sharex=True語句,設置了axPrice和axVol這兩個子圖共享x軸。
第二,第二,在第1四、1八、19和第20行,因爲是在K線圖和均線圖的axPrice子圖裏操做,因此若干方法的調用主體是axPrice對象,而不是以前的pyplot.plt對象。
從第23行到第36行裏,咱們在axVol子圖裏繪製了成交量圖的效果。請你們注意第23行到第27行的for循環,在其中,咱們經過第24行的if語句,比較收盤價和開盤價,以判斷當天股票是漲是跌,在此基礎上,經過第25行或第27行的bar方法,設置當日成交量圖的填充顏色。從上述代碼能看出,成交量是在自於csv文件裏的Volume列。
在繪製成交量圖的時候有兩個細節請你們注意一下。
第一,在第25行、第27行和第30行裏,當咱們設置y軸的刻度值和範圍時,咱們除以了一個相同的數,這是由於在第28行咱們設置y軸文字時,指定了y軸成交量的單位是「億手「。
第二, 本次是經過第35行和第36行的for循環,設置了「x軸文字旋轉」的效果,從代碼裏咱們能看到,本案例中的旋轉角度是15度。
上述代碼的運行效果以下圖所示,從中你們能看兩個x軸刻度一致的子圖,且在成交量子圖裏,上漲日和下跌日的成交量填充色分別是紅色和綠色。
成交量和股價間也存在着八大規律,經過下圖,咱們能感覺到這些規律,其中縱座標表示價(即股價),橫座標表示量(即成交量)。
咱們能看出量價之間的八種關係,即量增價平、量增價升、量平價升、量縮價升、量減價平、量縮價跌、量平價跌、量跌價升,隨着上述週期過程,股價也完成了一個從漲到跌的完整循環,下面咱們來具體解釋一下。
1.量增價平:股價通過持續下跌進入到低位狀態,出現了成交量增長但股價平穩的現象,此時不一樣天的成交量高度落差可能比較明顯,這說明該股在底部積聚上漲動力。
2.量增價升:成交量在低價位區持續上升,同時伴隨着股價上漲趨勢,這說明股價上升獲得了成交量的支撐,後市將繼續看好,這是中短線的買入信號。
3.量平價升:在股價持續上漲的過程當中,若是多日的成交量保持等量水平,建議在這一階段中能夠適當增長倉位。
4.量縮價升:成交量開始減小,但股價依然在上升,此時應該視狀況繼續持股。但若是尚未買入的投資者就不宜再重倉介入,由於股價已經有了必定的漲幅,價位開始接近上限。
5.量減價平:股價經長期大幅度上漲後,成交量顯著減小,股價也開始橫向調整再也不上升,這是高位預警的信號。這個階段裏一旦有風吹草動,好比忽然拉出大陽線和大陰線,建議應出貨離場,作到落袋爲安。
6.量縮價跌:成交量在高位繼續減小,股價也開始進入降低通道,這是明確的賣出信號。若是還出現縮量陰跌,這說明股價底部尚遠,不會輕易止跌。
7.量平價跌:成交量中止減小,但股價卻出現急速下滑現象,這說明市場並無造成一致看空的共識。股諺有「多頭不死,跌勢不止「的說法,出現「量平價跌」的狀況,說明主力開始逐漸退出市場,這個階段裏,應繼續觀望或者出貨,別輕易去買入以所謂的「搶反彈」。
8. 量增價跌:股價經長期大幅下跌以後,有可能出現成交量增長的狀況,此時的操做原則是建議賣出,或者空倉觀望。若是低價區成交量有增長,則說明有資金在此價位區間接盤,預示後期有望造成底部並出現反彈。但若是出現量增價跌,則建議應清倉出局。
在下文裏,咱們將經過Python語言驗證量價理論中的兩個規則。
在以下的calBuyPointByVol.py案例中,咱們將驗證「量增價平「的買點。在這段代碼裏咱們作了三件事,第一是經過yahoo接口獲得了指定股票指定範圍內的交易數據,第二經過pandas接口保存獲得的數據,以便往後驗證,第三經過遍歷dataframe對象,計算量和價的關係,從而得到買點日期。
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas_datareader 4 import pandas as pd 5 import numpy as np 6 #漲幅是否大於指定比率 7 def isMoreThanPer(lessVal,highVal,per): 8 if np.abs(highVal-lessVal)/lessVal>per/100: 9 return True 10 else: 11 return False 12 #漲幅是否小於指定比率 13 def isLessThanPer(lessVal,highVal,per): 14 if np.abs(highVal-lessVal)/lessVal<per/100: 15 return True 16 else: 17 return False 18 code='600895.ss' 19 stock = pandas_datareader.get_data_yahoo(code,'2018-09-01','2018-12-31') 20 #刪除最後一行,由於get_data_yahoo會多取一天數據 21 stock.drop(stock.index[len(stock)-1],inplace=True) 22 #保存在本地 23 stock.to_csv('D:\\stockData\ch7\\60089520181231.csv') 24 #從文件裏獲得數據 25 df = pd.read_csv('D:/stockData/ch7/60089520181231.csv',encoding='gbk') 26 cnt=0 27 while cnt<=len(df)-1: 28 try: 29 #規則1,連續三天收盤價變更不超過3% 30 if isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+1]['Close'],3) and isLessThanPer(df.iloc[cnt]['close'],df.iloc[cnt+2]['Close'],3) : 31 #規則2,連續三天成交量漲幅超過75% 32 if isMoreThanPer(df.iloc[cnt]['Volume'],df.iloc[cnt+1]['volume'],75) and isMoreThanPer(df.iloc[cnt]['Volume'],df.iloc[cnt+2]['Volume'],75) : 33 print("Buy Point on:" + df.iloc[cnt]['Date']) 34 except: 35 pass 36 cnt=cnt+1
在第7行定義的isMoreThanPer方法裏,咱們比較了高價和低價,以判斷是否超過由參數per指定的漲幅。在第13行的isLessThanPer方法裏,咱們判斷了跌幅是否超過per指定的範圍。因爲這兩個功能常常會用到,因此咱們把它們封裝成函數。
從第18行到第25行,咱們完成了獲取並保存數據的動做,並用df對象保存了待遍歷的股票數據(即張江高科2018-09-01到2018-12-31的數據)。
在第27行到第36行按日期遍歷股票數據時,咱們制定了以下規則,連續三天股票的收盤價變更範圍不超過5%(即價平)且3天成交量的漲幅過75%(即量增),把知足條件的日期打印出來。運行後,咱們能看到11月2日這個買點。
在以前代碼基礎上改寫下,把時間範圍改爲2018-09-01到2018-12-31,再運行下,能看到以下圖所示的效果。
從中咱們能看到驗證後的結果:在11月2日以後,股票的漲幅比較明顯,確實是個合適的買點,從中咱們能看出 「量增價平」的指導意義。
在以下calSellPointByVol.py案例中,咱們一樣是分析張江高科2018-09-01到2018-12-31的交易數據,本次咱們制定的策略是,第一,仍是連續三天股票的收盤價變更範圍不超過5%(即價平),第二,較第一日相比,第二日和第三日的成交量降低幅度超過75%(即量減)。
1 #!/usr/bin/env python 2 #coding=utf-8 3 import pandas_datareader 4 import pandas as pd 5 import numpy as np 6 #漲幅是否大於指定比率 7 def isMoreThanPer(lessVal,highVal,per): 8 if np.abs(highVal-lessVal)/lessVal>per/100: 9 return True 10 else: 11 return False 12 #漲幅是否小於指定比率 13 def isLessThanPer(lessVal,highVal,per): 14 if np.abs(highVal-lessVal)/lessVal<per/100: 15 return True 16 else: 17 return False 18 #本次直接從文件裏獲得數據 19 df = pd.read_csv('D:/stockData/ch7/60089520181231.csv',encoding='gbk') 20 cnt=0 21 while cnt<=len(df)-1: 22 try: 23 #規則1,連續三天收盤價變更不超過3% 24 if isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+1]['Close'],3) and isLessThanPer(df.iloc[cnt]['Close'],df.iloc[cnt+2]['close'],3) : 25 #規則2,連續三天成交量跌幅超過75% 26 if isMoreThanPer(df.iloc[cnt+1]['Volume'],df.iloc[cnt]['Volume'],75) and isMoreThanPer(df.iloc[cnt+2]['Volume'],df.loc[cnt]['Volume'],75) : 27 print("Sell Point on:" + df.iloc[cnt]['Date']) 28 except: 29 pass 30 cnt=cnt+1
上述代碼和以前calBuyPointByVol.py案例很類似,只不過咱們適當變動了第26行判斷「成交量」的if條件。上述代碼運行後,咱們能獲得的賣點是2018-12-05,從上圖裏咱們能看出,在這段時間以後的若干交易日裏,張江高科的股價確實有下跌現象。
在本系列的後面文章中,將陸續經過python繪製成交量、KDJ、MACD、RSI,BIAS和OBV等指標,並且還會用Python編寫針對這些指標的交易策略,敬請關注。
本文用了我將近2個小時,若是你們感受好,請幫忙推薦下。
關於轉載有以下的說明。
1 本文文字和代碼均屬原創,可轉載,但謝絕用於商業用戶。
2 轉載時請用連接的方式,給出原文出處,同時寫明原做者是hsm_computer。
3 在轉載時,請原文轉載 ,如要在轉載修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。