Index Options

Requesting Data


Request Index Options data in your algorithm to receive a feed of contract prices in the OnData method. For more information about the specific dataset we use for backtests, see the US Index Options dataset listing. To trade Index Options live, you can use one of the brokerage data feeds. Index Options are exclusively European-style Options.

Create Subscriptions

Before you can subscribe to an Index Option contract, you must configure the underlying Index and get the contract Symbol.

Configure the Underlying Index

In most cases, you should subscribe to the underlying Index before you subscribe to an Index Option contract.

_symbol = AddIndex("SPX").Symbol;
self.symbol = self.AddIndex("SPX").Symbol

If you subscribe to an Index Option contract but don't have a subscription to the underlying Index, LEAN automatically subscribes to the underlying Index and sets its fill forward property to match that of the Index Option contract. In this case, you still need the Index Symbol to subscribe to Index Option contracts. If you don't have access to it, create it.

_symbol = QuantConnect.Symbol.Create("SPX", SecurityType.Index, Market.USA);
self.symbol = Symbol.Create("SPX", SecurityType.Index, Market.USA)

To override the initial guess of implied volatility, set and warm up the underlying volatility model.

Get Contract Symbols

To get Index Option contract Symbol objects, call the CreateOption method or use the OptionChainProvider. If you use the CreateOption method, you need to know the specific contract details.

// Standard contracts
_contractSymbol = QuantConnect.Symbol.CreateOption(_symbol, Market.USA,
    OptionStyle.European, OptionRight.Call, 3650, new DateTime(2022, 6, 17));

// Weekly contracts
_weeklyContractSymbol = QuantConnect.Symbol.CreateOption(_symbol, "SPXW", Market.USA,
    OptionStyle.European, OptionRight.Call, 3650, new DateTime(2022, 6, 17));
# Standard contracts
self.contract_symbol = Symbol.CreateOption(self.symbol, Market.USA,
    OptionStyle.European, OptionRight.Call, 3650, datetime(2022, 6, 17))

# Weekly contracts
self.weekly_contract_symbol = Symbol.CreateOption(self.symbol, "SPXW", Market.USA,
    OptionStyle.European, OptionRight.Call, 3650, datetime(2022, 6, 17))

Another way to get an Index Option contract Symbol is to use the OptionChainProvider. The GetOptionContractList method of OptionChainProvider returns a list of Symbol objects that reference the available Option contracts for a given underlying Index on a given date. To filter and select contracts, you can use the following properties of each Symbol object:

ID.DateThe expiration date of the contract.
ID.StrikePriceThe strike price of the contract.
ID.OptionRight The contract type. The OptionRight enumeration has the following members:
ID.OptionStyle The contract style. The OptionStyle enumeration has the following members:
We currently only support European-style Options for Index Options.
// Standard contracts
_canonicalSymbol = QuantConnect.Symbol.CreateCanonicalOption(_symbol, Market.USA, "?SPX");
var contractSymbols = OptionChainProvider.GetOptionContractList(_canonicalSymbol, Time);
var expiry = contractSymbols.Select(symbol => symbol.ID.Date).Min();
var filteredSymbols = contractSymbols.Where(symbol => symbol.ID.Date == expiry && symbol.ID.OptionRight == OptionRight.Call);
_contractSymbol = filteredSymbols.OrderByDescending(symbol => symbol.ID.StrikePrice).Last();

// Weekly contracts
_weeklyCanonicalSymbol = QuantConnect.Symbol.CreateCanonicalOption(_symbol, "SPXW", Market.USA, "?SPXW");
var weeklyContractSymbols = OptionChainProvider.GetOptionContractList(_weeklyCanonicalSymbol, Time)
    .Where(symbol => OptionSymbol.IsWeekly(symbol));
var weeklyExpiry = weeklyContractSymbols.Select(symbol => symbol.ID.Date).Min();
filteredSymbols = contractSymbols.Where(symbol => symbol.ID.Date == weeklyExpiry && symbol.ID.OptionRight == OptionRight.Call);
_weeklyContractSymbol = filteredSymbols.OrderByDescending(symbol => symbol.ID.StrikePrice).Last();
# Standard contracts
self.canonical_symbol = Symbol.CreateCanonicalOption(self.symbol, Market.USA, "?SPX")       
contract_symbols = self.OptionChainProvider.GetOptionContractList(self.canonical_symbol, self.Time)
expiry = min([symbol.ID.Date for symbol in contract_symbols])
filtered_symbols = [symbol for symbol in contract_symbols if symbol.ID.Date == expiry and symbol.ID.OptionRight == OptionRight.Call]
self.contract_symbol = sorted(filtered_symbols, key=lambda symbol: symbol.ID.StrikePrice)[0]

# Weekly contracts
self.weekly_canonical_symbol = Symbol.CreateCanonicalOption(self.symbol, "SPXW", Market.USA, "?SPXW")
weekly_contract_symbols = self.OptionChainProvider.GetOptionContractList(self.weekly_canonical_symbol, self.Time)
weekly_contract_symbols = [symbol for symbol in weekly_contract_symbols if OptionSymbol.IsWeekly(symbol)]
weekly_expiry = min([symbol.ID.Date for symbol in weekly_contract_symbols])
weekly_filtered_symbols = [symbol for symbol in weekly_contract_symbols if symbol.ID.Date == weekly_expiry and symbol.ID.OptionRight == OptionRight.Call]
self.weekly_contract_symbol = sorted(weekly_filtered_symbols, key=lambda symbol: symbol.ID.StrikePrice)[0]

Subscribe to Contracts

To create an Index Option contract subscription, pass the contract Symbol to the AddIndexOptionContract method. Save a reference to the contract Symbol so you can easily access the contract in the OptionChain that LEAN passes to the OnData method. To override the default pricing model of the Option, set a pricing model.

var option = AddIndexOptionContract(_contractSymbol);
option.PriceModel = OptionPriceModels.BlackScholes();
option = self.AddIndexOptionContract(self.contract_symbol)
option.PriceModel = OptionPriceModels.BlackScholes()

The AddIndexOptionContract method creates a subscription for a single Index Option contract and adds it to your user-defined universe. To create a dynamic universe of Index Option contracts, add an Index Option universe.

Warm Up Contract Prices

If you subscribe to an Index Option contract with AddIndexOptionContract, you'll need to wait until the next Slice to receive data and trade the contract. To trade the contract in the same time step you subscribe to the contract, set the current price of the contract in a security initializer.

var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(new BrokerageModelSecurityInitializer(BrokerageModel, seeder));
seeder = FuncSecuritySeeder(self.GetLastKnownPrices)
self.SetSecurityInitializer(BrokerageModelSecurityInitializer(self.BrokerageModel, seeder))

Supported Assets

To view the supported assets in the US Index Options dataset, see Supported Assets.


The following table shows the available resolutions and data formats for Index Option contract subscriptions:

ResolutionTradeBarQuoteBarTrade TickQuote Tick


Minutegreen checkgreen check
Hourgreen checkgreen check
Dailygreen checkgreen check

The default resolution for Index Option subscriptions is Resolution.Minute. To change the resolution, pass a resolution argument to the AddIndexOptionContract method.

AddIndexOptionContract(_contractSymbol, Resolution.Hour);
self.AddIndexOptionContract(self.contract_symbol, Resolution.Hour)

To create custom resolution periods, see Consolidating Data.

Supported Markets

The following Market enumeration members are available for Index Options:

You don't need to pass a Market argument to the AddIndexOptionContract method because the contract Symbol already contains the market.

Fill Forward

Fill forward means if there is no data point for the current slice, LEAN uses the previous data point. Fill forward is the default data setting. If you disable fill forward, you may get stale fills or you may see trade volume as zero.

To disable fill forward for a security, set the fillForward argument to false when you create the security subscription.

AddIndexOptionContract(_contractSymbol, fillForward: false);
self.AddIndexOptionContract(self.contract_symbol, fillForward=False)

Margin and Leverage

LEAN models buying power and margin calls to ensure your algorithm stays within the margin requirements. Options are already leveraged products, so you can't change their leverage.

Data Normalization

The data normalization mode doesn't affect the data that LEAN passes to OnData or the data from history request. If you change the data normalization mode, it won't change the outcome.

Remove Subscriptions

To remove a contract subscription that you created with AddIndexOptionContract, call the RemoveOptionContract method. This method is an alias for RemoveSecurity.


The RemoveOptionContract method cancels your open orders for the contract and liquidates your holdings.


The AddIndexOptionContract method returns an Option object, which have the following properties:

Helper Methods

The Option object provides methods you can use for basic calculations. These methods require the underlying price. To get the Option object and the Security object for its underlying in any function, use the Option Symbol to access the value in the Securities object.

var option = Securities[_contractSymbol];
var underlying = Securities[_contractSymbol.Underlying];
var underlyingPrice = underlying.Price;
option = self.Securities[self.contract_symbol]
underlying = self.Securities[self.contract_symbol.Underlying]
underlying_price = underlying.Price

To get the Option payoff, call the GetPayOff method.

var payOff = option.GetPayOff(underlyingPrice);
pay_off = option.GetPayOff(underlying_price)

To get the Option intrinsic value, call the GetIntrinsicValue method.

var intrinsicValue = option.GetIntrinsicValue(underlyingPrice);
intrinsic_value = option.GetIntrinsicValue(underlying_price)

To get the Option out-of-the-money amount, call the OutOfTheMoneyAmount method.

var otmAmount = option.OutOfTheMoneyAmount(underlyingPrice);
otm_amount = option.OutOfTheMoneyAmount(underlying_price)

To check whether the Option can be automatic exercised, call the IsAutoExercised method.

var isAutoExercised = option.IsAutoExercised(underlyingPrice);
is_auto_exercised = option.IsAutoExercised(underlying_price)

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: