用Python爬取股票數據,繪製K線和均線並用機器學習預測股價(來自我出的書)
最近我出了一本書,《基於股票大數據分析的Python入門實戰 影片教學版》,京東鏈接://item.jd.com/69241653952.html,在其中用股票範例講述Python爬蟲、數據分析和機器學習的技術,大家看了我的書,不僅能很快用比較熱門的案例學好Python,更能了解些股票知識,不至於一入市就拍腦袋買賣。
在本文里,將給出若干精彩範例,包括用爬蟲獲取股市數據,用matplotlib可視化控制項繪製K線和均線,以及用sklean庫里的方法,通過機器學習預測股價的走勢。
1 通過pandas_datareader庫的方法爬取股市數據
pandas_datareader是一個能讀取各種金融數據的庫,在下面的getDataByPandasDatareader.py范常式序中演示了通過這個庫獲取股市數據的常規方法。
1 # coding=utf-8 2 from pandas_datareader import data as pdr 3 import yfinance as yf 4 yf.pdr_override() 5 code='600895.ss' 6 stock = pdr.get_data_yahoo(code,'2019-01-02','2019-02-01') 7 print(stock) # 輸出內容 8 # 保存為excel和csv文件 9 stock.to_excel('D:\\stockData\\ch5\\'+code+'.xlsx') 10 stock.to_csv('D:\\stockData\ch5\\'+code+'.csv')
從這個范常式序的程式碼上來看,不算複雜,從中沒有見到爬取網站之類的程式碼。關鍵的是第6行,通過調用pdr.get_data_yahoo方法從雅虎網站獲取數據,這個方法的參數分別是股票程式碼,開始日期和結束日期。第4行使用yf.pdr_override方法是為了防止雅虎網站修改獲取歷史數據的API介面而導致get_data_yahoo方法不可用。
在這個范常式序中獲取了600895(張江高科)2019-01-02到2019-01-31的數據,可以看出,獲取的數據並不包括結束日期參數當天的數據。
在第7行和第8行分別調用了to_excel和to_csv方法,把結果存入了指定目錄下的文件中。這個范常式序運行後,我們首先能在控制台中看到輸出,其次會在D:\stockData\ch5\目錄中,看到600895.ss.xlsx和600895.ss.csv這兩個保存股票數據的文件。打開600895.ss.xlsx文件,能看到如圖5-4所示的數據內容,其實在控制台中和另一個csv文件中,可以看到一樣的數據。
在上述范常式序中,在調用get_data_yahoo方法時,傳入的股票程式碼帶有.ss的後綴,這表示該程式碼是滬股的。此外,還能通過.sz的後綴來表示深股,通過.hk的後綴表示港股。如果要獲取美股的數據,則直接用美股的股票程式碼即可。在下面的printDataByPandasDatareader.py范常式序中演示了獲取美股,港股和深股相關數據的方式。
1 # coding=utf-8 2 from pandas_datareader import data as pdr 3 import yfinance as yf 4 yf.pdr_override() 5 stockCodeList = [] 6 stockCodeList.append('600007.ss') # 滬股「中國國貿」 7 stockCodeList.append('000001.sz') # 深股「平安銀行」 8 stockCodeList.append('2318.hk') # 港股「中國平安」 9 stockCodeList.append('IBM') # 美股,IBM,直接輸入股票程式碼不帶後綴 10 for code in stockCodeList: 11 # 為了演示,只取一天(2019-01-02)的交易數據 12 stock = pandas_datareader.get_data_yahoo(code,'2019-01-02','2019-01-03') 13 print(stock)
這個范常式序運行後,就能從控制台中看到輸出的4個股票在指定日期內的交易情況,由於數據量比較多,本書就不羅列具體的數據了。
2 用matplotlib繪製k線和均線
K線是由開盤價、收盤價、最高價和最低價這四個要素構成。在得到上述四個值之後,首先用開盤價和收盤價繪製成一個長方形實體。隨後根據最高價和最低價,把它們垂直地同長方形實體連成一條直線,這條直線就叫影線。如果再細分一下,長方形實體上方的就叫上影線,下方的就叫下影線。通過K線可以形象地記錄價格變動的情況,常用的有日K線,周K線和月K線。
均線也叫移動平均線(Moving Average,簡稱MA),是指某段時間內的平均股價(或指數)連成的曲線,均線一般分為三類:短期、中期和長期。通常把5日和10日移動平均線稱為短期均線,一般把20日、30日和60日移動平均線作為中期均線,一般120日和250日(甚至更長)移動平均線稱為長期均線。
在如下的drawKAndMAMore.py范常式序中,將用到上文提到的爬取股票數據的程式碼,從網路介面里獲取股票數據,並繪製k線和均線,請大家不僅注意k線和均線的含義,還要重視matplotlib庫里繪製圖形、圖例和坐標軸的做法,在這本書里,對應的知識點都有詳細的說明。
1 # !/usr/bin/env python 2 # coding=utf-8 3 from pandas_datareader import data as pdr 4 import pandas as pd 5 import matplotlib.pyplot as plt 6 from mpl_finance import candlestick2_ochl 7 from matplotlib.ticker import MultipleLocator 8 import yfinance as yf 9 yf.pdr_override() 10 # 根據指定程式碼和時間範圍獲取股票數據 11 code='600895.ss' 12 stock.drop(stock.index[len(stock)-1],inplace=True) 13 # 保存在本地 14 stock.to_csv('D:\\stockData\ch7\\600895.csv') 15 df = pd.read_csv('D:/stockData/ch7/600895.csv',encoding='gbk',index_col=0) 16 # 設置窗口大小 17 fig, ax = plt.subplots(figsize=(10, 8)) 18 xmajorLocator = MultipleLocator(5) # 將x軸主刻度設置為5的倍數 19 ax.xaxis.set_major_locator(xmajorLocator) 20 # 調用方法繪製K線圖 21 candlestick2_ochl(ax = ax, opens=df["Open"].values,closes=df["Close"].values, highs=df["High"].values, lows=df["Low"].values,width=0.75, colorup='red', colordown='green') 22 # 如下是繪製3種均線 23 df['Close'].rolling(window=3).mean().plot(color="red",label='3日均線') 24 df['Close'].rolling(window=5).mean().plot(color="blue",label='5日均線') 25 df['Close'].rolling(window=10).mean().plot(color="green",label='10日均線') 26 plt.legend(loc='best') # 繪製圖例 27 ax.grid(True) # 帶網格線 28 plt.title("600895張江高科的K線圖") 29 plt.rcParams['font.sans-serif']=['SimHei'] 30 plt.setp(plt.gca().get_xticklabels(), rotation=30) 31 plt.show()
第一,從第9行到第15行通過調用之前介紹過的get_data_yahoo方法,傳入股票程式碼、開始時間和結束時間這三個參數,從雅虎網站中獲得股票交易的數據。
第二,在第17行中調用figsize方法設置了窗口的大小。
第三,第18行和第19行的程式程式碼設置了主刻度是5的倍數。之所以設置成5的倍數,是因為一般一周的交易日是5天。但這裡不能簡單地把主刻度設置成每周一,因為某些周一有可能是股市休市的法定假日。
第四,由於無需在x軸上設置每天的日期,因此這裡無需再調用plt.xticks方法,但是要調用如第30行所示的程式碼,設置x軸刻度的旋轉角度,否則x軸顯示的時間依然有可能會相互重疊。
至於繪製K線的candlestick2_ochl方法和繪製均線的rolling方法與之前drawKAndMA.py范常式序中的程式碼是完全一致的。
這個范常式序的運行結果如圖7-5所示,從中可以看到改進後的效果。由於本次顯示的股票時間段變長了(是3個月),因此與drawKAndMA.py范常式序相比,這個范常式序均線的效果更為明顯,尤其是3日均線,幾乎貫穿於整個時間段的各個交易日。
另外,由於在第26行通過調用plt.legend(loc=’best’)方法指定了圖例將「顯示在合適的位置」,因此這裡的圖例顯示在效果更加合適的左上方,而不是drawKAndMA.py范常式序中的右上方。
3 用sklearn庫的機器學習方法預測股票後市價格
在下面的predictStockByLR.py范常式序中,根據股票歷史的開盤價、收盤價和成交量等特徵值,從數學角度來預測股票未來的收盤價。
1 # !/usr/bin/env python 2 # coding=utf-8 3 import pandas as pd 4 import numpy as np 5 import math 6 import matplotlib.pyplot as plt 7 from sklearn.linear_model import LinearRegression 8 from sklearn.model_selection import train_test_split 9 # 從文件中獲取數據 10 origDf = pd.read_csv('D:/stockData/ch13/6035052018-09-012019-06-01.csv',encoding='gbk') 11 df = origDf[['Close', 'High', 'Low','Open' ,'Volume']] 12 featureData = df[['Open', 'High', 'Volume','Low']] 13 # 劃分特徵值和目標值 14 feature = featureData.values 15 target = np.array(df['Close'])
第10行的程式語句從包含股票資訊的csv文件中讀取數據,在第14行設置了特徵值是開盤價、最高價、最低價和成交量,同時在第15行設置了要預測的目標列是收盤價。在後續的程式碼中,需要將計算出開盤價、最高價、最低價和成交量這四個特徵值和收盤價的線性關係,並在此基礎上預測收盤價。
16 # 劃分訓練集,測試集 17 feature_train, feature_test, target_train ,target_test = train_test_split(feature,target,test_size=0.05) 18 pridectedDays = int(math.ceil(0.05 * len(origDf))) # 預測天數 19 lrTool = LinearRegression() 20 lrTool.fit(feature_train,target_train) # 訓練 21 # 用測試集預測結果 22 predictByTest = lrTool.predict(feature_test)
第17行的程式語句通過調用train_test_split方法把包含在csv文件中的股票數據分成訓練集和測試集,這個方法前兩個參數分別是特徵列和目標列,而第三個參數0.05則表示測試集的大小是總量的0.05。該方法返回的四個參數分別是特徵值的訓練集、特徵值的測試集、要預測目標列的訓練集和目標列的測試集。
第18行的程式語句計算了要預測的交易日數,在第19行中構建了一個線性回歸預測的對象,在第20行是調用fit方法訓練特徵值和目標值的線性關係,請注意這裡的訓練是針對訓練集的,在第22行中,則是用特徵值的測試集來預測目標值(即收盤價)。也就是說,是用多個交易日的股價來訓練lrTool對象,並在此基礎上預測後續交易日的收盤價。至此,上面的程式程式碼完成了相關的計算工作。
23 # 組裝數據 24 index=0 25 # 在前95%的交易日中,設置預測結果和收盤價一致 26 while index < len(origDf) - pridectedDays: 27 df.ix[index,'predictedVal']=origDf.ix[index,'Close'] 28 df.ix[index,'Date']=origDf.ix[index,'Date'] 29 index = index+1 30 predictedCnt=0 31 # 在後5%的交易日中,用測試集推算預測股價 32 while predictedCnt<pridectedDays: 33 df.ix[index,'predictedVal']=predictByTest[predictedCnt] 34 df.ix[index,'Date']=origDf.ix[index,'Date'] 35 predictedCnt=predictedCnt+1 36 index=index+1
在第26行到第29行的while循環中,在第27行把訓練集部分的預測股價設置成收盤價,並在第28行設置了訓練集部分的日期。
在第32行到第36行的while循環中,遍歷了測試集,在第33行的程式語句把df中表示測試結果的predictedVal列設置成相應的預測結果,同時也在第34行的程式語句逐行設置了每條記錄中的日期。
37 plt.figure() 38 df['predictedVal'].plot(color="red",label='predicted Data') 39 df['Close'].plot(color="blue",label='Real Data') 40 plt.legend(loc='best') # 繪製圖例 41 # 設置x坐標的標籤 42 major_index=df.index[df.index%10==0] 43 major_xtics=df['Date'][df.index%10==0] 44 plt.xticks(major_index,major_xtics) 45 plt.setp(plt.gca().get_xticklabels(), rotation=30) 46 # 帶網格線,且設置了網格樣式 47 plt.grid(linestyle='-.') 48 plt.show()
在完成數據計算和數據組裝的工作後,從第37行到第48行程式程式碼的最後,實現了可視化。
第38行和第39行的程式程式碼分別繪製了預測股價和真實收盤價,在繪製的時候設置了不同的顏色,也設置了不同的label標籤值,在第40行通過調用legend方法,根據收盤價和預測股價的標籤值,繪製了相應的圖例。
從第42行到第45行設置了x軸顯示的標籤文字是日期,為了不讓標籤文字顯示過密,設置了「每10個日期里只顯示1個」的顯示方式,並且在第47行設置了網格線的效果,最後在第48行通過調用show方法繪製出整個圖形。運行本范常式序,即可看到如圖13-7所示的結果。
可以看出,藍線表示真實的收盤價(圖中完整的線),紅線表示預測股價(圖中靠右邊的線。因為本書黑白印刷的原因,在書中讀者看不到藍色和紅色,請讀者在自己的電腦上運行這個范常式序即可看到紅藍兩色的線)。雖然預測股價和真實價之間有差距,但漲跌的趨勢大致相同。而且在預測時沒有考慮到漲跌停的因素,所以預測結果的漲跌幅度比真實數據要大。
股票價格不僅由技術面決定,還受政策面、資金量以及消息面等諸多因素的影響,這也能解釋預測結果和真實結果間有差異的原因。
4 對書的介紹和版權說明
本文給出的範例,僅是《基於股票大數據分析的Python入門實戰 影片教學版》一書里的部分案例,該書京東鏈接://item.jd.com/69241653952.html。
這本書包括如下的內容,是本入門python的工具書。
1 Python基本語法,集合,面向對象語法,異常處理,讀寫文件技能。
2 Python操作資料庫的技能。
3 通過爬蟲從網路介面爬取股票數據的技能。
4 基於Numpy+Pandas+Matplotlib進行數據分析的技能
5 基於TKinter的GUI編程技能+ 發送郵件的技能
6 Django框架的用法
7 線性回歸+SVM的機器學習技能
這本書里,像本文那樣花花綠綠能吸引人的圖真不少,而且還是通過python繪製出來的,用這類比較能吸引人的案例來入門python,一定非常高效。
本文可以轉載,轉載時請全文轉載,別有刪節,並用鏈接的形式給出原文鏈接。否則的話,可能會遇到出版社的維權。