使用Python的pandas-datareader包下載雅虎財經股價數據


0 准備工作

首先,使用pip方法安裝pandas和pandas-datareader兩個功能包. 安裝的方法十分簡單,以管理員身份運行cmd. 輸入以下命令。

$ pip install pandas
$ pip install pandas-datareader

需要注意的是,安裝pandas時將自動安裝numpy等功能包,因此可以使用pandas即代表安裝了numpy功能包。今后,在安裝所有Python所需功能包時,皆可使用以上方法。

在Yahoo Finance對API進行升級后,你可能需要安裝最新開發版本(latest development version)的pandas-datareader(目前是0.5.0版本),才能對雅虎財經的部分數據進行訪問,安裝方法可以參考原git

pandas-datareader包中的pandas_datareader.data.DataReader函數可以根據輸入的證券Ticker,起始日期和終止日期來返回包含所有歷史日價格的數據,其數據類型是DataFrame,這是pandas包引入的一個數據類型。在這里假設需要蘋果公司(Ticker: AAPL)從2016年初到今天(2017年4月6日)的歷史日價格。

到這里,打開你的Python代碼編輯器,你便完成了所有的准備工作。

1 獲取股價數據

此處需使用的包是datetime,pandas,和pandas-datareader. 導入datetime的原因是,我們要使用datetime包中的datetime.datetime.today()函數來調用今天的日期。

import datetime import pandas as pd import pandas_datareader.data as web ## !!! here it is 'pandas_datareader' rather than 'pandas-datareader' 

在以上代碼中,import A as B 的作用是導入A,並給A起一個別名叫做B. 此例中,pandas_datareader.data這個名稱顯然過長,因此給它起一個別名叫做web,這樣在后文中使用pandas_datareader.data.DataReader函數時,直接使用web.DataReader即可。一定要注意的是,這里的pandas_datareader中使用的是下划線'_',而非在pip安裝時使用的連接符‘-’.

接下來,設置起始日期和終止日期。使用datetime.datetime函數指向給定日期,使用datetime.date.today函數指向今天的日期。運行DataReader函數並將其保存到一個名為prices的變量中。

start = datetime.datetime(2016, 1, 1) # or start = '1/1/2016' end = datetime.date.today() prices = web.DataReader('AAPL', 'yahoo', start, end) print prices.head() # print first rows of the prices data 

注意DataReader函數中第二個參數代表數據來源,DataReader支持包括雅虎、谷歌在內的十數種數據來源,本篇筆記只關注來源為雅虎財經的數據。

觀察一下獲得的prices數據的前六行(含列名),

                  Open High Low Close Volume \ Date 2016-01-04 102.610001 105.370003 102.000000 105.349998 67649400 2016-01-05 105.750000 105.849998 102.410004 102.709999 55791000 2016-01-06 100.559998 102.370003 99.870003 100.699997 68457400 2016-01-07 98.680000 100.129997 96.430000 96.449997 81094400 2016-01-08 98.550003 99.110001 96.760002 96.959999 70798000 Adj Close Date 2016-01-04 102.612183 2016-01-05 100.040792 2016-01-06 98.083025 2016-01-07 93.943473 2016-01-08 94.440222 

這個DataFrame的index是日期,總共有六列數據,通常情況下我們只關注最后一列Adjusted Closing Price 並使用它計算收益率。Adj Close的好處是已將所有的權重、分割和股利分發等因素考慮在了價格中進行調整。

2 獲取股利數據

pandas-datareader包也可以用來獲取股利或股票分割等數據,只要將DataReader函數中的數據源參數修改為'yahoo-actions'即可。

actions = web.DataReader('AAPL', 'yahoo-actions', start, end) print actions.head() 

這樣返回的actions仍是一個DataFrame類型的變量,其index為日期。觀察前六行的數據。

              action value 2017-02-09 DIVIDEND 0.57 2016-11-03 DIVIDEND 0.57 2016-08-04 DIVIDEND 0.57 2016-05-05 DIVIDEND 0.57 2016-02-04 DIVIDEND 0.52 

此處的action表示證券所進行的操作,如派發股利,或股票分割等等,而value則表示操作值。我們可以看到,蘋果公司最近一筆股利發放是在2017年2月9日,每股發放了0.57美元的股利。

值得一提的是,如果在給定日期內,該證券並沒有操作活動,DataReader函數將返回一個空的DataFrame,既沒有index,也沒有列名。

