---
title: "Future Options"
description: "A Future Option universe lets you select a basket of Option contracts on the contracts in a Futures universe."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/universes/future-options
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/universes/future-options.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/12%20Universes/07%20Future%20Options
modified: 2026-10-30
index: https://www.quantconnect.com/llms.txt
---

# Future Options

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

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

## Introduction

A Future Option universe lets you select a basket of Option contracts on the contracts in a [Futures universe](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md).

## Create Universes

To add a universe of Future Option contracts, in the `initialize` method, [define a Future universe](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#11-Create-Universes) and then pass the canonical `symbol` to the `add_future_option` method.

```python
self.universe_settings.asynchronous = True
future = self.add_future(Futures.Metals.GOLD)
future.set_filter(0, 90)
self.add_future_option(future.symbol)
```

The following table describes the `add_future_option` method arguments:

| Argument | Data Type | Description |
| --- | --- | --- |
| `symbol` | `Symbol` | The continuous Future contract Symbol. To view the supported assets in the US Future Options dataset, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-future-options.md#08-Supported-Assets). |
| `option_filter` | `Callable[[OptionFilterUniverse], OptionFilterUniverse]` | A function that selects Future Option contracts |

The subscription characteristics such as resolution, market, and fill forward behavior are inherited from 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.

To override the default [pricing model](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/options-models/pricing.md) of the Option, [set a pricing model](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/options-models/pricing.md#03-Set-Models) in a security initializer.

```python
# In Initialize
seeder = SecuritySeeder.NULL
self.set_security_initializer(MySecurityInitializer(self.brokerage_model, seeder, self))

# Outside of the algorithm class
class MySecurityInitializer(BrokerageModelSecurityInitializer):

    def __init__(self, brokerage_model: IBrokerageModel, security_seeder: ISecuritySeeder, QCAlgorithm algorithm) -> None:
        super().__init__(brokerage_model, security_seeder)
        self._algorithm = algorithm;

    def initialize(self, security: Security) -> None:
        # First, call the superclass definition
        # This method sets the reality models of each security using the default reality models of the brokerage model
        super().initialize(security)

        # Next, set the price model
        if security.type == SecurityType.FUTURE_OPTION: # Option type
            security.price_model = OptionPriceModels.binomial_cox_ross_rubinstein()
```

To override the [initial guess of implied volatility](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/options-models/pricing.md#96-What-Is-Implied-Volatility3F), set and warm up the underlying [volatility model](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/options-models/volatility/key-concepts.md).

## Filter Contracts

By default, LEAN subscribes to the Option contracts that have the following characteristics:

- Standard type (weeklies and non-standard contracts are not available)
- Within 1 strike price of the underlying asset price
- Expire within 35 days

To adjust the universe of contracts, set a filter. The filter usually runs at every [time step](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md) in your algorithm. When the filter selects a contract that isn't currently in your universe, LEAN adds the new contract data to the next `Slice` that it passes to the `on_data` method.

To set a contract filter, in the `initialize` method, pass a filter function to the `add_future_option` method. The following table describes the available filter techniques:

```python
self.add_future_option(future.symbol, lambda option_filter_universe: option_filter_universe.strikes(-1, 1))
```

The following table describes the filter methods of the `OptionFilterUniverse` class:

`strikes(min_strike: int, max_strike: int)`

Selects contracts that are within `m_strike` strikes below the underlying price and `max_strike` strikes above the underlying price.

`calls_only()`

Selects call contracts.

`puts_only()`

Selects put contracts.

`standards_only()`

Selects standard contracts.

`weeklys_only()`

Selects weekly contracts. This filter doesn't currently work. To add this functionality to [our roadmap](https://www.quantconnect.com/docs/v2/lean-engine/getting-started.md#05-Roadmap), react to [this GitHub Issue](https://github.com/QuantConnect/Lean/issues/7570) with a thumbs up emoji.

`front_month()`

Selects the front month contract.

`back_months()`

Selects the non-front month contracts.

`back_month()`

Selects the back month contracts.

`expiration(min_expiryDays: int, max_expiryDays: int)`

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

`contracts(contracts: list[Symbol])`

Selects a list of contracts.

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

Selects contracts that a selector function selects.

The preceding methods return an `OptionFilterUniverse`, so you can chain the methods together.

```python
self.add_future_option(future.symbol, lambda option_filter_universe: option_filter_universe.strikes(-1, 1).calls_only())
```

To perform thorough filtering on the `OptionFilterUniverse`, define an isolated filter method.

```python
# In Initialize
self.add_future_option(future.symbol, self._contract_selector)

def _contract_selector(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
    symbols = option_filter_universe.puts_only()
    strike = min([symbol.id.strike_price for symbol in symbols])
    symbols = [symbol for symbol in symbols if symbol.id.strike_price == strike]
    return option_filter_universe.contracts(symbols)
```

Some of the preceding filter methods only set an internal enumeration in the `OptionFilterUniverse` 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 `OptionFilterUniverse`.

## Navigate Option Chains

`OptionChain` objects represent an entire chain of Option contracts for a single underlying security.

To get the `OptionChain`, loop through the `option_chains` property. After you get the `OptionChain`, you can sort and filter the Option contracts in the chain.

```python
def on_data(self, slice: Slice) -> None:
    for _, option_chain in slice.option_chains.items():
        # Example: Find 5 put contracts that are closest to at-the-money (ATM) and have the farthest expiration
        contracts = [x for x in option_chain if x.right == OptionRight.PUT]
        contracts = sorted(sorted(contracts, \
            key=lambda x: abs(option_chain.underlying.price - x.strike)), \
            key=lambda x: x.expiry, reverse=True)[:5]

        # Select the contract with the delta closest to -0.5
        contract = sorted(contracts, key=lambda x: abs(-0.5 - x.greeks.delta))[0]
```

You can also iterate through the `futures_chains` first.

```python
def on_data(self, slice: Slice) -> None:
    for continuous_future_symbol, futures_chain in slice.futures_chains.items():
        # Select a Future Contract and create its canonical FOP Symbol
        futures_contract = [contract for contract in futures_chain][0]
        canonical_fop_symbol = Symbol.create_canonical_option(futures_contract.symbol)
        fop_chain = slice.option_chains.get(canonical_fop_symbol)
        if fop_chain:
            for contract in fop_chain:
                pass
```

### Filter Chains

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

```python
# Select the call contracts that expire in 20-40 days and are within 3 strikes of the underlying price.
contracts = chain.calls_only().expiration(20, 40).strikes(-3, 3)
```

The contract property filters, the Greeks and implied volatility filters, and the [Option strategy](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies.md) filters are all available. The strategy filters select the legs of the strategy, or return an empty chain when no set of contracts matches the criteria.

```python
# Select the four legs of an Iron Condor that expires in at least 30 days.
legs = chain.iron_condor(30, 5, 10)
```

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

```python
liquid_contracts = chain.where(lambda contract: contract.open_interest > 100)
```

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.

### Select Contracts

To get a single contract from the chain, call the `select` method. It returns the contract that best matches the criteria you provide, or `None` when the chain holds no match.

```python
# Get the put contract at 85% of the underlying price, from the expiration closest to 30 days out.
contract = chain.select(OptionRight.PUT, target_dte=30, moneyness=-0.15)
```

These methods take a *target* number of days to expiration and return the closest expiration within the optional `min_dte` and `max_dte` window. The Option strategy filters instead take a *minimum* number of days to expiration and return the first expiration at or after it.

The following table describes the contract selection methods of the `OptionChain` class:

`select(right: OptionRight = None, target_dte: int = None, min_dte: int = None, max_dte: int = None, moneyness: float = 0)`

Selects the contract with the strike closest to `moneyness` as a signed fraction of the underlying price. For example, -0.15 targets 85% of the underlying price and 0 targets the at-the-money strike.

`pick(right: OptionRight = None, target_dte: int = None, min_dte: int = None, max_dte: int = None, moneyness: float = 0)`

A synonym of the `select` method.

`select_by_strike_distance(strike_from_atm: float, right: OptionRight = None, target_dte: int = None, min_dte: int = None, max_dte: int = None)`

Selects the contract with the strike closest to a signed distance from the underlying price, in price units. This is how the Option strategy filters express their strikes.

`select_by_delta(target_delta: float, right: OptionRight = None, target_dte: int = None, min_dte: int = None, max_dte: int = None)`

Selects the contract with the absolute delta closest to the absolute target, so a 30 delta put is 0.3 or -0.3. Contracts without Greeks are ignored.

`at_the_money(right: OptionRight = None)`

Selects the contract with the strike closest to the underlying price. Ties go to the lower strike, then to the nearest expiration.

`closest_expiry(target_dte: int = None, min_dte: int = None, max_dte: int = None)`

Returns the expiration date closest to the target number of days out, or `None` when no expiration falls in the window.

`at(expiry: datetime)`

Returns a new chain with the contracts of the given expiration date. The time of day is ignored.

The expiration methods compose with the chain filters, so you can narrow a single expiration down further.

```python
expiry = chain.closest_expiry(target_dte=45, min_dte=30, max_dte=60)
contracts = chain.at(expiry).puts_only().strikes(-2, 0)
```

`OptionChain` objects also expose read-only views of their contracts: `calls` and `puts`, sorted by expiration and then strike; `expiries`, the distinct expiration dates in ascending order; and `strike_prices`, the distinct strikes in ascending order.

`strike_prices` is a `StrikeList` object, which adds the `closest_to`, `first_above`, and `first_below` methods. Each one takes a reference price and returns `None` when no strike matches.

```python
strike = chain.strike_prices.first_above(chain.underlying.price)
```

### Properties

`OptionChain` objects have the following properties:

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

## Historical Data

To get historical Future Option universe data, call the `history` method with the canoncial Option `Symbol`. 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 FutureOptionsHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Select a Futures contract.
        future = self.add_future(Futures.Indices.SP_500_E_MINI)
        futures_contract = list(self.futures_chain(future.symbol))[0]
        # Create the canoncial Option Symbol for this Futures contract.
        canonical = Symbol.create_canonical_option(futures_contract.symbol)
        # Get the historical Option universe data for this Futures contract.
        # DataFrame example:
        history_df = self.history(OptionUniverse, canonical, 3, flatten=True)
        # Series example:
        history_series = self.history(OptionUniverse, canonical, 3, flatten=False)
        # OptionUniverse example:
        history = self.history[OptionUniverse](canonical, 3)
        for universe in history:
            end_time = universe.end_time
            for contract in universe:
                symbol = contract.symbol
                expiry = contract.id.date
                price = contract.close
```

The method represents each contract with a `OptionUniverse` object, which have the following properties:

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

## Selection Frequency

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

## Examples

The following examples demonstrate some common Future Option universes.

### Example 1: 0DTE Contracts

**0DTE Options** are Option contracts that expire on the same day you trade them. The following algorithm selects 0DTE Future Option contracts for the E-mini S&P 500 that fall within 3 strikes of the underlying price.

```python
class ZeroDTEFutureOptionUniverseAlgorithm(QCAlgorithm):

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

        future = self.add_future(Futures.Indices.SP_500_E_MINI)
        future.set_filter(0, 90)
        self.add_future_option(
            future.symbol,
            lambda u: u.expiration(0, 0).strikes(-3, 3)
        )
```

For full trading examples of Future Options, see [Examples](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/future-options/requesting-data/universes.md#99-Examples) .
