Sophie

Sophie

distrib > Fedora > 18 > i386 > by-pkgid > bf21b4394f4d7fa09e3626145d3315e0 > files > 371

python-matplotlib-doc-1.2.0-14.fc18.i686.rpm

.. _pylab_examples-finance_work2:

pylab_examples example code: finance_work2.py
=============================================



.. plot:: /builddir/build/BUILD/matplotlib-1.2.0/doc/mpl_examples/pylab_examples/finance_work2.py

::

    import datetime
    import numpy as np
    import matplotlib.colors as colors
    import matplotlib.finance as finance
    import matplotlib.dates as mdates
    import matplotlib.ticker as mticker
    import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt
    import matplotlib.font_manager as font_manager
    
    
    startdate = datetime.date(2006,1,1)
    today = enddate = datetime.date.today()
    ticker = 'SPY'
    
    
    fh = finance.fetch_historical_yahoo(ticker, startdate, enddate)
    # a numpy record array with fields: date, open, high, low, close, volume, adj_close)
    
    r = mlab.csv2rec(fh); fh.close()
    r.sort()
    
    
    def moving_average(x, n, type='simple'):
        """
        compute an n period moving average.
    
        type is 'simple' | 'exponential'
    
        """
        x = np.asarray(x)
        if type=='simple':
            weights = np.ones(n)
        else:
            weights = np.exp(np.linspace(-1., 0., n))
    
        weights /= weights.sum()
    
    
        a =  np.convolve(x, weights, mode='full')[:len(x)]
        a[:n] = a[n]
        return a
    
    def relative_strength(prices, n=14):
        """
        compute the n period relative strength indicator
        http://stockcharts.com/school/doku.php?id=chart_school:glossary_r#relativestrengthindex
        http://www.investopedia.com/terms/r/rsi.asp
        """
    
        deltas = np.diff(prices)
        seed = deltas[:n+1]
        up = seed[seed>=0].sum()/n
        down = -seed[seed<0].sum()/n
        rs = up/down
        rsi = np.zeros_like(prices)
        rsi[:n] = 100. - 100./(1.+rs)
    
        for i in range(n, len(prices)):
            delta = deltas[i-1] # cause the diff is 1 shorter
    
            if delta>0:
                upval = delta
                downval = 0.
            else:
                upval = 0.
                downval = -delta
    
            up = (up*(n-1) + upval)/n
            down = (down*(n-1) + downval)/n
    
            rs = up/down
            rsi[i] = 100. - 100./(1.+rs)
    
        return rsi
    
    def moving_average_convergence(x, nslow=26, nfast=12):
        """
        compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg'
        return value is emaslow, emafast, macd which are len(x) arrays
        """
        emaslow = moving_average(x, nslow, type='exponential')
        emafast = moving_average(x, nfast, type='exponential')
        return emaslow, emafast, emafast - emaslow
    
    
    plt.rc('axes', grid=True)
    plt.rc('grid', color='0.75', linestyle='-', linewidth=0.5)
    
    textsize = 9
    left, width = 0.1, 0.8
    rect1 = [left, 0.7, width, 0.2]
    rect2 = [left, 0.3, width, 0.4]
    rect3 = [left, 0.1, width, 0.2]
    
    
    fig = plt.figure(facecolor='white')
    axescolor  = '#f6f6f6'  # the axes background color
    
    ax1 = fig.add_axes(rect1, axisbg=axescolor)  #left, bottom, width, height
    ax2 = fig.add_axes(rect2, axisbg=axescolor, sharex=ax1)
    ax2t = ax2.twinx()
    ax3  = fig.add_axes(rect3, axisbg=axescolor, sharex=ax1)
    
    
    
    ### plot the relative strength indicator
    prices = r.adj_close
    rsi = relative_strength(prices)
    fillcolor = 'darkgoldenrod'
    
    ax1.plot(r.date, rsi, color=fillcolor)
    ax1.axhline(70, color=fillcolor)
    ax1.axhline(30, color=fillcolor)
    ax1.fill_between(r.date, rsi, 70, where=(rsi>=70), facecolor=fillcolor, edgecolor=fillcolor)
    ax1.fill_between(r.date, rsi, 30, where=(rsi<=30), facecolor=fillcolor, edgecolor=fillcolor)
    ax1.text(0.6, 0.9, '>70 = overbought', va='top', transform=ax1.transAxes, fontsize=textsize)
    ax1.text(0.6, 0.1, '<30 = oversold', transform=ax1.transAxes, fontsize=textsize)
    ax1.set_ylim(0, 100)
    ax1.set_yticks([30,70])
    ax1.text(0.025, 0.95, 'RSI (14)', va='top', transform=ax1.transAxes, fontsize=textsize)
    ax1.set_title('%s daily'%ticker)
    
    ### plot the price and volume data
    dx = r.adj_close - r.close
    low = r.low + dx
    high = r.high + dx
    
    deltas = np.zeros_like(prices)
    deltas[1:] = np.diff(prices)
    up = deltas>0
    ax2.vlines(r.date[up], low[up], high[up], color='black', label='_nolegend_')
    ax2.vlines(r.date[~up], low[~up], high[~up], color='black', label='_nolegend_')
    ma20 = moving_average(prices, 20, type='simple')
    ma200 = moving_average(prices, 200, type='simple')
    
    linema20, = ax2.plot(r.date, ma20, color='blue', lw=2, label='MA (20)')
    linema200, = ax2.plot(r.date, ma200, color='red', lw=2, label='MA (200)')
    
    
    last = r[-1]
    s = '%s O:%1.2f H:%1.2f L:%1.2f C:%1.2f, V:%1.1fM Chg:%+1.2f' % (
        today.strftime('%d-%b-%Y'),
        last.open, last.high,
        last.low, last.close,
        last.volume*1e-6,
        last.close-last.open )
    t4 = ax2.text(0.3, 0.9, s, transform=ax2.transAxes, fontsize=textsize)
    
    props = font_manager.FontProperties(size=10)
    leg = ax2.legend(loc='center left', shadow=True, fancybox=True, prop=props)
    leg.get_frame().set_alpha(0.5)
    
    
    volume = (r.close*r.volume)/1e6  # dollar volume in millions
    vmax = volume.max()
    poly = ax2t.fill_between(r.date, volume, 0, label='Volume', facecolor=fillcolor, edgecolor=fillcolor)
    ax2t.set_ylim(0, 5*vmax)
    ax2t.set_yticks([])
    
    
    ### compute the MACD indicator
    fillcolor = 'darkslategrey'
    nslow = 26
    nfast = 12
    nema = 9
    emaslow, emafast, macd = moving_average_convergence(prices, nslow=nslow, nfast=nfast)
    ema9 = moving_average(macd, nema, type='exponential')
    ax3.plot(r.date, macd, color='black', lw=2)
    ax3.plot(r.date, ema9, color='blue', lw=1)
    ax3.fill_between(r.date, macd-ema9, 0, alpha=0.5, facecolor=fillcolor, edgecolor=fillcolor)
    
    
    ax3.text(0.025, 0.95, 'MACD (%d, %d, %d)'%(nfast, nslow, nema), va='top',
             transform=ax3.transAxes, fontsize=textsize)
    
    #ax3.set_yticks([])
    # turn off upper axis tick labels, rotate the lower ones, etc
    for ax in ax1, ax2, ax2t, ax3:
        if ax!=ax3:
            for label in ax.get_xticklabels():
                label.set_visible(False)
        else:
            for label in ax.get_xticklabels():
                label.set_rotation(30)
                label.set_horizontalalignment('right')
    
        ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')
    
    
    
    class MyLocator(mticker.MaxNLocator):
        def __init__(self, *args, **kwargs):
            mticker.MaxNLocator.__init__(self, *args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            return mticker.MaxNLocator.__call__(self, *args, **kwargs)
    
    # at most 5 ticks, pruning the upper and lower so they don't overlap
    # with other ticks
    #ax2.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
    #ax3.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
    
    ax2.yaxis.set_major_locator(MyLocator(5, prune='both'))
    ax3.yaxis.set_major_locator(MyLocator(5, prune='both'))
    
    plt.show()
    
    
    

Keywords: python, matplotlib, pylab, example, codex (see :ref:`how-to-search-examples`)