---
title: "US Index Options"
description: "US Index Options dataset from AlgoSeek."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-index-options
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek/us-index-options.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/14%20Datasets/03%20AlgoSeek/05%20US%20Index%20Options
modified: 2026-10-30
index: https://www.quantconnect.com/llms.txt
---

# US Index Options

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Datasets > [AlgoSeek](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/algoseek.md) > US Index Options

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

## Introduction

The US Index Options dataset by AlgoSeek provides Option data, including prices, strikes, expires, and open interest. The data covers European Option contracts for 3 US Indices: SPX, VIX, and NDX. It starts from January 2012 and is delivered on minute resolution. This dataset is created by monitoring the Options Price Reporting Authority (OPRA) data feed, which consolidates last sale and quotation information originating from the national securities exchanges that have been approved by the Securities and Exchange Commission.

The US Index Options dataset depends on the [US Index Option Universe](https://www.quantconnect.com/docs/v2/lean-cli/datasets/quantconnect/index-options.md#02-Prerequisites) dataset because the US Index Options Universe dataset contains information on the available contracts, including their daily Greeks and implied volatility values.

For more information about the US Index Options dataset, including CLI commands and pricing, see the [dataset listing](https://www.quantconnect.com/datasets/algoseek-us-index-options).

## About the Provider

AlgoSeek is a leading historical intraday US market data provider offering the most comprehensive and detailed market data and analytics products in the financial industry covering Equities, Futures, Options, cash FOREX, and Cryptocurrencies. AlgoSeek data is built for quantitative trading and machine learning. For more information about AlgoSeek, visit [algoseek.com](https://www.algoseek.com).

## Getting Started

The following snippet demonstrates how to request data from the US Index Options dataset:

```python
self.index_symbol = self.add_index('VIX').symbol
option = self.add_index_option(self.index_symbol)
option.set_filter(-2, 2, 0, 90)
self.option_symbol = option.symbol
```

## Data Summary

The following table describes the dataset properties:

| Property | Value |
| --- | --- |
| Start Date | January 2012 |
| Asset Coverage | 7 Index Options |
| Data Density | Regular |
| Resolution | Minute, Hourly, & Daily |
| Timezone | New York |
| Market Hours | [Regular Only](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/market-hours.md) |

## Specification Over Time

According to the SPX Options [contract specification](https://www.cboe.com/tradable_products/sp_500/spx_options/specifications/), some SPX contracts expire every month and SPXW contracts expires every day. Before 2021, you could only trade SPX contracts with the following expiration dates:

- Expires within the next 4 months
- Expires in September within the next 14 months
- Expires in January, March, or June within the next 2 years
- Expires in December within the next 3 years

During this time, SPXW didn't have 0DTE every day.

`Sources`:
- [Cboe Options Exchange to List Three Long-Dated SPX Options Expirations, Beginning November 1, 2021](https://www.prnewswire.com/news-releases/cboe-options-exchange-to-list-three-long-dated-spx-options-expirations-beginning-november-1-2021-301410178.html)
- [S&P 500 Weekly Options Now Expire Five Days a Week](https://www.indexologyblog.com/2022/05/12/sp-500-weekly-options-now-expire-five-days-a-week/)

## Requesting Data

To add US Index Options data to your algorithm, call the `add_index_option` method. Save a reference to the Index Option `Symbol` so you can access the data later in your algorithm.

```python
class IndexOptionsDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2021, 1, 1);
        self.set_end_date(2021, 6, 1);
        self.set_cash(1000000);
        self.universe_settings.asynchronous = True
        self.index_symbol = self.add_index('VIX').symbol

        standard_option = self.add_index_option(self.index_symbol)
        standard_option.set_filter(-2, 2, 0, 90)
        self.standard_option_symbol = standard_option.symbol

        weekly_option = self.add_index_option(self.index_symbol, "VIXW")
        weekly_option.set_filter(-2, 2, 0, 90)
        self.weekly_option_symbol = weekly_option.symbol
```

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.

For more information about creating US Index Option subscriptions, see [Requesting Data](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/requesting-data.md) or [Index Options Universes](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/index-options.md).

## Accessing Data

To get the current US Index Options data, index the `option_chains` property of the current [`Slice`](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md) with the canonical Index Option `Symbol`. Slice objects deliver unique events to your algorithm as they happen, but the `Slice` may not contain data for your Index Option at every time step.

```python
def on_data(self, slice: Slice) -> None:
    standard_chain = slice.option_chains.get(self.standard_option_symbol)
    if standard_chain:
        for contract in standard_chain:
            self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")

    weekly_chain = slice.option_chains.get(self.weekly_option_symbol)
    if weekly_chain:
        for contract in weekly_chain:
            self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
```

You can also iterate through all of the `OptionChain` objects in the current `Slice`.

```python
def on_data(self, slice: Slice) -> None:
    for canonical_symbol, chain in slice.option_chains.items():
        for contract in chain:
            self.log(f"{contract.symbol} price at {slice.time}: {contract.last_price}")
```

For more information about accessing US Index Options data, see [Handling Data](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index-options/handling-data.md).

## Historical Data

You can get historical US Index Options data in an algorithm and the Research Environment.

### Historical Data In Algorithms

To get historical US Index Options data in an algorithm, call the `history` method with the Index Option contract `Symbol`. If there is no data in the period you request, the history result is empty.

```python
# DataFrame of trade and quote data
history_df = self.history(contract.symbol, 100, Resolution.MINUTE)

# DataFrame of open interest data
history_oi_df = self.history(OpenInterest, contract.symbol, 100, Resolution.MINUTE)

# TradeBar objects
history_trade_bars = self.history[TradeBar](contract.symbol, 100, Resolution.MINUTE)

# QuoteBar objects
history_quote_bars = self.history[QuoteBar](contract.symbol, 100, Resolution.MINUTE)

# OpenInterest objects
history_oi = self.history[OpenInterest](contract.symbol, 100, Resolution.MINUTE)
```

For more information about historical data in algorithms, see [History Requests](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-requests.md).

### Historical Data In Research

To get historical US Index Options data in the Research Environment, call the `history` or `option_history` method. The `history` method returns the price, volume, and open interest history for some given Option contract(s). The `option_history` method returns the price and volume history for the contracts that pass your daily universe filter.

```python
qb = QuantBook()
index_symbol = qb.add_index('VIX').symbol
option = qb.add_index_option(index_symbol) # or qb.add_index_option(index_symbol, "VIXW")
option.set_filter(-2, 2, 0, 90)
history = qb.option_history(option.symbol, datetime(2020, 6, 1), datetime(2020, 6, 5))
history_df = history.data_frame
expiries = history.get_expiry_dates()
strikes = history.get_strikes()
```

To get historical data for arbitrary US Index Option contracts instead of just the that pass your universe filter, call the `history` method like you would in an algorithm, but on the `QuantBook` object. For more information about historical data in the Research Environment, see [Key Concepts](https://www.quantconnect.com/docs/v2/research-environment/datasets/index-options/key-concepts.md).

### Historical Greeks and IV Data

To get historical data for the Greeks and implied volatility of Index Options, see the [US Index Option Universe](https://www.quantconnect.com/datasets/quantconnect-us-index-option-universe) dataset.

## Supported Assets

The following table shows the available Index Options:

| Underlying Index | Underlying Ticker | Target Ticker | Standard Contracts | Weekly Contracts | Tradable on Expiry Day |
| --- | --- | --- | --- | --- | --- |
| NASDAQ-100 | NDX |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |
| NASDAQ-100 | NDX | NDXP | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| NASDAQ-100 | NDX | NQX | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| Russell 2000 | RUT |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |
| Russell 2000 | RUT | RUTW |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| S&P500 | SPX |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |
| S&P500 | SPX | SPXW |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |
| S&P500 | VIX |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |  |
| S&P500 | VIX | VIXW |  | ![green check](https://cdn.quantconnect.com/i/tu/check.png) |  |

For more information about each underlying Index, see [Supported Indices](https://www.quantconnect.com/docs/v2/writing-algorithms/datasets/quantconnect/cash-indices.md#10-Supported-Indices).

## Downloading Data

You can download the US Index Options dataset to your local machine to run the LEAN engine locally with the [LEAN CLI](https://www.quantconnect.com/docs/v2/lean-cli.md). For the download commands, prerequisites, and pricing, see [Index Options](https://www.quantconnect.com/docs/v2/lean-cli/datasets/quantconnect/index-options.md) in the LEAN CLI documentation.

## Example Applications

The US Index Options dataset enables you to accurately design strategies for Index Options. Examples include the following strategies:

- Buying VIX call Options to hedge against upcoming volatility
- Buying VIX put Options to capture the natural downward price movement in the VIX index
- Buying SPX put Options to protect against downward price movement in the S&P 500

### Classic Algorithm Example

The following example algorithm buys the VIX Index Option Bull Call Spread with the furthest expiration:

```python
from AlgorithmImports import *

class IndexOptionsDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(200000)
        # Asynchronous can use computational resources efficiently
        self.universe_settings.asynchronous = True
        # Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
        option = self.add_index_option("SPX")
        option.set_filter(lambda u: u.calls_only().strikes(-2, +2).expiration(0, 180))
        self.option_symbol = option.symbol

    def on_data(self, slice: Slice) -> None:
        if not self.portfolio.invested and self.is_market_open(self.option_symbol):
            # Make sure getting the updated VIX option chain
            chain = slice.option_chains.get(self.option_symbol)
            if chain:
                expiry = max([c.expiry for c in chain])
                call_contracts = sorted([c for c in chain if c.expiry == expiry],
                    key=lambda c: c.strike)

                # Need 2 contracts to form a call spread
                if len(call_contracts) < 2:
                    return

                # Obtain 2 call contracts with different strike price to form the call spread
                longCall, shortCall = call_contracts[0:2]

                # Use all the buying power, but need to ensure the order size of the long and short call are the same
                quantity = min([
                    abs(self.calculate_order_quantity(shortCall.symbol, -1)),
                    abs(self.calculate_order_quantity(longCall.symbol, 1))])
                if not quantity:
                    return

                # Bull call spread consists of long a lower-strike call and short a higher-strike call
                self.market_order(shortCall.symbol, -quantity)
                self.market_order(longCall.symbol, quantity)

                expected_margin_usage = max((longCall.strike - shortCall.strike) * self.securities[longCall.symbol].symbol_properties.contract_multiplier * quantity, 0)
                if expected_margin_usage != self.portfolio.total_margin_used:
                    raise Exception("Unexpect margin used!")

    def on_securities_changed(self, changes: SecurityChanges) -> None:
        for security in changes.added_securities:
            if security.type == SecurityType.INDEX_OPTION:
                # Historical data
                history = self.history(security.symbol, 10, Resolution.MINUTE)
```

### Framework Algorithm Example

The following example algorithm buys the VIX Index Option Bull Call Spread with the furthest expiration:

```python
from AlgorithmImports import *

class IndexOptionsDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(200000)
        self.universe_settings.asynchronous = True
        self.set_universe_selection(VIXIndexOptionUniverseSelectionModel())

        self.set_alpha(BullCallSpreadAlphaModel())

        self.set_portfolio_construction(SingleSharePortfolioConstructionModel())

class VIXIndexOptionUniverseSelectionModel(OptionUniverseSelectionModel):

    def __init__(self):
        super().__init__(timedelta(1), self.option_chain_symbol_selector)

    def option_chain_symbol_selector(self, utc_time: datetime) -> List[Symbol]:
        # Only interest in VIX options
        return [Symbol.create("VIX", SecurityType.INDEX_OPTION, Market.USA)]

    def filter(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
        # Filter to get ATM calls expiring in 180 days to form the Bull Call Spread
        return option_filter_universe.calls_only().strikes(-2, +2).expiration(0, 180)

class BullCallSpreadAlphaModel(AlphaModel):

    def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
        if algorithm.portfolio.invested:
            return []

        for canonical_symbol, chain in slice.option_chains.items():
            if not chain:
                return []
            # Bull call spread legs are having the same expiry
            expiry = max([c.expiry for c in chain])
            call_contracts = sorted([c for c in chain if c.expiry == expiry],
                key=lambda c: c.strike)

            # Need 2 contracts to form a call spread
            if len(call_contracts) < 2:
                return []

            # Obtain 2 call contracts with different strike price to form the call spread
            long_call, short_call = call_contracts[0:2]

            # Bull call spread consists of long a lower-strike call and short a higher-strike call
            return Insight.group(
                [
                    Insight.price(long_call.symbol, expiry + timedelta(1), InsightDirection.UP),
                    Insight.price(short_call.symbol, expiry + timedelta(1), InsightDirection.DOWN)
                ])
        return []

    def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
        for security in changes.added_securities:
            if security.type == SecurityType.INDEX_OPTION:
                # Historical data
                history = algorithm.history(security.symbol, 10, Resolution.MINUTE)

class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):

    def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
        if not insights:
            return []
        # Only a single contract toi ensure both legs size is equal
        quantity = min([abs(algorithm.calculate_order_quantity(i.symbol, int(i.direction)))
            for i in insights])

        return [PortfolioTarget(i.symbol, quantity * int(i.direction))
            for i in insights]
```

## Data Point Attributes

The US Index Options dataset provides `TradeBar`, `QuoteBar`, and `OpenInterest` objects.

### TradeBar Attributes

`TradeBar` objects have the following attributes:

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

### QuoteBar Attributes

`QuoteBar` objects have the following attributes:

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

### OpenInterest Attributes

`OpenInterest` objects have the following attributes:

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