Requesting Data
Individual Contracts
Introduction
The AddFutureOptionContractadd_future_option_contract method enables you to add an individual Option contract to your algorithm.
To check which contracts are currently available to add to your algorithm, use the OptionChainoption_chain method.
If you want to subscribe to a set of contracts instead of individual contracts one-by-one, see Universes.
Create Subscriptions
Before you can subscribe to an Option contract, you must configure the underlying Future and get the contract Symbol.
public class BasicFutureOptionAlgorithm : QCAlgorithm
{
private Future _future;
private Symbol _contractSymbol;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
_future = AddFuture(Futures.Indices.SP500EMini,
extendedMarketHours: true,
dataMappingMode: DataMappingMode.OpenInterest,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
contractDepthOffset: 0);
_future.SetFilter(0, 182);
}
public override void OnData(Slice data)
{
if (_contractSymbol == null)
{
// Method 1: Add the desired option chain for the mapped contract
_contractSymbol = SelectOptionContract(_future.Mapped);
AddFutureOptionContract(_contractSymbol);
// Method 2: Get all future contracts from the Future chain provider
var futureContractSymbol = FuturesChain(_future.Symbol).First().Symbol;
var symbol = SelectOptionContract(futureContractSymbol);
AddFutureOptionContract(symbol);
// Method 3: Iterate all Future chains to find the desired future options contracts
foreach (var (_, chain) in data.FutureChains)
{
var expiry = chain.Min(contract => contract.Expiry);
var futureContract = chain.Where(contract => contract.Expiry == expiry).FirstOrDefault();
symbol = SelectOptionContract(futureContract.Symbol);
AddFutureOptionContract(symbol);
}
}
}
private Symbol SelectOptionContract(Symbol futureContractSymbol)
{
var chain = OptionChain(futureContractSymbol)
.Where(contract => contract.Right == OptionRight.Call).ToList();
var expiry = chain.Min(contract => contract.Expiry);
return chain
.Where(contract => contract.Expiry == expiry)
.OrderBy(contract => contract.Strike)
.Select(contract => contract.Symbol).FirstOrDefault();
}
} class BasicFutureOptionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self._future = self.add_future(
Futures.Indices.SP_500_E_MINI,
extended_market_hours=True,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
contract_depth_offset=0
)
self._future.set_filter(0, 182)
self._contract_symbol = None
def on_data(self, data):
if not self._contract_symbol:
# Method 1: Add the desired option chain for the mapped contract
self._contract_symbol = self._select_option_contract(self._future.mapped)
self.add_future_option_contract(self._contract_symbol)
# Method 2: Get all future contracts from the Future chain provider
future_contract_symbol = list(self.futures_chain(self._future.symbol))[0].symbol
symbol = self._select_option_contract(future_contract_symbol)
self.add_future_option_contract(symbol)
# Method 3: Iterate all Future chains to find the desired future options contracts
for symbol, chain in data.future_chains.items():
expiry = min([contract.expiry for contract in chain])
future_contract = next(contract for contract in chain if contract.expiry == expiry)
symbol = self._select_option_contract(future_contract.symbol)
self.add_future_option_contract(symbol)
def _select_option_contract(self, future_contract_symbol):
chain = self.option_chain(future_contract_symbol, flatten=True).data_frame
expiry = chain.expiry.min()
return chain[
(chain.expiry == expiry) & (chain.right == OptionRight.CALL)
].sort_values('strike').index[-1]
Configure the Underlying Futures Contracts
In most cases, you should subscribe to the underlying Futures contract before you subscribe to a Futures Option contract.
_future = AddFuture(Futures.Indices.SP500EMini,
extendedMarketHours: true,
dataMappingMode: DataMappingMode.OpenInterest,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
contractDepthOffset: 0); self._future = self.add_future(
Futures.Indices.SP_500_E_MINI,
extended_market_hours=True,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
contract_depth_offset=0
)
To get a Symbol of a specific Futures contract, use the Mappedmapped property of the Future object or the Symbolsymbol property of the FutureContract objects in the Slice.FutureChainsSlice.future_chains collection.
Get Contract Symbols
To subscribe to a Future Option contract, you need the contract Symbol.
The preferred method to getting Option contract Symbol objects is to use the OptionChainoption_chain method.
This method returns an OptionChain object, which represent an entire chain of Option contracts for a single underlying security.
You can even format the chain data into a DataFrame where each row in the DataFrame represents a single contract.
With the chain, sort and filter the data to find the specific contract(s) you want to trade.
// Get the contracts available to trade.
var chain = OptionChain(futureContractSymbol)
.Where(contract => contract.Right == OptionRight.Call).ToList();
// Select a contract.
var expiry = chain.Min(contract => contract.Expiry);
_contractSymbol = chain
// Select call contracts with the closest expiry.
.Where(contract => contract.Expiry == expiry)
// Select the contract with the lowest strike price.
.OrderBy(contract => contract.Strike)
.Select(contract => contract.Symbol).FirstOrDefault(); # Get the contracts available to trade (in DataFrame format).
chain = self.option_chain(future_contract_symbol, flatten=True).data_frame
# Select a contract.
expiry = chain.expiry.min()
self._contract_symbol = chain[
# Select call contracts with the closest expiry.
(chain.expiry == expiry) & (chain.right == OptionRight.CALL)
# Select the contract with the lowest strike price.
].sort_values('strike').index[0]
Alternatively, you can create a Future Option contract Symbol object directly parsing its OSI ticker using the SymbolRepresentation.ParseOptionTickerOSISymbolRepresentation.parse_option_ticker_osi method.
// Create the contract Symbol for the Sept 2024 E-mini S&P 500 Call 7900 20 Sept 2024.
_contractSymbol = SymbolRepresentation.ParseOptionTickerOSI("ESU24 240920C07900000", SecurityType.FutureOption, OptionStyle.American, Market.CME);
// Create the contract Symbol using the 1-digit year format.
_contractSymbol = SymbolRepresentation.ParseOptionTickerOSI("ESU4 240920C07900000", SecurityType.FutureOption, OptionStyle.American, Market.CME); # Create the contract Symbol for the Sept 2024 E-mini S&P 500 Call 7900 20 Sept 2024.
self._contract_symbol = SymbolRepresentation.parse_option_ticker_osi('ESU24 240920C07900000', SecurityType.FUTURE_OPTION, OptionStyle.AMERICAN, Market.CME)
# Create the contract Symbol using the 1-digit year format.
self._contract_symbol = SymbolRepresentation.parse_option_ticker_osi('ESU4 240920C07900000', SecurityType.FUTURE_OPTION, OptionStyle.AMERICAN, Market.CME)
Subscribe to Contracts
To create a Future Option contract subscription, pass the contract Symbol to the AddFutureOptionContractadd_future_option_contract method. Save a reference to the contract Symbolsymbol so you can easily access the Option contract in the OptionChain that LEAN passes to the OnDataon_data method. This method returns an Option object. To override the default pricing model of the Option, set a pricing model.
var option = AddFutureOptionContract(_contractSymbol); option.PriceModel = OptionPriceModels.BinomialCoxRossRubinstein();
option = self.add_future_option_contract(self._contract_symbol) option.price_model = OptionPriceModels.binomial_cox_ross_rubinstein()
Warm Up Contract Prices
If you subscribe to a Future Option contract with AddFutureOptionContractadd_future_option_contract, 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.get_last_known_prices) self.set_security_initializer(BrokerageModelSecurityInitializer(self.brokerage_model, seeder))
Supported Assets
To view the supported assets in the US Future Options dataset, see the Supported Assets.
Resolutions
The following table shows the available resolutions and data formats for Future Option contract subscriptions:
| Resolution | TradeBar | QuoteBar | Trade Tick | Quote Tick |
|---|---|---|---|---|
TickTICK | ||||
SecondSECOND | ||||
MinuteMINUTE | ![]() | ![]() | ||
HourHOUR | ![]() | ![]() | ||
DailyDAILY | ![]() | ![]() |
There is only one resolution option, so you don't need to pass a resolution argument to the AddFutureOptionContractadd_future_option_contract method.
AddFutureOptionContract(_optionContractSymbol, Resolution.Minute);
self.add_future_option_contract(self._option_contract_symbol, Resolution.MINUTE)
To create custom resolution periods, see Consolidating Data.
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 fillForwardfill_forward argument to false when you create the security subscription.
AddFutureOptionContract(_optionContractSymbol, fillForward: false);
self.add_future_option_contract(self._option_contract_symbol, fill_forward=False)
Extended Market Hours
By default, your security subscriptions only cover regular trading hours. To subscribe to pre and post-market trading hours for a specific asset, enable the extendedMarketHoursextended_market_hours argument when you create the security subscription.
AddFutureOptionContract(_optionContractSymbol, extendedMarketHours: true);
self.add_future_option_contract(self._option_contract_symbol, extended_market_hours=True)
You only receive extended market hours data if you create the subscription with minute, second, or tick resolution. If you create the subscription with daily or hourly resolution, the bars only reflect the regular trading hours.
To view the schedule of regular and extended market hours, see Market Hours.
Data Normalization
The data normalization mode doesn't affect the data that LEAN passes to OnDataon_data 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 AddFutureOptionContractadd_future_option_contract, call the RemoveOptionContractremove_option_contract method. This method is an alias for RemoveSecurityremove_security.
RemoveOptionContract(_optionContractSymbol);
self.remove_option_contract(self._option_contract_symbol)
The RemoveOptionContractremove_option_contract method cancels your open orders for the contract and liquidates your holdings.
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 Symbolsymbol to access the value in the Securitiessecurities object.
var option = Securities[_optionContractSymbol]; var underlying = Securities[_optionContractSymbol.Underlying]; var underlyingPrice = underlying.Price;
option = self.securities[self._option_contract_symbol] underlying = self.securities[self._option_contract_symbol.underlying] underlying_price = underlying.price
To get the Option payoff, call the GetPayOffget_pay_off method.
var payOff = option.GetPayOff(underlyingPrice);
pay_off = option.get_pay_off(underlying_price)
To get the Option intrinsic value, call the GetIntrinsicValueget_intrinsic_value method.
var intrinsicValue = option.GetIntrinsicValue(underlyingPrice);
intrinsic_value = option.get_intrinsic_value(underlying_price)
To get the Option out-of-the-money amount, call the OutOfTheMoneyAmountout_of_the_money_amount method.
var otmAmount = option.OutOfTheMoneyAmount(underlyingPrice);
otm_amount = option.out_of_the_money_amount(underlying_price)
To check whether the Option can be automatic exercised, call the IsAutoExercisedis_auto_exercised method.
var isAutoExercised = option.IsAutoExercised(underlyingPrice);
is_auto_exercised = option.is_auto_exercised(underlying_price)
