zoukankan      html  css  js  c++  java
  • 使用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
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    通用分页后台显示
    自定义的JSP标签
    Java反射机制
    Java虚拟机栈---本地方法栈
    XML建模实列
    XML解析与xml和Map集合的互转
    [离散数学]第二次作业
    [线性代数]2016.10.13作业
    [数字逻辑]第二次作业
    [线性代数]2016.9.26作业
  • 原文地址:https://www.cnblogs.com/yuhou/p/11103047.html
Copyright © 2011-2022 走看看