In Chapter 3, Getting Familiar with Commonly Used Functions, we learned how to calculate the EMA of stock prices. We will plot the close price of a stock and three of its EMA. To clarify the plot, we will add a legend. We will also indicate crossovers of two of the averages with annotations. Some steps are again omitted to avoid repetition.
9
, 12
, and 15
periods:emas = [] for i in range(9, 18, 3): weights = np.exp(np.linspace(-1., 0., i)) weights /= weights.sum() ema = np.convolve(weights, close)[i-1:-i+1] idx = (i - 6)/3 ax.plot(dates[i-1:], ema, lw=idx, label="EMA(%s)" % (i)) data = np.column_stack((dates[i-1:], ema)) emas.append(np.rec.fromrecords( data, names=["dates", "ema"]))
Notice that the plot()
function call needs a label for the legend. We stored the moving averages in record arrays for the next step.
first = emas[0]["ema"].flatten() second = emas[1]["ema"].flatten() bools = np.abs(first[-len(second):] - second)/second < 0.0001 xpoints = np.compress(bools, emas[1])
for xpoint in xpoints: ax.annotate('x', xy=xpoint, textcoords='offset points', xytext=(-50, 30), arrowprops=dict(arrowstyle="->"))
matplotlib
decide where to put it:leg = ax.legend(loc='best', fancybox=True))
leg.get_frame().set_alpha(0.5)
The stock price and moving averages with a legend and annotations appears as follows:
We plotted the close price of a stock and three of its EMAs. We added a legend to the plot. We annotated the crossover points of the first two averages with annotations (see emalegend.py
):
from matplotlib.finance import quotes_historical_yahoo from matplotlib.dates import DateFormatter from matplotlib.dates import DayLocator from matplotlib.dates import MonthLocator import sys from datetime import date import matplotlib.pyplot as plt import numpy as np today = date.today() start = (today.year - 1, today.month, today.day) symbol = 'DISH' if len(sys.argv) == 2: symbol = sys.argv[1] quotes = quotes_historical_yahoo(symbol, start, today) quotes = np.array(quotes) dates = quotes.T[0] close = quotes.T[4] fig = plt.figure() ax = fig.add_subplot(111) emas = [] for i in range(9, 18, 3): weights = np.exp(np.linspace(-1., 0., i)) weights /= weights.sum() ema = np.convolve(weights, close)[i-1:-i+1] idx = (i - 6)/3 ax.plot(dates[i-1:], ema, lw=idx, label="EMA(%s)" % (i)) data = np.column_stack((dates[i-1:], ema)) emas.append(np.rec.fromrecords(data, names=["dates", "ema"])) first = emas[0]["ema"].flatten() second = emas[1]["ema"].flatten() bools = np.abs(first[-len(second):] - second)/second < 0.0001 xpoints = np.compress(bools, emas[1]) for xpoint in xpoints: ax.annotate('x', xy=xpoint, textcoords='offset points', xytext=(-50, 30), arrowprops=dict(arrowstyle="->")) leg = ax.legend(loc='best', fancybox=True) leg.get_frame().set_alpha(0.5) alldays = DayLocator() months = MonthLocator() month_formatter = DateFormatter("%b %Y") ax.plot(dates, close, lw=1.0, label="Close") ax.xaxis.set_major_locator(months) ax.xaxis.set_minor_locator(alldays) ax.xaxis.set_major_formatter(month_formatter) ax.grid(True) fig.autofmt_xdate() plt.show()