book
Checkout our new book! Hands on AI Trading with Python, QuantConnect, and AWS Learn More arrow

Futures

Universes

Introduction

This page explains how to request historical data for a universe of Futures contracts.

Create Subscriptions

Follow these steps to subscribe to a Futures universe:

  1. Load the assembly files and data types in their own cell.
  2. #load "../Initialize.csx"
  3. Import the data types.
  4. #load "../QuantConnect.csx"
    #r "../Microsoft.Data.Analysis.dll"
    
    using QuantConnect;
    using QuantConnect.Data;
    using QuantConnect.Algorithm;
    using QuantConnect.Research;
    using QuantConnect.Indicators;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using Microsoft.Data.Analysis;
  5. Create a QuantBook.
  6. var qb = new QuantBook();
    qb = QuantBook()
  7. Call the AddFutureadd_future method with a ticker, resolution, and contract rollover settings.
  8. var future = qb.AddFuture(
        Futures.Indices.SP500EMini, 
        Resolution.Minute,
        dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
        dataMappingMode: DataMappingMode.LastTradingDay,
        contractDepthOffset: 0
    );
    future = qb.add_future(
        Futures.Indices.SP_500_E_MINI, 
        Resolution.MINUTE,
        data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
        data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
        contract_depth_offset=0
    )

    To view the available tickers in the US Futures dataset, see Supported Assets.

    If you omit any of the arguments after the ticker, see the following table for their default values:

    ArgumentDefault Value
    resolutionResolution.MinuteResolution.MINUTE
    dataNormalizationModedata_normalization_modeDataNormalizationMode.AdjustedDataNormalizationMode.ADJUSTED
    dataMappingModedata_mapping_modeDataMappingMode.OpenInterest
    contractDepthOffsetcontract_depth_offset0

Contract Price History

The contract filter determines which Futures contracts are in your universe each trading day. The default filter doesn't select any contracts. To change the filter, call the SetFilterset_filter method.

// Set the contract filter to select contracts that expire within 180 days.
future.SetFilter(0, 180);
# Set the contract filter to select contracts that expire within 180 days.
future.set_filter(0, 180)

To get the prices and volumes for all of the Futures contracts that pass your filter during a specific period of time, call the FutureHistoryfuture_history method with the Symbol of the continuous Futures contract, a start DateTimedatetime, and an end DateTimedatetime.

// Set the contract filter to select contracts that expire within 180 days.
var history = qb.FutureHistory(
    future.Symbol, new DateTime(2025, 4, 1), new DateTime(2025, 4, 3), Resolution.Minute, 
    fillForward: false, extendedMarketHours: false
);
# Set the contract filter to select contracts that expire within 180 days.
history = qb.future_history(
    future.Symbol, datetime(2025, 4, 1), datetime(2025, 4, 3), Resolution.MINUTE, 
    fill_forward=False, extended_market_hours=False
)

The future_historyFutureHistory method returns a FutureHistory object. To get each Slice in the FutureHistory object, iterate through it.

foreach (var slice in history)
{
    foreach (var kvp in slice.FuturesChains)
    {
        var continuousContractSymbol = kvp.Key;
        var chain = kvp.Value;
        foreach (var contract in chain)
        {
            
        }
    }
}
for slice_ in history:
    for continuous_contract_symbol, chain in slice_.futures_chains.items(): 
        for contract in chain:
            pass

To convert the FutureHistory object to a DataFrame that contains the trade and quote information of each contract, use the data_frame property.

history.data_frame
askcloseaskhighasklowaskopenasksizebidclosebidhighbidlowbidopenbidsizeclosehighlowopenvolume
expirysymboltime
2025-06-20ES YTG30NVEFCW12025-04-01 09:31:005631.505639.755631.505639.0019.05631.255639.505631.255638.7524.05631.255639.755631.255638.7511661.0
2025-04-01 09:32:005629.005634.005628.005631.5023.05628.755633.755627.755631.251.05629.005633.755627.755631.257613.0
2025-04-01 09:33:005636.255638.255628.255629.0041.05636.005638.005628.005628.7510.05636.005638.005628.255629.006543.0
......................................................
2025-09-19ES YVXOP65RE0HT2025-04-02 16:58:005631.255638.505630.005637.251.05629.005636.005627.255635.002.05634.005635.005634.005635.003.0
2025-04-02 16:59:005625.755636.005624.005631.251.05623.505632.755620.755629.002.05627.005627.005627.005627.001.0
2025-04-02 17:00:005633.255634.505625.755625.751.05630.505632.005623.505623.501.05628.755628.755626.755626.7536.0

