pandas获取雅虎金融数据

作者: 海墨星人 | 来源:发表于2017-04-20 17:06 被阅读140次
    pandas.jpg

    首先,强烈推荐关注Dr. Fish, 每篇文章都很有深度。因为受到她《用Python浅析股票数据》文章的启发,所以分享下最近几天学习获取股票交易历史数据的总结.

    pandas 官方文档
    matplotlib 官方文档
    上证指数

    首先,需要引入相应的包

    import pandas as pd
    import numpy as np
    from pandas_datareader import data, wb # 需要安装 pip install pandas_datareader
    import datetime
    import matplotlib.pyplot as plt
    import matplotlib
    matplotlib.style.use('ggplot')
    %matplotlib inline
    %pylab inline
    %config InlineBackend.figure_format = 'retina'
    

    如果采用anaconda,安装办法参考: 检索和安装package

    如果是pycharm等其他开发环境,请

    pip install pandas_datareader 
    

    利用DataReader获取数据,今天是20170420,获取从4月1日到19日的数据

    # 定义获取数据的时间段
    start = datetime.datetime(2017, 4, 1)
    end = datetime.date.today()
    
    # 获取股票信息 ex: 中国石油
    # 如果要看上证指数请参考换成600000.ss
    # 如果要看深成指请换成000001.sz
    cnpc = data.DataReader("601857.SS", 'yahoo', start, end)
    
    cnpc.head(5)
    
    Open High Low Close Volume Adj Close
    Date
    2017-04-03 7.87 7.87 7.87 7.87 0 7.87
    2017-04-04 7.87 7.87 7.87 7.87 0 7.87
    2017-04-05 7.87 7.98 7.85 7.97 54742900 7.97
    2017-04-06 7.94 7.99 7.93 7.98 40905400 7.98
    2017-04-07 8.00 8.13 7.98 8.05 81109300 8.05

    获取统计信息

    cnpc.describe() # 数据整体概览
    
    Open High Low Close Volume Adj Close
    count 13.000000 13.000000 13.000000 13.000000 1.300000e+01 13.000000
    mean 7.978462 8.025385 7.931538 7.984615 3.532568e+07 7.984615
    std 0.078830 0.091526 0.078299 0.089220 2.115596e+07 0.089220
    min 7.870000 7.870000 7.750000 7.800000 0.000000e+00 7.800000
    25% 7.900000 7.980000 7.870000 7.960000 2.729580e+07 7.960000
    50% 8.000000 8.060000 7.950000 8.020000 3.735440e+07 8.020000
    75% 8.040000 8.080000 7.980000 8.050000 4.342920e+07 8.050000
    max 8.080000 8.130000 8.030000 8.100000 8.110930e+07 8.100000
    #修改索引和列的名称
    cnpc.rename(columns={'Open':'open', 'High':'high', 'Low':'low', 'Close':'close','Volume':'volumne','Adj Close':'adj close'}, inplace=True)
    cnpc.index.rename('date', inplace=True)
    
    open high low close volume adj close
    date
    2017-04-03 7.87 7.87 7.87 7.87 0 7.87
    2017-04-04 7.87 7.87 7.87 7.87 0 7.87
    2017-04-05 7.87 7.98 7.85 7.97 54742900 7.97
    2017-04-06 7.94 7.99 7.93 7.98 40905400 7.98

    因为实验数据太少,现将20170401 改成20170301

    cnpc.columns
    # outputs: Index(['open', 'high', 'low', 'close', 'volumne', 'adj close', 'change','pct_change'],dtype='object')
    

    试做收盘价曲线

    cnpc['close'].plot(grid=True)
    
    收盘曲线图

    我们看到由于清明节放假原因4月3号,4号休市。剔除volume为空的行

    cnpc[cnpc.volume != 0]
    

    计算涨跌值

    # 利用 diff 函数快速计算涨跌幅
    change=cnpc.close.diff()
    #插入列
    cnpc.insert(6,'change', change)
    cnpc.tail(5)
    

    ||open|high|low|close|volumne|adj close|change|
    | ------------- |:-------------:| -----:|-----:|-----:|-----:|-----:|
    |date||||||||
    |2017-04-13|8.08|8.11|8.03|8.06|29579200|8.06|-0.04|
    |2017-04-14|8.05|8.07|8.00|8.02|27295800|8.02|-0.04|
    |2017-04-17|7.99|8.07|7.95|8.05|34244900|8.05|0.03|
    |2017-04-18|8.02|8.05|7.95|7.96|25706900|7.96|-0.09|
    |2017-04-19|7.90|7.92|7.75|7.80|37354400|7.80|-0.16 |

    计算涨跌幅

    # 用shift方法错位
    # cnpc['pct_change'] = ((cnpc['Change'] - sh['Change'].shift(1)) / sh['Change'])
    # 或用pct_Change函数
    cnpc.change.pct_change()
    cnpc.insert(7,'pct_change', cnpc.change.pct_change())
    cnpc.tail(5)
    

    ||open|high|low|close|volume|adj close|change|pct_change|
    | ------------- |:-------------:| -----:|-----:|-----:|-----:|-----:|-----:|
    |date||||||||
    |2017-04-13|8.08|8.11|8.03|8.06|29579200|8.06|-0.04|-1.500000e+00|
    |2017-04-14|8.05|8.07|8.00|8.02|27295800|8.02|-0.04|4.440892e-14|
    |2017-04-17|7.99|8.07|7.95|8.05|34244900|8.05|0.03|-1.750000e+00|
    |2017-04-18|8.02|8.05|7.95|7.96|25706900|7.96|-0.09|-4.000000e+00|
    |2017-04-19|7.90|7.92|7.75|7.80|37354400|7.80|-0.16|7.777778e-01|

    shift的用法
    shift函数是对数据进行移动的操作,假如现在有一个DataFrame数据df

    | index | value1 |
    | ------------- | -----:||
    | A| 0 |
    | B| 1 |
    | C | 2 |
    | D | 3 |

    df.shift()
    

    | index | value1 |
    | ------------- | -----:||
    | A| NaN |
    | B| 0|
    | C | 1 |
    | D | 2 |
    函数原型:

    DataFrame.shift(periods=1, freq=None, axis=0)
    #periods:类型为int,表示移动的幅度,可以是正数,也可以是负数,默认值是1,1就表示移动一次,注意这里移动的都是数据,而索引是不移动的,移动之后没有对应值的,就赋值为NaN。
    执行以下代码:
    df.shift(2)
    

    | index | value1 |
    | ------------- | -----:||
    | A| NaN |
    | B| NaN|
    | C | 0|
    | D | 1 |

    df.shift(-1)
    

    | index | value1 |
    | ------------- | -----:||
    | A| 1|
    | B| 2|
    | C | 3|
    | D | NaN |

    计算5日,20日均线

    cnpc["ma5"] = np.round(cnpc["close"].rolling(window = 5, center = False).mean(), 2)
    cnpc["ma20"] = np.round(cnpc["close"].rolling(window = 20, center = False).mean(), 2)
    
    5日均线.png

    用matplotlib图形化显示价格信息以及变动

    rom datetime import datetime
    from dateutil.parser import parse
    from matplotlib.dates import AutoDateLocator, DateFormatter,DayLocator
    
    
    # date = cnpc['date']
    # date = pd.to_datetime(date)
    date = cnpc.index
    high = cnpc['high'].values
    low = cnpc['low'].values
    open= cnpc['open'].values
    close = cnpc['close'].values
    ma5 = cnpc['ma5'].values
    ma10 = cnpc['ma10'].values
    ma20 = cnpc['ma20'].values
    # turnover=stock_data['turnover'].values
    
    
    fig = plt.figure(figsize = (15,15))
    ax = fig.add_subplot(211)
    ax.set_title("Stock price")
    ax.plot(date,open,label='open')
    ax.plot(date,high,label='high')
    ax.plot(date,low,label = 'low')
    ax.plot(date,close,label = 'close')
    ax.plot(date,ma5,label = 'ma5')
    ax.plot(date,ma10,label = 'ma10')
    ax.plot(date,ma20,label = 'ma20')
    # ax.plot(date,turnover,label='turnover')
    
    ax.set_xlabel("date")
    ax.set_ylabel("values")
    ax.xaxis.set_major_locator(DayLocator(bymonthday=range(1,32), interval=1)) 
    ax.xaxis.set_major_formatter(DateFormatter('%Y%m%d')) 
    plt.xticks(rotation=60)
    plt.legend(loc='upper left') 
    
    plt.grid(True)
    plt.show()
    
    价格变动.png

    假设5日均线与20日均线的交叉点,是交易的时机。移动平均线策略,最简单的方式就是:当5日均线从下方超越20日均线时,买入股票,当5日均线从上方越到20日均线之下时,卖出股票。

    为了找出交易的时机,我们计算5日均价和20日均价的差值,并取其正负号,作于下图。当图中水平线出现跳跃的时候就是交易时机。

    cnpc['ma5-20'] = cnpc['ma5'] - cnpc['ma20']
    cnpc['Diff'] = np.sign(cnpc['ma5-20']) # sign是取+-
    cnpc['Diff'].dropna().plot(ylim=(-2,2)).axhline(y=0, color='black', lw=2)
    
    Paste_Image.png

    K线图

    首先非常感谢DrFish提供的思路,K线图可以将最高价、最低价、开盘价、收盘价四个价格指标很好的显示出来

    Paste_Image.png

    如下代码引用自DrFish的文章:

    from matplotlib.finance import candlestick_ohlc
    from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY
    # TUESDAY 仅仅在X粥主轴上显示周二的日期
    def pandas_candlestick_ohlc(stock_data, otherseries=None):    
    
        # 设置绘图参数,主要是坐标轴 
        mondays = WeekdayLocator(MONDAY) 
        alldays = DayLocator()   
        dayFormatter = DateFormatter('%d')
    
        fig, ax = plt.subplots()
        fig.subplots_adjust(bottom=0.2)
        print(stock_data.index)
        print(stock_data.index[-1]) 
        print(stock_data.index[0]) 
        if stock_data.index[-1] - stock_data.index[0] < pd.Timedelta('730 days'):
            weekFormatter = DateFormatter('%b %d')  
            ax.xaxis.set_major_locator(mondays)
            ax.xaxis.set_minor_locator(alldays)
        else:
            weekFormatter = DateFormatter('%b %d, %Y')
        ax.xaxis.set_major_formatter(weekFormatter)
        ax.grid(True)
    
        # 创建K线图   
        stock_array = np.array(stock_data.reset_index()[['date','open','high','low','close']])
        stock_array[:,0] = date2num(stock_array[:,0])
        candlestick_ohlc(ax, stock_array, colorup = "red", colordown="green", width=0.4)
    
    
        # 可同时绘制其他折线图
        if otherseries is not None:
            for each in otherseries:
                plt.plot(stock_data[each], label=each)            
            plt.legend()
    
    
        ax.xaxis_date()
        ax.autoscale_view()
        plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
    
        plt.show()
    
    
    K线图.png

    相关系数展示

    前一篇文章中,我只是通过循环print出各自的相关系数,但是没有进行图形化的展示,通过DrFish的讲解, 此处引用当做笔记

    part=cnpc[['open', 'high', 'low', 'close', 'volumne', 'adj close']]
    cov = np.corrcoef(part.T) # 通过矩阵的转置
    cov
    #array([[ 1.        ,  0.93329891,  0.91815383,  0.81640801, -0.12577619,
             0.81640801],
           [ 0.93329891,  1.        ,  0.938317  ,  0.92304648, -0.00264197,
             0.92304648],
           [ 0.91815383,  0.938317  ,  1.        ,  0.9365154 , -0.21158285,
             0.9365154 ],
           [ 0.81640801,  0.92304648,  0.9365154 ,  1.        , -0.10726339,
             1.        ],
           [-0.12577619, -0.00264197, -0.21158285, -0.10726339,  1.        ,
            -0.10726339],
           [ 0.81640801,  0.92304648,  0.9365154 ,  1.        , -0.10726339,
             1.        ]])
    
    

    如果觉得看数字还是不够方便,我们继续将上述相关性矩阵转换成图形,如下图所示,其中用颜色来代表相关系数。

    img = plt.matshow(cov,cmap=plt.cm.winter)
    plt.colorbar(img, ticks=[-1,0,1])
    plt.show()
    
    表示相关系数的散点图.png

    本文主要是为了熟悉pandas, matplotlib使用,供自己和大家学习参考.

    相关文章

      网友评论

        本文标题:pandas获取雅虎金融数据

        本文链接:https://www.haomeiwen.com/subject/ksokzttx.html