---
title: "Futures Universes"
description: "A Future Universe Selection model selects contracts for a set of Futures."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/futures-universes
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/futures-universes.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/34%20Algorithm%20Framework/02%20Universe%20Selection/07%20Futures%20Universes
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Futures Universes

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Algorithm Framework > Universe Selection > Futures Universes

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

## Introduction

A Future Universe Selection model selects contracts for a set of Futures.

## Future Universe Selection

The `FutureUniverseSelectionModel` selects all the contracts for a set of Futures you specify. To use this model, provide a `refresh_interval` and a selector function. The `refresh_interval` defines how frequently LEAN calls the selector function. The selector function receives a `datetime` object that represents the current Coordinated Universal Time (UTC) and returns a list of `Symbol` objects. The `Symbol` objects you return from the selector function are the Futures of the universe.

```python
# Run universe selection asynchronously to speed up your algorithm.
# This setting means you cannot rely on the method or algorithm state between filter calls.
self.universe_settings.asynchronous = True
# Add a universe of E-mini S&P 500 Futures contracts.
self.add_universe_selection(
    FutureUniverseSelectionModel(
        # Refresh the universe daily.
        timedelta(1),
        lambda _: [Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME)]
    )
)
```

The following table describes the arguments the model accepts:

| Argument | Data Type | Description | Default Value |
| --- | --- | --- | --- |
| `refresh_interval` | `timedelta` | Time interval between universe refreshes |  |
| `future_chain_symbol_selector` | `Callable[[datetime], List[Symbol]]` | A function that selects the Future symbols for a given Coordinated Universal Time (UTC). To view the supported assets in the US Futures dataset, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-futures.md#09-Supported-Assets). |  |
| `universe_settings` | `UniverseSettings` | The [universe settings](https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/universe-settings.md). If you don't provide an argument, the model uses the `algorithm.universe_settings` by default. | `None` |

The following example shows how to define the Future chain Symbol selector as an isolated method:

```python
# In the initialize method, add the FutureUniverseSelectionModel with a custom selection function.
def initialize(self) -> None:
    self.set_universe_selection(
        FutureUniverseSelectionModel(timedelta(days=1), self.select_future_chain_symbols)
    )

def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
    # Add E-mini S&P 500 and Gold Futures to the universe.
    return [
        Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME),
        Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
    ]
```

This model uses the default Future contract filter, which doesn't select any Futures contracts. To use a different filter, subclass the `FutureUniverseSelectionModel` and define a `filter` method. The `filter` method accepts and returns a `FutureFilterUniverse` object to select the Futures contracts. The following table describes the filter methods of the `FutureFilterUniverse` class:

`standards_only()`

Selects standard contracts

`weeklys_only()`

Selects weekly contracts

`front_month()`

Selects the front month contract

`back_months()`

Selects the non-front month contracts

`back_month()`

Selects the back month contracts

`farthest_expiration()`

Selects the contracts with the farthest expiration date

`expiration(min_expiry: timedelta, max_expiry: timedelta)`

Selects contracts that expire within a range of dates relative to the current day

`expiration(min_expiry_days: int, max_expiry_days: int)`

Selects contracts that expire within a range of dates relative to the current day

`expiration(expiries: list[datetime])`

Selects the contracts that expire on any of the given dates. The time of day is ignored

`expiring_after(date: datetime)`

Selects the contracts that expire after the given date. The date itself is excluded and the time of day is ignored

`expiring_before(date: datetime)`

Selects the contracts that expire before the given date. The date itself is excluded and the time of day is ignored

`zero_dte()`

Selects the contracts that expire today

`expiration_cycle(months: list[int])`

Selects the contracts that expire in any of the given months of the year. The `FutureExpirationCycles` class defines the common cycles. For example, `FutureExpirationCycles.MARCH` is March, June, September, and December

`contract_months(months: list[int])`

Selects the contracts whose contract month, the month the contract is named after, is any of the given months of the year. Some products, like crude oil, expire the month before their contract month, so this filter and `expiration_cycle` can select different contracts

`oi(min: int, max: int)`
`open_interest(min: int, max: int)`

Selects the contracts with open interest in the given range

`volume(min: int, max: int)`

Selects the contracts with volume in the given range

`contracts(contracts: list[Symbol])`

Selects a list of contracts

`contracts(contractSelector: Callable[[list[Symbol]], list[Symbol]])`

Selects contracts that a selector function selects

The contract filter runs at the first time step of each day.

To move the Future chain Symbol selector and the contract selection function outside of the algorithm class, create a universe selection model that inherits the FundamentalUniverseSelectionModel class and override its Select method.

