---
title: "Futures"
description: "A Futures universe lets you select a basket of contracts for a single Future. LEAN models Future subscriptions as a universe of Future contracts."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/12%20Universes/06%20Futures
modified: 2026-10-31
index: https://www.quantconnect.com/llms.txt
---

# Futures

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

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

## Introduction

A Futures universe lets you select a basket of contracts for a single Future. LEAN models Future subscriptions as a universe of Future contracts. A Future universe is similar to an [Option universe](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/equity-options.md), except Future contracts don't have a strike price, so the universe filter primarily focuses on the contract expiration date.

LEAN subscribes to every contract that passes your filter, so you don't need to call the `add_future_contract` method for them. To trade a specific contract, such as when you manage the rollover with your own rule, select it from the [FuturesChain](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/handling-data.md#05-Futures-Chains) in the `Slice` and place your orders with its `Symbol`. Set the filter wide enough to include the next contract on the date you plan to roll. For example, a week before the front-month contract expires, the next quarterly contract is about 98 days away, so a filter of 0 to 92 days excludes it.

## Create Universes

To add a universe of Future contracts, in the `initialize` method, call the `add_future` method. This method returns an `Future` object, which contains the continuous contract `symbol`. The continuous contract `symbol` is the key to access the contracts in the [FutureChain](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/handling-data.md#05-Futures-Chains) that LEAN passes to the `on_data` method. The continuous contract `mapped` property references the current contract in the continuous contract series. When you create the Future subscription, save a reference to the `Future` object so you can use it later in your algorithm.

```python
class BasicFutureAlgorithm(QCAlgorithm):
    def initialize(self):
        self.universe_settings.asynchronous = True
        self._future = self.add_future(Futures.Currencies.BTC,
            extended_market_hours=True,
            data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
            data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
            contract_depth_offset=0)
        self._future.set_filter(0,62)

    def on_data(self, data):
        if self.portfolio.invested:
            return
        continuous_trade_bar = data.bars.get(self._future.symbol)
        mapped_trade_bar = data.bars.get(self._future.mapped)
        self.market_order(self._future.mapped, 1)

    # Track events when security changes its ticker allowing algorithm to adapt to these changes.
    def on_symbol_changed_events(self, symbol_changed_events):
        for symbol, changed_event in  symbol_changed_events.items():
            old_symbol = changed_event.old_symbol
            new_symbol = changed_event.new_symbol
            quantity = self.portfolio[old_symbol].quantity

            # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
            tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}"
            self.liquidate(old_symbol, tag=tag)
            if quantity: self.market_order(new_symbol, quantity, tag=tag)
```

The following table describes the `add_future` method arguments:

### Argument: `ticker`

The Future ticker. 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).

Data Type: `str`

### Argument: `resolution`