To get the expiration dates of all the contracts in a FutureHistory object, call the get_expiry_datesGetExpiryDates method.

var expiries = history.GetExpiryDates();
expiries = history.get_expiry_dates()

Continuous Price History

To get historical trade, quote, or tick data for the continuous contract, use the symbolSymbol property of the Future object when you make the history request.

// Get the daily TradeBar objects of the continuous contract. 
var history = qb.History<TradeBar>(future.Symbol, new DateTime(2025, 1, 1), new DateTime(2025, 4, 1), Resolution.Daily);
# Get the daily TradeBar objects of the continuous contract. 
history = qb.history(TradeBar, future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1), Resolution.DAILY)
closehighlowopenvolume
expirysymboltime
1899-12-30/ES2025-01-02 17:00:005972.2368306037.8103775926.5875546020.4081661496415.0
2025-01-03 17:00:006038.0625836049.6640565986.3603645997.4574251009229.0
2025-01-06 17:00:006081.4420066121.7949576056.9780296085.9817131207465.0
2025-01-07 17:00:006007.2934576098.8442165987.3691876095.3133331543464.0
2025-01-08 17:00:006007.2934576024.4434625969.2103596006.5368391436052.0
..................
2025-03-25 17:00:005832.0000005837.2500005809.5000005826.000000842430.0
2025-03-26 17:00:005754.7500005834.5000005743.0000005824.0000001269497.0
2025-03-27 17:00:005741.2500005779.7500005720.0000005742.7500001287285.0
2025-03-28 17:00:005602.5000005731.2500005602.2500005723.5000001595221.0
2025-03-31 17:00:005644.5000005672.7500005533.7500005563.5000001766518.0

Symbol Changes History

To get historical symbol change data, call the History<SymbolChangedEvent> method with the continuous contract Symbol.

To get historical symbol change data, call the history method with the SymbolChangedEvent type and the continuous contract Symbol. This method returns a DataFrame that contains the old and new Symbol for each rollover.

// Get the rollovers of the continuous contract. 
var history = qb.History<SymbolChangedEvent>(future.Symbol, new DateTime(2024, 1, 1), new DateTime(2025, 1, 1));
# Get the rollovers of the continuous contract. 
history = qb.history(SymbolChangedEvent, future.symbol, datetime(2024, 1, 1), datetime(2025, 1, 1))
newsymbololdsymbol
expirysymboltime
1899-12-30/ES2024-03-13ES YJHOAMPYKQGXES YGT6HGVF2SQP
2024-06-19ES YLZ9Z50BJE2PES YJHOAMPYKQGX
2024-09-18ES YOGVNNAOI1OHES YLZ9Z50BJE2P
2024-12-18ES YQYHC5L1GPA9ES YOGVNNAOI1OH
# Select the dates of each rollover.
dates = list(history.index.levels[2])

If you intend to use the data in the DataFrame to create SymbolChangedEvent objects, request that the history request returns the data type you need. Otherwise, LEAN consumes unnecessary computational resources populating the DataFrame. To get a list of SymbolChangedEvent objects instead of a DataFrame, call the history[SymbolChangedEvent] method.

# Get the rollovers of the continuous contract in SymbolChangedEvent format. 
history = qb.history[SymbolChangedEvent](symbol, datetime(2024, 1, 1), datetime(2025, 1, 1))
# Iterate through each SymbolChangedEvent object.
for symbol_changed_event in history:
    t = symbol_changed_event.end_time
    old_symbol = symbol_changed_event.old_symbol
    new_symbol = symbol_changed_event.new_symbol

Daily Prices History

To get daily data on all the tradable contracts for a given date, call the History<FutureUniverse> method with the continuous Futures contract Symbol. To get daily data on all the tradable contracts for a given date, call the history method with the FutureUniverse type and the continuous contract Symbol. If you pass flatten=True, this method returns a DataFrame with columns for the data point attributes. The result contains the entire Futures chain for each trading day, not the subset of contracts that pass your universe filter. The daily Futures chains contain the prices, volume, and open interest.

// Get the daily contract objects during Q1 2025.
var history = qb.History<FutureUniverse>(future.Symbol, new DateTime(2025, 1, 1), new DateTime(2025, 4, 1)); 
// Iterate through each day of the history.
foreach (var futureUniverse in history)
{
    var t = futureUniverse.EndTime;
    // Select the contract with the greatest open interest.
    var mostOi = futureUniverse.Select(c => c as FutureUniverse).OrderByDescending(c => c.OpenInterest).First();
}
# Get the daily contract objects during Q1 2025. 
history = qb.history(FutureUniverse, future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1), flatten=True)
closehighlowopenopeninterestvaluevolume
timesymbol
2025-01-03ES YQYHC5L1GPA95920.0005985.0005874.7505967.7502068557.05920.0001496415.0
ES YTG30NVEFCW15975.7506037.5005930.0006018.7507388.05975.7501305.0
ES YVXOP65RE0HT6030.2506030.2506000.0006017.750393.06030.25013.0
ES YYFADOG4CO3L6086.6256185.7505938.8756133.3751152.06086.6250.0
ES Z0WW26QHBBPD6139.0006187.3756113.3756187.3750.06139.0000.0
...........................
2025-03-29ES Z0WW26QHBBPD5750.0005750.0005750.0005750.0006.05750.0001.0
ES Z3EHQP0U9ZB50.0000.0000.0000.0000.00.0000.0
2025-04-01ES YTG30NVEFCW15644.5005672.7505533.7505563.5002082053.05644.5001766518.0
ES YVXOP65RE0HT5691.7505719.7505580.0005612.0007042.05691.750632.0
ES YYFADOG4CO3L5735.0005821.1255617.7505654.2502540.05735.0000.0
# Select the contract with the largest open interest each day.
most_oi = history.groupby('time').apply(lambda x: x.nlargest(1, 'openinterest')).reset_index(level=1, drop=True).openinterest
time        symbol         
2025-01-03  ES YQYHC5L1GPA9    2068557.0
2025-01-04  ES YQYHC5L1GPA9    2068557.0
2025-01-07  ES YQYHC5L1GPA9    2048207.0
2025-01-08  ES YQYHC5L1GPA9    2058863.0
2025-01-09  ES YQYHC5L1GPA9    2047807.0
                                 ...    
2025-03-26  ES YTG30NVEFCW1    2086227.0
2025-03-27  ES YTG30NVEFCW1    2064932.0
2025-03-28  ES YTG30NVEFCW1    2070698.0
2025-03-29  ES YTG30NVEFCW1    2064619.0
2025-04-01  ES YTG30NVEFCW1    2082053.0
Name: openinterest, Length: 62, dtype: float64

If you intend to use the data in the DataFrame to create FutureUniverse objects, request that the history request returns the data type you need. Otherwise, LEAN consumes unnecessary computational resources populating the DataFrame. To get a list of FutureUniverse objects instead of a DataFrame, call the history[FutureUniverse] method.

# Get the 5 trailing daily FutureUniverse objects in FutureUniverse format. 
history = qb.history[FutureUniverse](future.symbol, 5, Resolution.DAILY)
# Iterate through the FutureUniverse objects and access their volumes.
for future_universe in history:
    t = future_universe.end_time
    most_oi = sorted(future_universe, key=lambda contract: contract.open_interest)[-1]

The method represents each contract with an FutureUniverse object, which have the following properties:

Examples

The following examples demonstrate some common practices for applying the Futures dataset.

Example 1: 5-Minute Candlestick Plot

The following example studies the candlestick pattern of the ES Future. To study the short term pattern, we consolidate the data into 5 minute bars and plot the 5-minute candlestick plot.

// Load the required assembly files and data types in a separate cell.
#load "../Initialize.csx"

#load "../QuantConnect.csx"
using System;
using QuantConnect;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Data.Consolidators;
using QuantConnect.Indicators;
using QuantConnect.Algorithm;
using QuantConnect.Research;
using QuantConnect.Securities;

// Import Plotly for plotting.
#r "../Plotly.NET.dll"
using Plotly.NET;
using Plotly.NET.LayoutObjects;

// Create a QuantBook.
var qb = new QuantBook();

// Request the continuous future historical data.
var future = qb.AddFuture(Futures.Indices.SP500EMini);
var history = qb.History<TradeBar>(future.Symbol, 
    start: new DateTime(2024, 7, 1),
    end: new DateTime(2025, 1, 1),
    resolution: Resolution.Minute,
    fillForward: true,
    extendedMarketHours: true,
    dataMappingMode: DataMappingMode.OpenInterest,
    dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
    contractDepthOffset: 0);

// Set up a consolidator and a RollingWindow to save the data
var consolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5));
var window = new RollingWindow<TradeBar>(10000);

// Attach a consolidation handler method that saves the consolidated bars in the RollingWindow
consolidator.DataConsolidated += (sender, consolidated) =>
{
    window.Add(consolidated);
};

// Iterate the historical market data and feed each bar into the consolidator
foreach(var bar in history)
{
    consolidator.Update(bar);
}

// Crete the Candlestick chart using the 5-minute windows.
var chart = Chart2D.Chart.Candlestick<decimal, decimal, decimal, decimal, DateTime, string>(
    window.Select(x => x.Open),
    window.Select(x => x.High),
    window.Select(x => x.Low),
    window.Select(x => x.Close),
    window.Select(x => x.EndTime)
);
// Create a Layout as the plot settings.
LinearAxis xAxis = new LinearAxis();
xAxis.SetValue("title", "Time");
LinearAxis yAxis = new LinearAxis();
yAxis.SetValue("title", "Price ($)");
Title title = Title.init($"{future.Symbol} Price");

Layout layout = new Layout();
layout.SetValue("xaxis", xAxis);
layout.SetValue("yaxis", yAxis);
layout.SetValue("title", title);
// Assign the Layout to the chart.
chart.WithLayout(layout);
// Display the plot.
HTML(GenericChart.toChartHTML(chart))
# Import plotly library for plotting.
import plotly.graph_objects as go

# Create a QuantBook
qb = QuantBook()

# Request the continuous future historical data.
# Use raw normalization mode to fairly compare the actual bid and ask dollar volume.
future = qb.add_future(Futures.Indices.SP_500_E_MINI)
history = qb.history(
    future.symbol, 
    start=datetime(2024, 7, 1), 
    end=datetime(2025, 1, 1), 
    resolution=Resolution.MINUTE, 
    fill_forward=True, 
    extended_market_hours=True, 
    data_mapping_mode=DataMappingMode.OPEN_INTEREST, 
    data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO, 
    contract_depth_offset=0
)

# Drop level 0, 1 index (Symbol index) from the DataFrame
history = history.droplevel([0, 1])

# Select the required columns to obtain the 5-minute OHLC data.
history = history[["open", "high", "low", "close"]].resample("5T").agg({
    "open": "first",
    "high": "max",
    "low": "min",
    "close": "last"
})

# Crete the Candlestick chart using the 5-minute windows.
candlestick = go.Candlestick(
    x=history.index,
    open=history['open'],
    high=history['high'],
    low=history['low'],
    close=history['close']
)
# Create a Layout as the plot settings.
layout = go.Layout(
    title=go.layout.Title(text=f'{future.symbol} OHLC'),
    xaxis_title='Date',
    yaxis_title='Price',
    xaxis_rangeslider_visible=False
)
# Create the Figure.
fig = go.Figure(data=[candlestick], layout=layout)
# Display the plot.
fig.show()
ES continuous contract candlestick plot.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: