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

# Index Options

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

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

## Introduction

An Index Option universe lets you select a basket of Option contracts on an Index.

## Create Universes

To add a universe of Index Option contracts, in the `initialize` method, call the `add_index_option` method. This method returns an `Option` object, which contains the canonical `symbol`. You can't trade with the canonical Option `symbol`, but save a reference to it so you can easily access the Option contracts in the [OptionChain](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/handling-data.md#04-Option-Chains) that LEAN passes to the `on_data` method. The method to create the universe depends on if the Index Options you want require a target ticker.

### Create Non-Standard Universes

Non-standard Option contracts are popular among Option traders. To create a universe of non-standard Index Options like weekly VIX contracts, pass the index Symbol and target Option ticker to the `add_index_option` method.

```python
class WeeklyIndexOptionAlgorithm(QCAlgorithm):

    def initialize(self):
        underlying = self.add_index("VIX").symbol
        option = self.add_index_option(underlying, "VIXW")
        option.set_filter(lambda universe: universe.expiration(0, 7).delta(0.35, 0.75))
        self._symbol = option.symbol

    def on_data(self, data):
        chain = data.option_chains.get(self._symbol)
        if chain:
            contract = sorted(chain, key=lambda x: (x.expiry, x.greeks.delta))[0]
```

The following table describes the `add_index_option` method arguments for non-standard universes:

| Argument | Data Type | Description |
| --- | --- | --- |
| `underlying` | `Symbol` | The underlying Index `Symbol`. To view the supported indices, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-index-options.md#09-Supported-Assets). |
| `target_option` | `str` | The target Option ticker. To view the supported target Options, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-index-options.md#09-Supported-Assets). |
| `resolution` | `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/index-options/requesting-data/individual-contracts.md#03-Resolutions). The Index resolution must be less than or equal to the Index Option resolution. For example, if you set the Index resolution to minute, then you must set the Index Option resolution to minute, hour, or daily. |
| `market` | `str` | The Index Option market. |
| `fill_forward` | `bool` | If true, the current slice contains the last available data even if there is no data at the current time. |

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.

If you add an Option universe for an underlying Index that you don't have a subscription for, LEAN automatically subscribes to the underlying Index.

### Create Standard Universes

To create a universe of Index Options based on an index like VIX, SPX, or NDX, pass the index ticker to the `add_index_option` method.

```python
option = self.add_index_option("SPX")
option.set_filter(lambda universe: universe.expiration(0, 60).delta(0.35, 0.75))
self._symbol = option.symbol
```

The following table describes the `add_index_option` method arguments for standard universes:

| Argument | Data Type | Description |
| --- | --- | --- |
| `ticker` | `str` | The underlying Index ticker. To view the supported indices, see [Supported Assets](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-index-options.md#09-Supported-Assets). |
| `resolution` | `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/index-options/requesting-data/individual-contracts.md#03-Resolutions). |
| `market` | `str` | The Index Option market. |
| `fill_forward` | `bool` | If true, the current slice contains the last available data even if there is no data at the current time. |

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.

If you add an Option universe for an underlying Index that you don't have a subscription for, LEAN automatically subscribes to the underlying Index and sets its [fill forward](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index/requesting-data.md#05-Fill-Forward) property to match that of the Index Option universe.

## Filter by Investment Strategy

[Options trading strategies](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies.md) consist of simultaneously buying or selling one or more Option contracts on the same underlying Index, but with different features.

```python
# Example 1: Select a Straddle
option.set_filter(lambda option_filter_universe: option_filter_universe.straddle(30))

# Example 2: Select the contracts (including weeklys) that expire in the next 30 days that form an Iron Condor
option.set_filter(lambda option_filter_universe: option_filter_universe.strikes(-20, 20).expiration(0, 30).iron_condor(30, 5, 10))

# Example 3: Select the 0DTE contracts that form an Strangle
option.set_filter(lambda option_filter_universe: option_filter_universe.expiration(0, 0).strangle(30, 5, -10))
```

The following table describes the filter methods of the `OptionFilterUniverse` class that select contracts for Option strategies:

`naked_call(min_days_till_expiry: int, strike_from_atm: float)`

Selects a call contract to form [Naked Call](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/naked-call.md), [Covered Call](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/covered-call.md), or [Protective Call](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/protective-call.md) Option strategies.

`naked_put(min_days_till_expiry: int, strike_from_atm: float)`

Selects a put contract to form [Naked Put](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/naked-put.md), [Covered Put](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/covered-put.md), or [Protective Put](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/protective-put.md) Option strategies.