```python
# In the initialize method, define the universe settings and add data.
self.universe_settings.asynchronous = True
self.add_universe_selection(FrontMonthFutureUniverseSelectionModel())

# Outside of the algorithm class, define the universe selection model.
class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
    def __init__(self) -> None:
        # Refresh the universe daily.
        super().__init__(timedelta(1), self.select_future_chain_symbols)

    def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
        # Add E-mini S&P 500 and Gold Futures to the universe.
        return [
            Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME),
            Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
        ]

    def filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
        # Select the front month contracts.
        return filter.front_month()
```

Some of the preceding filter methods only set an internal enumeration in the `FutureFilterUniverse` that it uses later on in the filter process. This subset of filter methods don't immediately reduce the number of contract `Symbol` objects in the `FutureFilterUniverse`.

The `add_universe_selection` method doesn't return a `Future` object like the [add_future](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#11-Create-Universes) method. The `Future` object contains `Symbol` and `mapped` properties, which reference the [continuous contract](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts) and the currently selected contract in the continuous contract series, respectively. To get the `Future` object, define the `on_securities_changed` method in your algorithm class or framework models and check the result of the `is_canonical` method.

```python
# Save the Future object if the security added to the universe is the canonical asset.
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
    for security in changes.added_securities:
        if security.symbol.is_canonical():
            self.future = security
```

For more information about this model, see the [class reference](https://www.lean.io/docs/v2/lean-engine/class-reference/py/QuantConnect/Algorithm/Framework/Selection/FutureUniverseSelectionModel/) and [implementation](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Framework/Selection/FutureUniverseSelectionModel.py).

## Open Interest Future Universe Selection

The `OpenInterestFutureUniverseSelectionModel` is an extension of the `FutureUniverseSelectionModel` that selects the contract with the greatest open interest on a daily basis.

```python
# Enable asynchronous universe settings for faster performance.
self.universe_settings.asynchronous = True
# Add an OpenInterestFutureUniverseSelectionModel for E-mini S&P 500 Futures, incorporating contracts with high
# open interest into the trading universe.
self.add_universe_selection(
    OpenInterestFutureUniverseSelectionModel(
        self,
        lambda utc_time: [Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME)]
    )
)
```

The following table describes the arguments the model accepts:

| Argument | Data Type | Description | Default Value |
| --- | --- | --- | --- |
| `algorithm` | `IAlgorithm` | Algorithm |  |
| `future_chain_symbol_selector` | `Callable[[datetime], List[Symbol]]` | A function that selects the Future symbols for a given Coordinated Universal Time (UTC). To view the supported assets in the US Futures dataset, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-futures.md#09-Supported-Assets). |  |
| `chain_contracts_lookup_limit` | `int/None` | Limit on how many contracts to query for open interest | 6 |
| `results_limit` | `int/None` | Limit on how many contracts will be part of the universe | 1 |

The following example shows how to define the Future chain Symbol selector as an isolated method:

```python
# In the Initialize method, define the universe settings and add a universe.
def initialize(self) -> None:
    self.universe_settings.asynchronous = True
    self.add_universe_selection(
        OpenInterestFutureUniverseSelectionModel(self, self.select_future_chain_symbols)
    )

# Define the selection function, which returns Symbol objects.
def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
    return [
        Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME),
        Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)
    ]
```

To move the Future chain Symbol selector outside of the algorithm class, create a universe selection model that inherits the `OpenInterestFutureUniverseSelectionModel` class.

```python
# In the Initialize method, define the universe settings and add a universe.
self.universe_settings.asynchronous = True
self.add_universe_selection(GoldOpenInterestFutureUniverseSelectionModel(self))

# Outside of the algorithm class, define the universe selection model.
class GoldOpenInterestFutureUniverseSelectionModel(OpenInterestFutureUniverseSelectionModel):
    def __init__(self, algorithm: QCAlgorithm, chain_contracts_lookup_limit: int=6, results_limit: int=1):
        super().__init__(algorithm, self.select_future_chain_symbols, chain_contracts_lookup_limit, results_limit)

    def select_future_chain_symbols(self, utcTime: datetime) -> List[Symbol]:
        return [Symbol.create(Futures.Metals.GOLD, SecurityType.FUTURE, Market.COMEX)]
```

The `add_universe_selection` method doesn't return a `Future` object like the [add_future](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#11-Create-Universes) method. The `Future` object contains `Symbol` and `mapped` properties, which reference the [continuous contract](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts) and the currently selected contract in the continuous contract series, respectively. To get the `Future` object, define the `on_securities_changed` method in your algorithm class or framework models and check the result of the `is_canonical` method.

```python
# Save the Future object if the security added to the universe is the canonical asset.
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
    for security in changes.added_securities:
        if security.symbol.is_canonical():
            self.future = security
```

For more information about this model, see the [class reference](https://www.lean.io/docs/v2/lean-engine/class-reference/py/QuantConnect/Algorithm/Framework/Selection/OpenInterestFutureUniverseSelectionModel/) and [implementation](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Framework/Selection/OpenInterestFutureUniverseSelectionModel.cs).

## Examples

The following examples demonstrate some common practices for implementing a Futures universe selection model.

### Example 1: Front Month Contracts

The following algorithm selects a list of Futures to buy and hold equally. To ensure liquidity and efficiency, we will select only their front-month contracts. We can do so in the algorithm framework through a child class inheriting the `FutureUniverseSelectionModel` while providing the list of Futures and overriding the `filter` method to select the front month contracts.

```python
class FrameworkFutureUniverseSelectionAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(100000)

        # It is usual to trade Futures during extended market hours.
        self.universe_settings.extended_market_hours = True
        # Add a universe with custom selection rules for filtering.
        self.add_universe_selection(FrontMonthFutureUniverseSelectionModel(7))

        # Sent insights on buying and holding the selected securities.
        self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(7)))
        # Evenly dissipate the capital risk among selected securities.
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())

class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
    '''Creates futures chain universes that select the front month contract and run a user-defined
    futureChainSymbolSelector every day to enable choosing different futures chains'''
    def __init__(self, rebalance_period: int = 7) -> None:
        super().__init__(timedelta(rebalance_period), self.select_future_chain_symbols)

    def filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
        # Defines the futures chain universe filter to select only the front-month contracts at market open.
        return filter.front_month()

    def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
        return [
            Symbol.create(Futures.Indices.VIX, SecurityType.FUTURE, Market.CFE),
            Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME),
            Symbol.create(Futures.Indices.NASDAQ_100_E_MINI, SecurityType.FUTURE, Market.CME),
            Symbol.create(Futures.Indices.DOW_30_E_MINI, SecurityType.FUTURE, Market.CBOT),
            Symbol.create(Futures.Energy.GASOLINE, SecurityType.FUTURE, Market.NYMEX),
            Symbol.create(Futures.Energy.HEATING_OIL, SecurityType.FUTURE, Market.NYMEX),
            Symbol.create(Futures.Energy.NATURAL_GAS, SecurityType.FUTURE, Market.NYMEX),
            Symbol.create(Futures.Grains.CORN, SecurityType.FUTURE, Market.CBOT),
            Symbol.create(Futures.Grains.OATS, SecurityType.FUTURE, Market.CBOT),
            Symbol.create(Futures.Grains.SOYBEANS, SecurityType.FUTURE, Market.CBOT),
            Symbol.create(Futures.Grains.WHEAT, SecurityType.FUTURE, Market.CBOT),
        ]
```

### Example 2: Seasonal Contracts

Some Futures exhibit a seasonality effect, i.e., a yearly cycle in its price fluctuation. Studies show that the Natural Gas contract has a yearly cycle of maximizing its price in early December and minimizing it in early April. It might be due to the high demand for natural gas during winter warming. The following algorithm will hold Natural Gas contracts from summer to winter with a similar universe selection model in Example 1, but using a custom selection function with a time argument to select the contract.

```python
class FrameworkFutureUniverseSelectionAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(100000)

        # It is usual to trade Futures during extended market hours.
        self.universe_settings.extended_market_hours = True
        # We hold the Future and will not frequently trade it; using Daily resolution is sufficient for computational efficiency.
        self.universe_settings.resolution = Resolution.DAILY
        # Add a universe with custom selection rules for filtering.
        # Rescan every week to ensure we are on our plan.
        self.add_universe_selection(FrontMonthFutureUniverseSelectionModel(7))

        # Sent insights on buying and holding the selected securities.
        self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(7)))
        # Place orders for a single contract to control risk exposure and avoid over-leveraging.
        self.set_portfolio_construction(SingleSharePortfolioConstructionModel())

class FrontMonthFutureUniverseSelectionModel(FutureUniverseSelectionModel):
    '''Creates futures chain universes that select the front month contract and run a user-defined
     futureChainSymbolSelector every day to enable choosing different futures chains'''
    def __init__(self, rebalance_period: int = 7) -> None:
        super().__init__(timedelta(rebalance_period), self.select_future_chain_symbols)

    def filter(self, filter: FutureFilterUniverse) -> FutureFilterUniverse:
        # Defines the futures chain universe filter to select only the front-month contracts.
        return filter.front_month()

    def select_future_chain_symbols(self, utc_time: datetime) -> List[Symbol]:
        # We hold Natural Gas from summer to winter since it is in an upward cycle.
        if 4 <= utc_time.month <= 11:
            return [ Symbol.create(Futures.Energy.NATURAL_GAS, SecurityType.FUTURE, Market.NYMEX) ]
        # We do not hold any contracts during the time of the downward cycle.
        return []

class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
    def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
        targets = []
        for insight in insights:
            if algorithm.securities[insight.symbol].is_tradable:
                # Use integer target to create a portfolio target to trade a single contract
                targets.append(PortfolioTarget(insight.symbol, insight.direction))
        return targets
```
