Notebook
In [1]:
import pandas as pd
import numpy as np

import matplotlib.cm as cm
import matplotlib.pyplot as plt

from datetime import timedelta, datetime

from quantopian.research.experimental import continuous_future, history
In [2]:
# All of the available futures categorized in a dictionary for convenience.
available_futures = {
    # Agricultural Commodities
    'ag_commodities': {
        'soybean': continuous_future('SY'),
        'soybean_emini': continuous_future('MS'),
        'soybean_oil': continuous_future('BO'),
        'soybean_meal': continuous_future('SM'),
        'wheat': continuous_future('WC'),
        'wheat_emini': continuous_future('MW'),
        'corn': continuous_future('CN'),
        'corn_emini': continuous_future('CM'),
        'oats': continuous_future('OA'),
        'rough_rice': continuous_future('RR'),
        'sugar': continuous_future('SB'),
        'ethanol': continuous_future('ET'),
        'feeder_cattle': continuous_future('FC'),
        'live_cattle': continuous_future('LC'),
        'lean_hogs': continuous_future('LH'),
        'pork_bellies': continuous_future('PB'),
        'lumber': continuous_future('LB'),
    },

    # Non-Agricultural Commodities
    'non_ag_commodities': {
        'crude_oil': continuous_future('CL'),
        'crude_oil_emini': continuous_future('QM'),
        'natural_gas': continuous_future('NG'),
        'natural_gas_emini': continuous_future('QG'),
        'unleaded_gasoline': continuous_future('HU'),
        'rbob_gasoline': continuous_future('XB'),
        'heating_oil': continuous_future('HO'),
        'gold': continuous_future('GC'),
        'gold_mini': continuous_future('XG'),
        'silver': continuous_future('SV'),
        'silver_mini': continuous_future('YS'),
        'copper': continuous_future('HG'),
        'palladium': continuous_future('PA'),
        'platinum': continuous_future('PL'),
    },

    # Currencies
    'currencies': {
        'jpy': continuous_future('JY'),
        'jpy_emini': continuous_future('JE'),
        'cad': continuous_future('CD'),
        'mxn': continuous_future('ME'),
        'aud': continuous_future('AD'),
        'nzd': continuous_future('NZ'),
        'gbp': continuous_future('BP'),
        'chf': continuous_future('SF'),
        'eur_emicro': continuous_future('EU'),
        'euro_fx': continuous_future('EC'),
        'euro_fx_emini': continuous_future('EE'),
    },

    # Equities
    'equities': {
        'sp500': continuous_future('SP'),
        'sp500_emini': continuous_future('ES'),
        'sp400_midcap': continuous_future('MD'),
        'sp400_midcap_emini': continuous_future('MI'),
        'nasdaq100': continuous_future('ND'),
        'nasdaq100_emini': continuous_future('NQ'),
        'russell1000_emini': continuous_future('RM'),
        'russell2000_emini': continuous_future('ER'),
        'nikkei225': continuous_future('NK'),
        'MSCI_emerging_markets_mini': continuous_future('EI'),
        'MSCI_EAFE_mini': continuous_future('MG'),
        'dow_jones': continuous_future('DJ'),
        'dow_jones_emini': continuous_future('YM'),
        'big_dow': continuous_future('BD'),
        'vix': continuous_future('VX'),
        'bloomberg_commodity_index': continuous_future('AI'),
    },

    # Rates
    'rates': {
        'us_2y': continuous_future('TU'),
        'us_5y': continuous_future('FV'),
        'us_10y': continuous_future('TY'),
        'us_30y': continuous_future('US'),
        'deliverable_interest_rate_swap_5y': continuous_future('FI'),
        'deliverable_interest_rate_swap_10y': continuous_future('TN'),
        'interest_rate_swap_5y': continuous_future('FS'),
        'interest_rate_swap_10y': continuous_future('TS'),
        'municipal_bonds': continuous_future('MB'),
        'utra_tbond': continuous_future('UB'),
        'tbills': continuous_future('TB'),
        'fed30day': continuous_future('FF'),
        'eur': continuous_future('ED'),
        'eurodollar_nyse_liffe': continuous_future('EL'),
    },
}
In [3]:
# Gets the halfway point between two dates so that we can add root symbols as 
# labels in the center of each horizontal line on our chart.
def x_center(start_date, end_date):
    half_seconds = (end_date - start_date).total_seconds() / 2
    half = start_date + timedelta(seconds=half_seconds)
    return half


# Function for plotting a horizontal line + 2 dots at each end for a given future.
def plot_future_lifespan(future, counter, c, a): 
    plt.hlines(y = counter, xmin=future.start_date, xmax=future.end_date, color=c, alpha=a)
    plt.scatter(future.start_date, counter, s=75, c=c, alpha=a)
    plt.scatter(future.end_date, counter, s=75, c=c, alpha=a)
    plt.text(x_center(future.start_date, future.end_date), counter+0.1, future.root_symbol)
In [4]:
# This will be a flattened list of all our futures.
futures = []

# This will be a mapping from root symbol --> sector.
future_sectors = {}

# Get our futures in a flat list and get a mapping of root_symbol --> sector.
for sector in available_futures:
    for future in available_futures[sector].values():
        futures.append(future)
        future_sectors[future.root_symbol] = sector
        
# Sort futures by start_date.
futures = sorted(futures, key=lambda x: x.start_date)

# Then sort futures by sector.
futures = sorted(futures, key=lambda x: future_sectors[x.root_symbol], reverse=True)

# Sort sectors alphabetically.
sectors = sorted(list(set(future_sectors.values())))

# Get a list of colors spaced evenly in the color space.
colors = cm.rainbow(np.linspace(0, 1, len(sectors)))

# Assign these colors to our sectors.
sector_colors = {}

for i in range(len(sectors)):
    sector_colors[sectors[i]] = colors[i]
In [5]:
# Set some visual properties for our plot.
ALPHA = 0.8
plt.figure(figsize=(11, 18))

# Plot each future on a horizontal line. These will be sorted first by sector,
# then by start date (see previous cell for sorting rules).
counter = 1
for future in futures:
    
    sector = future_sectors[future.root_symbol]
    color = sector_colors[sector]
    
    plot_future_lifespan(future, counter, color, ALPHA)
    
    counter += 1
    
ax = plt.gca()

# Remove horizontal grid lines.
ax.yaxis.grid(False) 

# Remove y-axis labels.
ax.yaxis.set_visible(False)

# Set bounds on y axis to remove extra space at top and bottom of the plot.
ax.set_ylim([0, counter])

# Set bounds on x axis to remove extra space on left and right of the plot.
ax.set_xlim([pd.Timestamp('2001-01-01'), pd.Timestamp('2017-08-01')])

# Make our legend to show the sector --> color mappings.
legend_elements = []
for sector in sectors:
    legend_elements.append(plt.Line2D([], [], color=sector_colors[sector], marker='.',
                          markersize=15, label=sector))

# Add our legend to the plot outside the plot.
plt.legend(handles=legend_elements, bbox_to_anchor=(1.35, 0.55), fontsize='large');
In [6]:
print 'Futures that are no longer trading:'

for fut in futures:
    if fut.end_date.date() < pd.Timestamp('2017-04-21').date():
        print fut.root_symbol
Futures that are no longer trading:
MB
TB
FS
TS
EL
HU
DJ
ND
MD
ER
BD
RM
PB