`call_spread(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float)`

Selects two call contracts to form [Bull Call Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bull-call-spread.md) or [Bear Call Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bear-call-spread.md) Option strategies.

`put_spread(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float)`

Selects two put contracts to form [Bull Put Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bull-put-spread.md) or [Bear Put Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bear-put-spread.md) Option strategies.

`call_calendar_spread(strike_from_atm: int, min_near_days_till_expiry: int, min_far_days_till_expiry: int)`

Selects two call contracts to form [Long Call Calendar Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-call-calendar-spread.md) or [Short Call Calendar Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-call-calendar-spread.md) Option strategies.

`put_calendar_spread(strike_from_atm: int, min_near_days_till_expiry: int, min_far_days_till_expiry: int)`

Selects two put contracts to form [Long Put Calendar Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-put-calendar-spread.md) or [Short Put Calendar Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-put-calendar-spread.md) Option strategies.

`strangle(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float)`

Selects two contracts to form [Long Strangle](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-strangle.md) or [Short Strangle](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-strangle.md) Option strategies.

`straddle(min_days_till_expiry: int)`

Selects two contracts to form [Long Straddle](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-straddle.md) or [Short Straddle](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-straddle.md) Option strategies.

`protective_collar(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float)`

Selects two contracts to form [Protective Collar](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/protective-collar.md) Option strategies.

`conversion(min_days_till_expiry: int, strike_from_atm: float)`

Selects two contracts to form [Conversion](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/conversion.md) or [Reverse Conversion](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/reverse-conversion.md) Option strategies.

`call_butterfly(min_days_till_expiry: int, strike_spread: float)`

Selects three contracts to form [Long Call Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-call-butterfly.md) or [Short Call Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-call-butterfly.md) Option strategies.

`put_butterfly(min_days_till_expiry: int, strike_spread: float)`

Selects three contracts to form [Long Put Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-put-butterfly.md) or [Short Put Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-put-butterfly.md) Option strategies.

`iron_butterfly(min_days_till_expiry: int, strike_spread: float)`

Selects four contracts to form [Long Iron Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-iron-butterfly.md) or [Short Iron Butterfly](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-iron-butterfly.md) Option strategies.

`iron_condor(min_days_till_expiry: int, near_strike_spread: float, far_strike_spread: float)`

Selects four contracts to form [Long Iron Condor](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-iron-condor.md) or [Short Iron Condor](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-iron-condor.md) Option strategies.

`box_spread(min_days_till_expiry: int, strike_spread: float)`

Selects four contracts to form [Box Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-box-spread.md) or [Short Box Spread](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-box-spread.md) Option strategies.

`jelly_roll(strike_from_atm: float, min_near_days_till_expiry: int, min_far_days_till_expiry: int)`

Selects four contracts to form [Jelly Roll](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/long-jelly-roll.md) or [Short Jelly Roll](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/short-jelly-roll.md) Option strategies.

`call_ladder(min_days_till_expiry: int, higher_strike_from_atm: float, middle_strike_from_atm: float, lower_strike_from_atm: float)`

Selects four contracts to form [Bear Call Ladder](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bear-call-ladder.md) or [Bull Call Ladder](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bull-call-ladder.md) Option strategies.

`put_ladder(min_days_till_expiry: int, higher_strike_from_atm: float, middle_strike_from_atm: float, lower_strike_from_atm: float)`

Selects four contracts to form [Bear Put Ladder](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bear-put-ladder.md) or [Bull Put Ladder](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/option-strategies/bull-put-ladder.md) Option strategies.

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

## Filter by Implied Volatility and Greeks

Option price models compute the theoretical price of Option contracts, their implied volatility, and their Greek values. Theoretical prices can help you detect undervalued and overvalued contracts, implied volatility can provide you insight into the upcoming volatility of the underlying security, and Greek values can help you hedge your portfolio.

```python
# Example 1: Select the contracts with delta between 0.25 and 0.75
option.set_filter(lambda option_filter_universe: option_filter_universe.delta(0.25, 0.75))

# Example 2: Select the contracts (including weeklys) that expire in the next 90 days with implied volatility below 20%
option.set_filter(lambda option_filter_universe: option_filter_universe.iv(0, 20).expiration(0, 90))

# Example 3: Select the contracts (including weeklys) that expire in the next 30 days with implied volatility below 20% that forms an Iron Condor
option.set_filter(lambda option_filter_universe: option_filter_universe.iv(0, 20).expiration(0, 30).iron_condor(30, 5, 10))
```

The following table describes the filter methods of the `OptionFilterUniverse` class that select contract for a range of implied volatility, Greek values, and open interest:

`iv(min: float, max: float)`
`implied_volatility(min: float, max: float)`

Selects a contract with [implied volatility](https://www.quantconnect.com/learning/articles/introduction-to-options/historical-volatility-and-implied-volatility#implied-volatility) within the range you set.

`d(min: float, max: float)`
`delta(min: float, max: float)`

Selects a contract with [delta](https://www.quantconnect.com/learning/articles/introduction-to-options/the-greek-letters#delta) within the range you set.

`g(min: float, max: float)`
`gamma(min: float, max: float)`

Selects a contract with [gamma](https://www.quantconnect.com/learning/articles/introduction-to-options/the-greek-letters#gamma) within the range you set.

`r(min: float, max: float)`
`rho(min: float, max: float)`

Selects a contract with [rho](https://www.quantconnect.com/learning/articles/introduction-to-options/the-greek-letters#rho) within the range you set.

`v(min: float, max: float)`
`vega(min: float, max: float)`

Selects a contract with [vega](https://www.quantconnect.com/learning/articles/introduction-to-options/the-greek-letters#vega) within the range you set.

`t(min: float, max: float)`
`theta(min: float, max: float)`

Selects a contract with [theta](https://www.quantconnect.com/learning/articles/introduction-to-options/the-greek-letters#theta) within the range you set.

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

Selects a contract with open interest within the range you set.

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

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

```python
# Select the put contracts with the lowest strike price.
option.set_filter(self._contract_selector)

def _contract_selector(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
    return option_filter_universe \
        .delta(0.5, 1.5) \
        .gamma(0.0001, 0.0006) \
        .vega(0.01, 1.5) \
        .theta(-2.0, -0.5) \
        .rho(0.5, 3.0) \
        .implied_volatility(1, 3) \
        .open_interest(100,500)
```

## Filter by Other Contract Properties

To set a contract filter, in the `initialize` method, call the `set_filter` method of the `Option` object.

```python
# Select contracts that have a strike price within 1 strike level above and below the underlying price
option.set_filter(min_strike=-1, max_strike=1)

# Select contracts that expire within 30 days
option.set_filter(min_expiry=timedelta(days=0), maxExpiry=timedelta(days=30))

# Select contracts that have a strike price within 1 strike level and expire within 30 days
option.set_filter(min_strike=-1, max_strike=1, min_expiry=timedelta(days=0), maxExpiry=timedelta(days=30))

# Select call contracts
option.set_filter(lambda option_filter_universe: option_filter_universe.calls_only())
```

The following table describes the available filter techniques:

`set_filter(minStrike: int, maxStrike: int)`

Selects the contracts that have a strike price within a minimum and maximum strike level relative to the underlying price. For example, say the underlying price is $302 and there are strikes at every $5. If you set `m_strike` to -1 and `max_strike` to 1, LEAN selects the contracts that have a strike of $300 or $305. This filter runs [asynchronously](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/settings.md#09-Asynchronous-Selection) by default.

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

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.

`set_filter(minStrike: int, maxStrike: int, minExpiry: timedelta, maxExpiry: timedelta)`

Selects the contracts that expire and have a strike 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.

`set_filter(universeFunc: Callable[[OptionFilterUniverse], OptionFilterUniverse])`

Selects the contracts that a function selects.

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

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.

`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
# Example 1: Select the front month call contracts
option.set_filter(lambda option_filter_universe: option_filter_universe.calls_only().front_month())

# Example 2: Select the contracts (including weeklys) that expire in the next 90 days
option.set_filter(lambda option_filter_universe: option_filter_universe.strikes(-20, 20).expiration(0, 90))
```

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

## Default Filter

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

- Standard and weeklys
- 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 the first bar of every day. 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.

## Navigate Intraday Option Chains

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

To get the `OptionChain`, index the `option_chains` property of the `Slice` with the canonical `symbol`. After you get the `OptionChain`, you can sort and filter the Option contracts in the chain.

```python
def on_data(self, slice: Slice) -> None:
    # Try to get the OptionChain using the canonical symbol
    chain = slice.option_chains.get(self._symbol)
    if chain:
        # Example: Find 5 put contracts that are closest to at-the-money (ATM) and have the farthest expiration
        contracts = [x for x in chain if x.right == OptionRight.PUT]
        contracts = sorted(sorted(contracts, \
            key = lambda x: abs(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 loop through the `option_chains` property to get each `OptionChain`.

```python
def on_data(self, slice: Slice) -> None:
    # Iterate all received Canonical Symbol-OptionChain key-value pairs
    for canonical_symbol, chain in slice.option_chains.items():
        contracts = chain.contracts
```

### Filter Chains

`OptionChain` objects provide the same filter methods as [Option universe selection](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/index-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*

## Navigate Daily Option Chains

To get the daily, pre-calculated Greeks and implied volaility of all the currently tradable contracts, call the `option_chain` method. This method returns a `DataHistory[OptionUniverse]` object, which you can format into a DataFrame or iterate through. Each row in the DataFrame and each `OptionUniverse` object represents a single contract. The data this method returns contains information on all the currently tradable contracts, not just the contracts that pass your filter.

```python
# In the initialize method, create a Scheduled Event to get the Option
# chain and rebalance the portfolio.
self.schedule.on(
    self.date_rules.week_start(self._symbol),
    self.time_rules.after_market_open(self._symbol, 1),
    self._rebalance
  )

# Define the method.
def _rebalance(self):
    daily_option_chain = self.option_chain(self._symbol, flatten=True)

    # Get the DataFrame format.
    df = daily_option_chain.data_frame
    delta_by_symbol = df.delta

    # Get the OptionUniverse objects format.
    for option_universe in daily_option_chain:
        close = option_universe.close
        oi = option_universe.open_interest
        delta = option_universe.greeks.delta
```

The `option_chain` method was previously known as the `option_chain_provider.get_option_contract_list` method.

`OptionUniverse` objects 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*

## Greeks and Implied Volatility

There are several ways to get the implied volatility and Greeks of contracts.

The Greeks and IV values in the [filter function](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/requesting-data/universes.md#04-Filter-by-Implied-Volatility-and-Greeks) are the daily, pre-calculated values based on the end of the previous trading day.

```python
def initialize(self):
    option = self.add_index_option("SPX")
    option.set_filter(lambda universe: universe.delta(0.3, 0.7).expiration(0,7))
```

To calculate the values, we use [our implementation](https://www.quantconnect.com/research/16977/greeks-and-iv-implementation/p1) of the Black-Scholes pricing model, which accounts for the interest rate and dividend payments when applicable. For example, VIX doesn't have dividends. We use SPY for SPX and QQQ for NDX.

You can't customize the Greeks and IV values that the filter function receives. However, you can create [indicators](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/greeks-and-implied-volatility/indicators.md) to customize how the Greeks and IV are calculated for the contracts already in your universe.

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). If you set a price model, it sets the price model of the individual contracts in the universe.

```python
// Set price_model field to use the Binomial Cox-Ross-Rubinstein model to price the Options.
option.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).

## Historical Data

To get historical chains for an Index Option, call the `history[OptionUniverse]` method with the canonical Option `Symbol`. This method returns the entire Option chain for each trading day, not the subset of contracts that pass your universe filter.

```python
class OptionHistoryAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        option = self.add_index_option('SPX');
        # DataFrame example:
        history_df = self.history(option.symbol, 5, flatten=True)
        # OptionUniverse objects example:
        history = self.history[OptionUniverse](option.symbol, 5)
        for chain in history:
            end_time = chain.end_time
            filtered_contracts = [c for c in chain if c.greeks.delta > 0.3]
            for contract in filtered_contracts:
                symbol = contract.symbol
                expiry = contract.id.date
                strike = contract.id.strike_price
                price = contract.close
                iv = contract.implied_volatility
```

The Greeks and IV values that you get from a [history request](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-requests.md) of the Option universe are the daily, pre-calculated values based on the end of the previous trading day. To get the intraday values or to customize the Greeks and IV calculations, create some [Option indicators](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/greeks-and-implied-volatility/indicators.md).

The method represents each contract with an `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, Index Option universes run at the first time step of each day to select their contracts.

## Examples

The following examples demonstrate some common Index 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 Option contracts for the SPX Index that fall within 3 strikes of the underlying price.

```python
class ZeroDTEIndexOptionUniverseAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        index = self.add_index('SPX')
        index_option = self.add_index_option(index.symbol, 'SPXW')
        index_option.set_filter(lambda u: u.expiration(0, 0).strikes(-3, 3))
```

For trading full examples of Index Option Universe, please refer to the [Securities > Index Options > Requesting Data > Universes](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/requesting-data/universes.md#99-Examples) page.
