1. 程式人生 > >用Python爬取股票資料,繪製K線和均線並用機器學習預測股價(來自我出的書)

用Python爬取股票資料,繪製K線和均線並用機器學習預測股價(來自我出的書)

    最近我出了一本書,《基於股票大資料分析的Python入門實戰 視訊教學版》,京東連結:https://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入門實戰 視訊教學版》一書裡的部分案例,該書京東連結:https://item.jd.com/69241653952.html。

    這本書包括如下的內容,是本入門python的工具書。

    1 Python基本語法,集合,面向物件語法,異常處理,讀寫檔案技能。

    2 Python操作資料庫的技能。

    3 通過爬蟲從網路介面爬取股票資料的技能。

    4 基於Numpy+Pandas+Matplotlib進行資料分析的技能

    5 基於TKinter的GUI程式設計技能+ 傳送郵件的技能

    6 Django框架的用法

    7 線性迴歸+SVM的機器學習技能

    這本書裡,像本文那樣花花綠綠能吸引人的圖真不少,而且還是通過python繪製出來的,用這類比較能吸引人的案例來入門python,一定非常高效。

    本文可以轉載,轉載時請全文轉載,別有刪節,並用連結的形式給出原文連結。否則的話,可能會遇到出版社的維權。

     文字相關連結:

用Python語言繪製股市OBV指標效果 
  程式設計師如何高效學Python,如何高效用Python掙錢 
  用matplotlib和pandas繪製股票MACD指標圖,並驗證化交易策略   向大家介紹我的新書:《基於股票大資料分析的Python入門實戰》 
  通過機器學習的線性迴歸演算法預測股票走勢(用Python實現)    在我的新書裡,嘗試著用股票案例講述Python爬蟲大資料視覺化等知識 
  以股票RSI指標為例,學習Python傳送郵件功能(含RSI指標確定賣點策略)    以預測股票漲跌案例入門基於SVM的機器學習   用python的matplotlib和numpy庫繪製股票K線均線和成交量的整合效果(含量化驗證交易策略程式碼) 
  用python的matplotlib和numpy庫繪製股票K線均線的整合效果(含從網路介面爬取資料和驗證交易策略程式碼)