The resolution of the market data. To view the supported resolutions, see [Resolutions](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/requesting-data/individual-contracts.md#03-Resolutions). If you don't provide a value, it uses `Resolution.MINUTE` by default.

Data Type: `Resolution/NoneType`

### Argument: `market`

The Futures market. To view the supported markets in the US Futures dataset, see [Supported Markets](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/requesting-data/individual-contracts.md#04-Supported-Markets). If you don't provide a value, it uses the default Future market of your [brokerage model](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/brokerages/key-concepts.md).

Data Type: `str`

### Argument: `fill_forward`

If true, the current slice contains the last available data even if there is no data at the current time.

Data Type: `bool`

### Argument: `leverage`

The leverage for this Future.

Data Type: `float`

### Argument: `extended_market_hours`

If true, use data from the pre and post market sessions

Data Type: `bool`

### Argument: `data_mapping_mode`

The contract mapping mode to use for the continuous future contract

Data Type: `DataMappingMode/NoneType`

### Argument: `data_normalization_mode`

The price scaling mode to use for the continuous future contract

Data Type: `DataNormalizationMode/NoneType`

### Argument: `contract_depth_offset`

The continuous future contract desired offset from the current front month. For example, 0 is the front month, 1 is the back month contract.

Data Type: `int`

If you don't set any of these parameters, LEAN uses the `self.universe_settings` values. See [Set Universe Settings](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md#06-Set-Universe-Settings) for more information.

## Continous Contracts

By default, LEAN only subscribes to the continuous Future contract. A continuous Future contract represents a series of separate contracts stitched together to form a continuous price. If you need a lot of historical data to warm up an indicator, apply the indicator to the continuous contract price series. The `Future` object has a `symbol` property and a `mapped` property. The price of the `symbol` property is the adjusted price of the continuous contract. The price of the `mapped` property is the raw price of the currently selected contract in the continuous contract series.

```python
# Get the adjusted price of the continuous contract.
adjusted_price = self.securities[self._future.symbol].price

# Get the raw price of the currently selected contract in the continuous contract series.
raw_price = self.securities[self._future.mapped].price
```

The continuous Futures contract isn't a [tradable security](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/key-concepts.md#05-Tradable-Status). You must place orders for a specific Futures contract. To access the currently selected contract in the continuous contract series, use the `mapped` property of the `Future` object.

```python
# Place a market order for the currently selected contract in the continuous contract series.
self.market_order(self._future.mapped, 1)
```

To configure how LEAN identifies the current Future contract in the continuous series and how it forms the adjusted price between each contract, provide `data_mapping_mode`, `data_normalization_mode`, and `contract_depth_offset` arguments to the `add_future` method. The `Future` object that the `add_future` method returns contains a `mapped` property that references the current contract in the continuous contract series. As the contracts roll over, the `mapped` property references the next contract in the series and you receive a `SymbolChangedEvent` object in the `on_data` method. The `SymbolChangedEvent` references the old contract `Symbol` and the new contract `Symbol`. You can use `SymbolChangedEvents` to roll over contracts.

```python
class BasicFutureAlgorithm(QCAlgorithm):
    # Track when the continuous contract switches from one contract to the next.
    def on_symbol_changed_events(self, symbol_changed_events):
        for symbol, changed_event in  symbol_changed_events.items():
            old_symbol = changed_event.old_symbol
            new_symbol = changed_event.new_symbol
            quantity = self.portfolio[old_symbol].quantity

            # Rolling over: To liquidate the old mapped contract and switch to the new mapped contract.
            tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}"
            self.liquidate(old_symbol, tag=tag)
            if quantity: self.market_order(new_symbol, quantity, tag=tag)
```

In backtesting, the `SymbolChangedEvent` occurs at midnight Eastern Time (ET). In live trading, the live data for continuous contract mapping arrives at 6/7 AM ET, so that's when it occurs.

### Data Normalization Modes

The `data_normalization_mode` argument defines how the price series of two contracts are stitched together when the contract rollovers occur. The following `DataNormalizatoinMode` enumeration members are available for continuous contracts:

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

Fields: `ForwardPanamaCanal`, `BackwardsPanamaCanal`, `BackwardsRatio`, `FORWARD_PANAMA_CANAL`, `BACKWARDS_PANAMA_CANAL`, `BACKWARDS_RATIO`

We use the entire Futures history to adjust historical prices. This process ensures you get the same adjusted prices, regardless of the backtest end date.

### Data Mapping Modes

The `data_mapping_mode` argument defines when contract rollovers occur. The `DataMappingMode` enumeration has the following members:

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

`Futures.Indices.VIX` (VX) doesn't support continous contract rolling with `DataMappingMode.OPEN_INTEREST` and `DataMappingMode.OPEN_INTEREST_ANNUAL`.

### Contract Depth Offsets

The `contract_depth_offset` argument defines which contract to use. 0 is the front month contract, 1 is the following back month contract, and 2 is the second back month contract.

## Filter Contracts

By default, LEAN doesn't add any contracts to the [FuturesChain](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/handling-data.md#05-Futures-Chains) it passes to the `on_data` method.

To set a contract filter, in the `initialize` method, call the `set_filter` method of the `Future` object. The following table describes the available filter techniques:

`set_filter(minExpiry: int, maxExpiry: int)`

Selects the contracts that expire within the range you set. This filter runs [asynchronously](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/settings.md#09-Asynchronous-Selection) by default.

```python
# Select the contracts that expire within 182 days.
self._future.set_filter(0, 182)

# Select the front month contract.
self._future.set_filter(lambda future_filter_universe: future_filter_universe.front_month())
```

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 preceding methods return an `FutureFilterUniverse`, so you can chain the methods together.

```python
# Select the front month standard contracts
self._future.set_filter(lambda future_filter_universe: future_filter_universe.standards_only().front_month())
```

```python
# Select the quarterly contracts with at least 10,000 contracts of open interest
self._future.set_filter(lambda future_filter_universe: future_filter_universe.contract_months(FutureExpirationCycles.MARCH).open_interest(10000, sys.maxsize))
```

You can also define an isolated filter method.

```python
# In Initialize
self._future.set_filter(self._contract_selector)

def _contract_selector(self,
    future_filter_universe: Callable[[FutureFilterUniverse], FutureFilterUniverse]) -> FutureFilterUniverse:
    return future_filter_universe.standards_only().front_month()
```

The same filter methods are available on [`FuturesChain`](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/futures/handling-data.md#05-Futures-Chains) objects, so you can reuse them to narrow down a chain you receive during the algorithm.

## Navigate Futures Chains

`FuturesChain` objects represent an entire chain of contracts for a single underlying Future. They have the following properties:

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

To get the `FuturesChain`, index the `futures_chains` property of the `Slice` with the continuous contract `Symbol`.

```python
def on_data(self, slice: Slice) -> None:
    chain = slice.futures_chains.get(self._symbol)
    if chain:
        # Example: Select the contract with the greatest open interest
        contract = sorted(chain, key=lambda contract: contract.open_interest, reverse=True)[0]
```

You can also loop through the `futures_chains` property to get each `FuturesChain`.

```python
def on_data(self, slice: Slice) -> None:
    for continuous_contract_symbol, chain in slice.futures_chains.items():
        pass
```

### Filter Chains

`FuturesChain` objects provide the same filter methods as [Futures universe selection](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#13-Filter-Contracts), with the same names and the same behavior. Each method returns a new `FuturesChain` and leaves the source chain unchanged, so you can chain the calls together.

```python
# Select the front contract that expires at least 90 days out.
contract = next(iter(chain.expiring_after(self.time + timedelta(days=90)).front_month()), None)

# Select the quarterly contracts.
quarterlies = chain.contract_months(FutureExpirationCycles.MARCH)
```

To filter the chain with your own predicate, call the `where` method.

```python
liquid_contracts = chain.open_interest(100000, sys.maxsize).where(lambda contract: contract.volume > 0)
```

The `standards_only` and `weeklys_only` methods of a chain apply to the contracts the chain already holds, so you can combine them with the expiration filters in any order. In universe selection, these two filters always run last.

## Historical Data

To get historical Future universe data, call the `history` method. This method returns the all the available contracts for each trading day, not the subset of contracts that pass your universe filter. The return type depends on how you call the method.

```python
class FutureHistoryAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        future = self.add_future(Futures.Indices.SP_500_E_MINI)
        # DataFrame example:
        history_df = self.history(FutureUniverse, future.symbol, 5, flatten=True)
        # Series example:
        history_series = self.history(FutureUniverse, future.symbol, 5, flatten=False)
        # FutureUniverse objects example:
        history = self.history[FutureUniverse](future.symbol, 5)
        for universe in history:
            end_time = universe.end_time
            for contract in universe:
                symbol = contract.symbol
                expiry = contract.id.date
                price = contract.close
                oi = contract.open_interest
```

The method represents each contract with a `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*

## Selection Frequency

By default, Futures universes run at the first time step of each day to select their contracts.

## Examples

The following examples demonstrate some common Futures universes.

### Example 1: Contracts Expiring On Quarter End

To reduce the need for rolling over, you can filter Future contracts that expire only on quarter ends to save transaction costs. The following example trades a simple EMA cross strategy on SP500 EMini Future contracts that expire on quarter ends.

```python
class QuarterlyFuturesAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(10000000)

        # Request ES Future data for trading.
        self.future = self.add_future(
            Futures.Indices.SP_500_E_MINI,
            extended_market_hours=True,
            data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
            data_mapping_mode=DataMappingMode.OPEN_INTEREST,
        )
        # We only filter the ones expiring on quarter ends to reduce the transaction cost needed for rolling over contracts.
        self.future.set_filter(lambda future_filter_universe: future_filter_universe.expiration_cycle([3, 6, 9, 12]))

        # Create an EMA indicator to track trends for trade signal generation.
        self._ema = self.ema(self.future.symbol, 20, Resolution.DAILY)
        # Warm up the indicator for immediate readiness.
        self.warm_up_indicator(self.future.symbol, self._ema, Resolution.DAILY)

        # A variable to control the algorithm trading in daily frequency only, since the indicator signal is by daily.
        self._day = -1

    def on_data(self, slice: Slice) -> None:
        # Get the chain to trade from the filtered contracts.
        chain = slice.future_chains.get(self.future.symbol)
        if self._day != slice.time.day and chain:
            # Select the contract with the nearest expiry.
            contract = min(chain, key=lambda x: x.expiry)

            # Trade an EMA cross strategy to follow the trend.
            quantity = self.portfolio[self.future.symbol].quantity
            if contract.last_price > self._ema.current.value and quantity <= 0:
                self.market_order(contract.symbol, 1-quantity)
            elif contract.last_price < self._ema.current.value and quantity >= 0:
                self.market_order(contract.symbol, -1-quantity)

            self._day = slice.time.day
```

### Example 2: Contracts Expiring Within One Week

The trading volume of Futures reaches its maximum during the last week of the trading period. The following algorithm selects contracts that expire within a week:

```python
class WeeklyFuturesAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Add ES Futures for trading. The continuous contract data is
        # only used for indicator values.
        self._future = self.add_future(
            Futures.Indices.SP_500_E_MINI,
            extended_market_hours=True,
            data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
            data_mapping_mode=DataMappingMode.OPEN_INTEREST
        )
        # Select the contract expiring within a week since they have
        # the highest liquidity.
        self._future.set_filter(lambda universe: universe.expiration(0, 7))
        # Create a Bollinger Band indicator to identify extreme prices
        # for trade signal generation.
        self._bb = self.bb(self._future.symbol, 60, 2)
        # Warm up the indicator for so we can trade right away.
        self.warm_up_indicator(self._future.symbol, self._bb)

    def on_data(self, slice: Slice) -> None:
        # Get the current Futures chain, if there is one.
        chain = slice.future_chains.get(self._future.symbol)
        if not chain:
            return
        # Select the contract with the nearest expiry.
        contract = min(chain, key=lambda x: x.expiry)
        # Trade a mean-reversal strategy based on Bollinger Band signal.
        holding = self.portfolio[contract.symbol]
        price = contract.last_price
        # Case 1: Short
        if not holding.is_short and price > self._bb.upper_band.current.value:
            target_quantity = -1
        # Case 2: Long
        elif not holding.is_long and price < self._bb.lower_band.current.value:
            target_quantity = 1
        # Case 3: Exit
        elif ((holding.is_short and price < self._bb.middle_band.current.value) or
            (holding.is_long and price > self._bb.middle_band.current.value)):
            target_quantity = 0
        # Case 4: Hold
        else:
            return
        self.market_order(contract.symbol, target_quantity - holding.quantity)
```

### Other Examples

For more examples, see the following algorithms:

**Demonstration Algorithms**

- [EmaCrossFuturesFrontMonthAlgorithm.py](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/EmaCrossFuturesFrontMonthAlgorithm.py) (Python)