print web.DataReader('AAPL', 'yahoo-actions', datetime.datetime(2017, 4, 1), datetime.date.today()) 

輸出結果為,

Empty DataFrame Columns: [] Index: [] 

3 合並股利和股價數據

因為actions的index是prices的index的一個子集,所以我們可以直接將actions的各列添加到prices后面。下面介紹兩種合並股利和股價的方法。

第一種方法思路比較簡單,直接將actions的每一列提取出來,添加到prices后面。

一個DataFrame變量的某一列單獨提取出來,是一個Series變量,這也是pandas包中獨有的一個數據類型。通常,在列名不含空格和連接符的情況下,可以直接將列名作為DataFrame變量的Attribute進行調用。如actions.action即為actions中action這一列,它的類型是Series. 而在prices變量中,‘Adj Close’列,因為列名中含有空格,只能使用prices['Adj Close']來調用。

Attribute可以理解為一個對象(如prices,actions,甚至start,end等等)所包含的一系列屬性、方法、函數等等,如在之前使用的prices.head()即是在調用prices的head這一Attribute.

將actions的列調用出來后,即可對prices的新列進行賦值。

prices['action'], prices['value'] = actions.action, actions.value print prices 

觀察合並后的數據中間的某幾行。

                  Open High Low Close Volume \ Date ... 2016-02-01 96.470001 96.709999 95.400002 96.430000 40943500 2016-02-02 95.419998 96.040001 94.279999 94.480003 37357200 2016-02-03 95.000000 96.839996 94.080002 96.349998 45964300 2016-02-04 95.860001 97.330002 95.190002 96.599998 46471700 2016-02-05 96.519997 96.919998 93.690002 94.019997 46418100 2016-02-08 93.129997 95.699997 93.040001 95.010002 54021400 ... Adj Close action value Date ... 2016-02-01 93.923996 NaN NaN 2016-02-02 92.024676 NaN NaN 2016-02-03 93.846074 NaN NaN 2016-02-04 94.600127 DIVIDEND 0.52 2016-02-05 92.073538 NaN NaN 2016-02-08 93.043048 NaN NaN ... 

可以發現,所有沒有action和value的日期,該處數值將為NaN(Not a Number),而有效的股利數據被加入了相應行中。

第二種方法是使用pandas包中的merge函數,它可以根據一定規則將兩個DataFrame變量合並。

prices = pd.merge(prices, actions, how='outer', left_index=True, right_index=True) print prices 

以上代碼,可以得到與第一種方法同樣的結果。其中how='outer'是說最后合並結果的長度將是prices和actions中較長的長度,因此才會有NaN的出現。left_index和right_index都設為True,即當左右DataFrame的index相符時才合並。

4 輸出為CSV文件

DataFrame類型有一個Attribute可以直接將數據導出為CSV文件。如將合並好的股價和股利數據保存到根目錄out文件夾中,並起名為AAPL.csv.

prices.to_csv('.\\out\\AAPL.csv) 

其中.to_csv()方法需要一個字符型參數,即所需保存路徑。在該字符串中,'.'表示working directory,使用PyCharm等編譯器的話,一般都是代碼文件所在的目錄。而兩個反斜杠表示文件夾的層級關系,之所以用兩個,是因為''在字符串中有轉義作用。

需要注意的一點是,此例中,'.\out'文件夾應事先建好。直觀的方法是直接新建文件夾,並命名為'out'. 使用Python的os包也可以實現。

import os os.mkdir('.\\out') 

將prices導出為CSV文件后,可以打開查看。也可以使用EXCEL進行操作。

Date,Open,High,Low,Close,Volume,Adj Close,action,value ... 2016-02-01,96.470001,96.709999,95.400002,96.43,40943500,93.923996,, 2016-02-02,95.419998,96.040001,94.279999,94.480003,37357200,92.024676,, 2016-02-03,95.0,96.839996,94.080002,96.349998,45964300,93.846074,, 2016-02-04,95.860001,97.330002,95.190002,96.599998,46471700,94.600127,DIVIDEND,0.52 2016-02-05,96.519997,96.919998,93.690002,94.019997,46418100,92.073538,, 2016-02-08,93.129997,95.699997,93.040001,95.010002,54021400,93.043048,, ... 

Python可以很方便地對金融數據進行相關操作,我將在未來的筆記中討論具體的做法。如果您發現任何問題或有任何疑問,歡迎指正或討論。



作者:JohnnyMOON
鏈接:https://www.jianshu.com/p/799027dd979a
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM