---
title: "Universes"
description: "This page explains how to request historical data for a universe of Futures contracts."
canonical: https://www.quantconnect.com/docs/v2/research-environment/datasets/futures/universes
markdown: https://www.quantconnect.com/docs/v2/research-environment/datasets/futures/universes.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/04%20Research%20Environment/03%20Datasets/12%20Futures/02%20Universes
modified: 2026-11-02
index: https://www.quantconnect.com/llms.txt
---

# Universes

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Research Environment](https://www.quantconnect.com/docs/v2/research-environment.md) > Datasets > Futures > Universes

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## 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. Create a `QuantBook`.
   ```python
   qb = QuantBook()
   ```
2. Call the `add_future` method with a ticker, resolution, and [contract rollover settings](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts).
   ```python
   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](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-futures.md#09-Supported-Assets).
   If you omit any of the arguments after the ticker, see the following table for their default values:
   | Argument | Default Value |
   | --- | --- |
   | `resolution` | `Resolution.MINUTE` |
   | `data_normalization_mode` | `DataNormalizationMode.ADJUSTED` |
   | `data_mapping_mode` | `DataMappingMode.OPEN_INTEREST` |
   | `contract_depth_offset` | 0 |

## Contract Price History

The [contract filter](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#13-Filter-Contracts) 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 `set_filter` method.

```python
# 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 `future_history` method with the `Symbol` of the continuous Futures contract, a start `datetime`, and an end `datetime`.

```python
# 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_history` method returns a `FutureHistory` object. To get each [Slice](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md) in the `FutureHistory` object, iterate through it.

```python
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.

```python
history.data_frame
```

| expiry | symbol | time | askclose | askhigh | asklow | askopen | asksize | bidclose | bidhigh | bidlow | bidopen | bidsize | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 2025-06-20 | ES YTG30NVEFCW1 | 2025-04-01 09:31:00 | 5631.50 | 5639.75 | 5631.50 | 5639.00 | 19.0 | 5631.25 | 5639.50 | 5631.25 | 5638.75 | 24.0 | 5631.25 | 5639.75 | 5631.25 | 5638.75 | 11661.0 |
| 2025-06-20 | ES YTG30NVEFCW1 | 2025-04-01 09:32:00 | 5629.00 | 5634.00 | 5628.00 | 5631.50 | 23.0 | 5628.75 | 5633.75 | 5627.75 | 5631.25 | 1.0 | 5629.00 | 5633.75 | 5627.75 | 5631.25 | 7613.0 |
| 2025-06-20 | ES YTG30NVEFCW1 | 2025-04-01 09:33:00 | 5636.25 | 5638.25 | 5628.25 | 5629.00 | 41.0 | 5636.00 | 5638.00 | 5628.00 | 5628.75 | 10.0 | 5636.00 | 5638.00 | 5628.25 | 5629.00 | 6543.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2025-09-19 | ES YVXOP65RE0HT | 2025-04-02 16:58:00 | 5631.25 | 5638.50 | 5630.00 | 5637.25 | 1.0 | 5629.00 | 5636.00 | 5627.25 | 5635.00 | 2.0 | 5634.00 | 5635.00 | 5634.00 | 5635.00 | 3.0 |
| 2025-09-19 | ES YVXOP65RE0HT | 2025-04-02 16:59:00 | 5625.75 | 5636.00 | 5624.00 | 5631.25 | 1.0 | 5623.50 | 5632.75 | 5620.75 | 5629.00 | 2.0 | 5627.00 | 5627.00 | 5627.00 | 5627.00 | 1.0 |
| 2025-09-19 | ES YVXOP65RE0HT | 2025-04-02 17:00:00 | 5633.25 | 5634.50 | 5625.75 | 5625.75 | 1.0 | 5630.50 | 5632.00 | 5623.50 | 5623.50 | 1.0 | 5628.75 | 5628.75 | 5626.75 | 5626.75 | 36.0 |

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

```python
expiries = history.get_expiry_dates()
```

## Continuous Price History

To get historical [trade](https://www.quantconnect.com/docs/v2/research-environment/datasets/futures/individual-contracts.md#03-Trade-History), [quote](https://www.quantconnect.com/docs/v2/research-environment/datasets/futures/individual-contracts.md#04-Quote-History), or [tick](https://www.quantconnect.com/docs/v2/research-environment/datasets/futures/individual-contracts.md#05-Tick-History) data for the [continuous contract](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/requesting-data/universes.md#03-Continous-Contracts), use the `symbol` property of the `Future` object when you make the history request.

```python
# 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)
```

| expiry | symbol | time | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1899-12-30 | /ES | 2025-01-02 17:00:00 | 5972.236830 | 6037.810377 | 5926.587554 | 6020.408166 | 1496415.0 |
| 1899-12-30 | /ES | 2025-01-03 17:00:00 | 6038.062583 | 6049.664056 | 5986.360364 | 5997.457425 | 1009229.0 |
| 1899-12-30 | /ES | 2025-01-06 17:00:00 | 6081.442006 | 6121.794957 | 6056.978029 | 6085.981713 | 1207465.0 |
| 1899-12-30 | /ES | 2025-01-07 17:00:00 | 6007.293457 | 6098.844216 | 5987.369187 | 6095.313333 | 1543464.0 |
| 1899-12-30 | /ES | 2025-01-08 17:00:00 | 6007.293457 | 6024.443462 | 5969.210359 | 6006.536839 | 1436052.0 |
| 1899-12-30 | /ES | ... | ... | ... | ... | ... | ... |
| 1899-12-30 | /ES | 2025-03-25 17:00:00 | 5832.000000 | 5837.250000 | 5809.500000 | 5826.000000 | 842430.0 |
| 1899-12-30 | /ES | 2025-03-26 17:00:00 | 5754.750000 | 5834.500000 | 5743.000000 | 5824.000000 | 1269497.0 |
| 1899-12-30 | /ES | 2025-03-27 17:00:00 | 5741.250000 | 5779.750000 | 5720.000000 | 5742.750000 | 1287285.0 |
| 1899-12-30 | /ES | 2025-03-28 17:00:00 | 5602.500000 | 5731.250000 | 5602.250000 | 5723.500000 | 1595221.0 |
| 1899-12-30 | /ES | 2025-03-31 17:00:00 | 5644.500000 | 5672.750000 | 5533.750000 | 5563.500000 | 1766518.0 |

## Symbol Changes History

To get historical [symbol change data](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/handling-data.md#09-Symbol-Changes), 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.

```python
# Get the rollovers of the continuous contract.
history = qb.history(SymbolChangedEvent, future.symbol, datetime(2024, 1, 1), datetime(2025, 1, 1))
```

| expiry | symbol | time | newsymbol | oldsymbol |
| --- | --- | --- | --- | --- |
| 1899-12-30 | /ES | 2024-03-13 | ES YJHOAMPYKQGX | ES YGT6HGVF2SQP |
| 1899-12-30 | /ES | 2024-06-19 | ES YLZ9Z50BJE2P | ES YJHOAMPYKQGX |
| 1899-12-30 | /ES | 2024-09-18 | ES YOGVNNAOI1OH | ES YLZ9Z50BJE2P |
| 1899-12-30 | /ES | 2024-12-18 | ES YQYHC5L1GPA9 | ES YOGVNNAOI1OH |

```python
# 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.

```python
# 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` 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.

```python
# Get the daily contract objects during Q1 2025.
history = qb.history(FutureUniverse, future.symbol, datetime(2025, 1, 1), datetime(2025, 4, 1), flatten=True)
```

| time | symbol | close | high | low | open | openinterest | value | volume |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 2025-01-03 | ES YQYHC5L1GPA9 | 5920.000 | 5985.000 | 5874.750 | 5967.750 | 2068557.0 | 5920.000 | 1496415.0 |
| 2025-01-03 | ES YTG30NVEFCW1 | 5975.750 | 6037.500 | 5930.000 | 6018.750 | 7388.0 | 5975.750 | 1305.0 |
| 2025-01-03 | ES YVXOP65RE0HT | 6030.250 | 6030.250 | 6000.000 | 6017.750 | 393.0 | 6030.250 | 13.0 |
| 2025-01-03 | ES YYFADOG4CO3L | 6086.625 | 6185.750 | 5938.875 | 6133.375 | 1152.0 | 6086.625 | 0.0 |
| 2025-01-03 | ES Z0WW26QHBBPD | 6139.000 | 6187.375 | 6113.375 | 6187.375 | 0.0 | 6139.000 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2025-03-29 | ES Z0WW26QHBBPD | 5750.000 | 5750.000 | 5750.000 | 5750.000 | 6.0 | 5750.000 | 1.0 |
| 2025-03-29 | ES Z3EHQP0U9ZB5 | 0.000 | 0.000 | 0.000 | 0.000 | 0.0 | 0.000 | 0.0 |
| 2025-04-01 | ES YTG30NVEFCW1 | 5644.500 | 5672.750 | 5533.750 | 5563.500 | 2082053.0 | 5644.500 | 1766518.0 |
| 2025-04-01 | ES YVXOP65RE0HT | 5691.750 | 5719.750 | 5580.000 | 5612.000 | 7042.0 | 5691.750 | 632.0 |
| 2025-04-01 | ES YYFADOG4CO3L | 5735.000 | 5821.125 | 5617.750 | 5654.250 | 2540.0 | 5735.000 | 0.0 |

```python
# 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
```

```python
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.

```python
# 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:

*Members of `QuantConnect.Data.UniverseSelection.FutureUniverse` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Data.UniverseSelection.FutureUniverse&language=python*

## 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.

```python
# 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.](https://cdn.quantconnect.com/i/tu/research-environment-es-continuous-contract-price.png)
