Datasets

Index Options

Introduction

This page explains how to request, manipulate, and visualize historical Index Options data.

Prerequisites

Working knowledge of C#.

Working knowedge of Python and pandas. If you are not familiar with pandas, see the pandas documentation.

Create Subscriptions

Follow these steps to subscribe to an Index Option security:

  1. Load the required assembly files and data types.
  2. #load "../Initialize.csx"
    #load "../QuantConnect.csx"
    
    using QuantConnect;
    using QuantConnect.Data;
    using QuantConnect.Data.Market;
    using QuantConnect.Algorithm;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Index;
    using QuantConnect.Research;
  3. Instantiate a QuantBook.
  4. var qb = new QuantBook();
    qb = QuantBook()
  5. Call the AddIndex method with a ticker and resolution.
  6. var index = qb.AddIndex("SPX", Resolution.Minute);
    index = qb.AddIndex("SPX", Resolution.Minute)

    If you do not pass a resolution argument, Resolution.Minute is used by default.

  7. Call the AddIndexOption method with the underlying Index Symbol.
  8. var option = qb.AddIndexOption(index.Symbol);
    option = qb.AddIndexOption(index.Symbol)
  9. (Optional) Call the SetFilter method with strike and expiration boundary values.
  10. option.SetFilter(-1, 1, 0, 90);
    option.SetFilter(-1, 1, 0, 90)

    If you don't call the SetFilter method, the default values of the minStrike, maxStrike, minExpiryDays, and maxExpiryDays parameters are -1, 1, 0, and 35, respectively.

If you want historical data on individual contracts and their OpenInterest, you need to subscribe to the individual contracts. You need to subscribe to the underlying Index before you can subscribe to its Option contracts. Follow these steps to subscribe to individual Index Option contracts:

  1. Call the GetOptionsContractList method with the underlying Index Symbol and a datetimeDateTime.
  2. var startDate = new DateTime(2021, 12, 31);
    var symbols = qb.OptionChainProvider.GetOptionContractList(index.Symbol, startDate);
    start_date = datetime(2021, 12, 31)
    symbols = qb.OptionChainProvider.GetOptionContractList(index.Symbol, start_date)

    The call returns a list of Symbols that reference the OptionContracts that were trading at the given time.

  3. Select the Symbol of the OptionContract(s) for which you want to get historical data.
  4. For example, select an arbitrary Symbol.

    var contractSymbol = symbols.ToArray()[698];
    contract_symbol = symbols[698]
  5. Call the AddIndexOptionContract method with an OptionContract Symbol and disable fill-forward.
  6. qb.AddIndexOptionContract(contractSymbol, fillDataForward: false);
    qb.AddIndexOptionContract(contract_symbol, fillDataForward = False)

    Disable fill-forward because there are only a few OpenInterest data points per day.

Get Historical Data

You need to subscribe to individual Option contracts before you can request their historical data. You can request an amount of historical data based on a trailing number of bars, a trailing period of time, or a defined period of time. Before you request historical data, call the SetStartDate method with a datetimeDateTime to reduce the risk of look-ahead bias.

qb.SetStartDate(startDate);
qb.SetStartDate(start_date)

If you call the SetStartDate method, the date that you pass to the method is the latest date for which your history requests will return data.

Trailing Number of Bars

Call the History method with a symbol and integer to request historical data based on the given number of trailing bars.

var contractHistory = qb.History(contractSymbol, 400);
var openInterestHistory = qb.History<OpenInterest>(contractSymbol, 400);
contract_history = qb.History(contract_symbol, 400)
open_interest_history = qb.History(OpenInterest, contract_symbol, 400)

These calls return the most recent bars, excluding periods of time when the exchange was closed.

Trailing Period of Time

Call the History method with a symbol and TimeSpantimedelta to request historical data based on the given trailing period of time.

var contractHistory = qb.History(contractSymbol, TimeSpan.FromDays(10));
var openInterestHistory = qb.History<OpenInterest>(contractSymbol, TimeSpan.FromDays(10));
contract_history = qb.History(contract_symbol, timedelta(days=10))
open_interest_history = qb.History(OpenInterest, contract_symbol, timedelta(days=10))

These calls return the most recent bars, excluding periods of time when the exchange was closed.

Defined Period of Time

Call the History method with a symbol, start DateTimedatetime, and end DateTimedatetime to request historical data based on the defined period of time.

var startTime = new DateTime(2021,12,1);
var endTime = new DateTime(2021,12,31);
var contractHistory = qb.History(contractSymbol, startTime, endTime);
var openInterestHistory = qb.History<OpenInterest>(contractSymbol, startTime, endTime);
start_time = datetime(2021,12,1)
end_time = datetime(2021,12,31)
contract_history = qb.History(contract_symbol, start_time, end_time)
open_interest_history = qb.History(OpenInterest, contract_symbol, start_time, end_time)

These calls return the bars that are timestamped within the defined period of time.

In all of the cases above, the History method returns a DataFrame with a MultiIndex. If you request trade history, the DataFrame contains quote prices and trade volume.

Trade history DataFrame

If you request open interest history, the DataFrame contains open interest data.

Open interest DataFrame

In all of the cases above, the History method returns an IEnumerable<TradeBar> for single-security trade history requests and an IEnumerable<OpenInterest> for open interest history requests. Request trade history with a list of Option contract Symbols to get an IEnumerable<Slice>.

var contractHistorySlices = qb.History(new [] { contractSymbol }, startTime, endTime);

Adjust Universe Size

You need to subscribe to all of the Options for which you want historical data. You can request historical data for a subset of the Option contract properties or a subset of the Option contracts. Before you request historical data, redefine the start datetimeDateTime to reduce the amount of data that the history requests return.

startTime = endTime.AddDays(-2);
start_time = end_time-timedelta(2)

Subset of Options Contract Properties

This functionality is not currently supported for C# research environments. Use Python to get a subset of OptionContract properties.

Call the GetOptionHistory method with an Index Symbol, start datetime, end datetime, and resolution to get historical Option contract data for the given Symbol.

option_history = qb.GetOptionHistory(index.Symbol, start_time, end_time, Resolution.Minute)

The call returns an OptionHistory object. If you don't call the SetFilter method, the GetOptionHistory method uses the default filter definition to select OptionContracts and their historical data.

Call the GetAllData method to get all of the historical data for the selected contracts and the underlying Index.

history = option_history.GetAllData()

The call returns a DataFrame with a MultiIndex.

GetAllData DataFrame

Call the GetExpiryDates method to get all of the expiry dates for the selected contracts.

expiries = option_history.GetExpiryDates()

The call returns a list of datetimes.

Call the OptionHistory's GetStrikes method to get all of the strike prices for the selected contracts.

strikes = option_history.GetStrikes()

The call returns a list of floats.

Subset of Option Contracts

Follow these steps to get historical data for a subset of the contracts for the Options to which you are subscribed:

  1. Call the GetOptionsContractList method with an Index Symbol and a datetimeDateTime to get a list of OptionContract Symbols that were trading at the given time.
  2. var symbols = qb.OptionChainProvider.GetOptionContractList(index.Symbol, startDate);
    symbols = qb.OptionChainProvider.GetOptionContractList(index.Symbol, start_date)

    The method returns a list of more than 5,000 Symbols.

  3. Select the subset of Symbols for which you want to get historical data.
  4. var expiry = new DateTime(2022,01,21);
    var selectedSymbols = symbols.Where(x => x.ID.Date == expiry && 
    x.ID.StrikePrice >= 4775 &&
    x.ID.StrikePrice <= 4810);
    selected_symbols = [symbol for symbol in symbols \
        if symbol.ID.StrikePrice in strikes and symbol.ID.Date == min(expiries)]
  5. If you want to get open interest data, call the AddIndexOptionContract method with the OptionContract Symbol and disable fill-forward.
  6. foreach (var symbol in selectedSymbols)
    {
        qb.AddIndexOptionContract(symbol, fillDataForward: false);
    }
    for symbol in selected_symbols:
        qb.AddIndexOptionContract(symbol, fillDataForward = False)
  7. Call the History method with a list of Symbols to get the historical data of the given Symbols.
  8. var definedPeriodContractHistory = qb.History(symbols, startTime, endTime);
    var timespanContractHistory = qb.History(symbols, TimeSpan.FromDays(2));
    var barCountContractHistory = qb.History(symbols, 400);
    
    var definedPeriodOpenInterestHistory = qb.History<OpenInterest>(symbols, startTime, endTime);
    var timespanOpenInterestHistory = qb.History<OpenInterest>(symbols, TimeSpan.FromDays(2));
    var barCountOpenInterestHistory = qb.History<OpenInterest>(symbols, 400);
    
    defined_period_contract_history = qb.History(selected_symbols, start_time, end_time)
    timespan_contract_history = qb.History(selected_symbols, timedelta(days=2))
    bar_count_contract_history = qb.History(selected_symbols, 400)
    
    defined_period_open_interest_history = qb.History(OpenInterest, selected_symbols, start_time, end_time)
    timespan_open_interest_history = qb.History(OpenInterest, selected_symbols, timedelta(days=2))
    bar_count_open_interest_history = qb.History(OpenInterest, selected_symbols, 400)

Wrangle Data

You need some historical data to perform wrangling operations. Run a cell in a Jupyter Notebook with the pandas object as the last line to display the historical data.

The DataFrame that contains historical data for Options contracts has a MultiIndex with levels for the expiry, strike, OptionRight, Symbol, and timestamp. For some of the wrangling operations, you need to drop the first three index levels. To drop the index levels, run:

contract_history.index = contract_history.index.droplevel([0,1,2])
open_interest_history.index = open_interest_history.index.droplevel([0,1,2])
timespan_contract_history.index = timespan_contract_history.index.droplevel([0,1,2])
timespan_open_interest_history.index = timespan_open_interest_history.index.droplevel([0,1,2])

You need some historical data to perform wrangling operations. Use LINQ to wrangle the data and then call the Console.WriteLine method in a Jupyter Notebook to display the data.

Select One Contract

Iterate through the IEnumerable to get the historical data of the contract.

Index the DataFrame with a Symbol to select the historical data of the contract.

To display the price data of the contract, run:

foreach(var bar in contractHistory.TakeLast(5))
{
    Console.WriteLine($"{bar} EndTime: {bar.EndTime}");
}
contract_history.loc[contract_symbol]

The Jupyter Notebook displays the trade and quote data of the contract.

The Jupyter Notebook displays a DataFrame containing the trade and quote data of the contract.

To display the open interest data of the contract, run:

foreach(var openInterest in openInterestHistory.TakeLast(5))
{
    Console.WriteLine($"{openInterest} EndTime: {openInterest.EndTime}");
}
open_interest_history.loc[contract_symbol]

The Jupyter Notebook displays the open interest of the contract.

The Jupyter Notebook displays a DataFrame containing the open interest of the contract.

Select a Property of the Contract

Iterate through the IEnumerable and select a property of the Slice to get the historical values of the property.

Index the DataFrame with a Symbol to select the historical data of the contract and then select a property column to get the historical values of the property.

To display the closing prices of the contract, run:

To display the closing ask prices of the contract, run:

foreach(var x in contractHistory.TakeLast(5))
{
    Console.WriteLine($"{x.Symbol}: Close: {x.Close} EndTime:{x.EndTime}");
}
contract_history.loc[contract_symbol]['askclose']

The Jupyter Notebook displays the closing prices of the contract.

The Jupyter Notebook displays a Series containing the closing ask prices of the contract.

To display the open interest of the contract, run:

open_interest_history.loc[contract_symbol]['openinterest']

The Jupyter Notebook displays a Series containing the open interest of the contract.

Unstack the Dataframe

If you request historical data for multiple contracts, you can transform the DataFrame so that it is a time series of a property value for all of the containing contracts. Select the column that you want to display for each contract and then call the unstack method to transform the DataFrame into the desired format. You can rename the columns of the transformed DataFrame to be the respective OptionsContract Symbols.

To display the closing bid prices of all of the contracts, run:

df = timespan_contract_history.copy()
df = df['bidclose'].unstack(level=0)
df.columns = [Symbol.GetAlias(SecurityIdentifier.Parse(x), index.Symbol)
    for x in df.columns]
df

The Jupyter Notebook displays a DataFrame that contains the closing bid prices of the contracts and has the Symbol of each OptionsContract as the column indices.

To display the open interest of all of the contracts, run:

df = timespan_open_interest_history.copy()
df = df['openinterest'].unstack(level=0)
df.columns = [Symbol.GetAlias(SecurityIdentifier.Parse(x), index.Symbol)
    for x in df.columns]
df

The Jupyter Notebook displays a DataFrame that contains the open interest of the contracts and has the Symbol of each OptionsContract as the column indices.

If you unstack the DataFrame that is returned from the GetAllData method instead of the History method, the DataFrame contains a NaN column that represents the underlying Index.

Plot Data

Jupyter Notebooks don't currently support libraries to plot historical data, but we are working on adding the functionality. Until we add the functionality, use Python to plot historical Index Options data.

You need to get some historical Index Option data to plot it. You can use many of the supported plotting libraries to visualize data in various formats. For example, you can plot candlestick and line charts.

Candlestick Chart

Follow these steps to plot candlestick charts:

  1. Call the History method with an OptionContract Symbol and a timedelta.
  2. history = qb.History(contract_symbol, timedelta(1))
  3. Drop the first four index levels of DataFrame that returns.
  4. history.index = history.index.droplevel([0,1,2,3])
  5. Import the plotly library.
  6. import plotly.graph_objects as go
  7. Call the Candlestick constructor with the timestamp and price series.
  8. candlestick = go.Candlestick(x=history.index,
                                 open=history['open'],
                                 high=history['high'],
                                 low=history['low'],
                                 close=history['close'])
  9. Call the Layout constructor with some titles.
  10. layout = go.Layout(title=go.layout.Title(text=f'{symbol.Value} OHLC'),
                       xaxis_title='Date',
                       yaxis_title='Price',
                       xaxis_rangeslider_visible=False)
  11. Call the Figure constructor with the Candlestick and Layout.
  12. fig = go.Figure(data=[candlestick], layout=layout)
  13. Call the show method.
  14. fig.show()

    The Jupyter Notebook displays a candlestick chart of the Option contract's price.

Line Chart

Follow these steps to plot line charts using built-in methods:

  1. Call the History method with the OpenInterest class, OptionContract Symbols, and a timedelta.
  2. history = qb.History(OpenInterest, selected_symbols, timedelta(days=30))
  3. Drop the first three index levels of the returned DataFrame.
  4. history.index = history.index.droplevel([0,1,2])
  5. Select the open interest property, call the unstack method, then call the ffill method.
  6. open_interests = history['openinterest'].unstack(level=0).ffill()
  7. Rename the columns to be the Symbol of each contract.
  8. open_interests.columns = [
        Symbol.GetAlias(SecurityIdentifier.Parse(x), index.Symbol)
            for x in open_interests.columns]
  9. Call the plot method with a title and figure size.
  10. open_interests.plot(title="Open Interest", figsize=(16, 8))
  11. Call the show method.
  12. plt.show()

    The Jupyter Notebook displays a line chart of open interest data.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: