Time for action – using a legend and annotations

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.

  1. Go back to Chapter 3, Getting Familiar with Commonly Used Functions, if needed, and review the EMA algorithm. Calculate and plot the EMAs of 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.

  2. Let's find the crossover points of the first two moving averages:
    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])
  3. Now that we have the crossover points, annotate them with arrows. Make sure that the annotation text is slightly away from the crossover points:
    for xpoint in xpoints:
       ax.annotate('x', xy=xpoint, textcoords='offset points',
                    xytext=(-50, 30),
                    arrowprops=dict(arrowstyle="->"))
  4. Add a legend and let matplotlib decide where to put it:
    leg = ax.legend(loc='best', fancybox=True))
  5. Make the legend transparent by setting the alpha channel value:
    leg.get_frame().set_alpha(0.5)

    The stock price and moving averages with a legend and annotations appears as follows:

    Time for action – using a legend and annotations

What just happened?

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()
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset