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
# 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'),
},
}
# 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)
# 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]
# 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');
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