用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,一定非常高效。

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

     文本相關鏈接:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章