Requesting Data
Universes
Introduction
The AddIndexOption
add_index_option
method enables you to select a basket of Option contracts for an underlying Index.
To form your universe of contracts, you can filter them down by their strike price and expiry or you can choose to a subset of the contracts that form popular Option strategies.
If you want to subscribe to individual contracts one-by-one instead of a set of contracts, see Individual Contracts.
Create Universes
To add a universe of Index Option contracts, in the Initialize
initialize
method, call the AddIndexOption
add_index_option
method. This method returns an Option
object, which has a SetFilter
set_filter
method you can call to filter the set of tradable contract down to just the contracts you want.
public class BasicIndexOptionAlgorithm : QCAlgorithm { private Symbol _symbol; public override void Initialize() { UniverseSettings.Asynchronous = true; var option = AddIndexOption("SPX", "SPXW"); option.SetFilter(Filter); _symbol = option.Symbol; } private OptionFilterUniverse Filter(OptionFilterUniverse universe) { return universe.IncludeWeeklys().Expiration(0, 7).Delta(0.35m, 0.75m); } public override void OnData(Slice data) { if (data.OptionChains.TryGetValue(_symbol, out var chain)) { var contract = chain.OrderBy(x => x.Expiry).ThenBy(x => x.Greeks.Delta).FirstOrDefault(); } } }
class BasicIndexOptionAlgorithm(QCAlgorithm): def initialize(self): self.universe_settings.asynchronous = True option = self.add_index_option("SPX","SPXW") option.set_filter(self._filter) self._symbol = option.symbol def _filter(self, universe): return universe.include_weeklys().expiration(0, 7).delta(0.35, 0.75) 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]
For more information about the AddIndexOption
add_index_option
method, see Create Universes.
Filter by Investment Strategy
Options trading strategies consist of simultaneously buying or selling one or more Option contracts of the same underlying Index with different features. The following table describes the filter methods of the OptionFilterUniverse
class that select contract for Option strategies.
The following table describes the filter methods of the OptionFilterUniverse
class that select contracts for Option strategies:
NakedCall(int minDaysTillExpiry, decimal strikeFromAtm) naked_call(min_days_till_expiry: int, strike_from_atm: float) Selects a call contract to form Naked Call, Covered Call, or Protective Call Option strategies. |
NakedPut(int minDaysTillExpiry, decimal strikeFromAtm) naked_put(min_days_till_expiry: int, strike_from_atm: float) Selects a put contract to form Naked Put, Covered Put, or Protective Put Option strategies. |
CallSpread(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal lowerStrikeFromAtm) 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 or Bear Call Spread Option strategies. |
PutSpread(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal lowerStrikeFromAtm) 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 or Bear Put Spread Option strategies. |
CallCalendarSpread(decimal strikeFromAtm, int minNearDaysTillExpiry, int minFarDaysTillExpiry) 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 or Short Call Calendar Spread Option strategies. |
PutCalendarSpread(decimal strikeFromAtm, int minNearDaysTillExpiry, int minFarDaysTillExpiry) 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 or Short Put Calendar Spread Option strategies. |
Strangle(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal lowerStrikeFromAtm) strangle(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float) Selects two contracts to form Long Strangle or Short Strangle Option strategies. |
Straddle(int minDaysTillExpiry) straddle(min_days_till_expiry: int) Selects two contracts to form Long Straddle or Short Straddle Option strategies. |
ProtectiveCollar(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal lowerStrikeFromAtm) protective_collar(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float) Selects two contracts to form Protective Collar Option strategies. |
Conversion(int minDaysTillExpiry, decimal strikeFromAtm) conversion(min_days_till_expiry: int, strike_from_atm: float) Selects two contracts to form Conversion or Reverse Conversion Option strategies. |
CallButterfly(int minDaysTillExpiry, decimal strikeSpread) call_butterfly(min_days_till_expiry: int, strike_spread: float) Selects three contracts to form Long Call Butterfly or Short Call Butterfly Option strategies. |
PutButterfly(int minDaysTillExpiry, decimal strikeSpread) put_butterfly(min_days_till_expiry: int, strike_spread: float) Selects three contracts to form Long Put Butterfly or Short Put Butterfly Option strategies. |
IronButterfly(int minDaysTillExpiry, decimal strikeSpread) iron_butterfly(min_days_till_expiry: int, strike_spread: float) Selects four contracts to form Long Iron Butterfly or Short Iron Butterfly Option strategies. |
IronCondor(int minDaysTillExpiry, decimal nearStrikeSpread, decimal farStrikeSpread) iron_condor(min_days_till_expiry: int, near_strike_spread: float, far_strike_spread: float) Selects four contracts to form Long Iron Condor or Short Iron Condor Option strategies. |
BoxSpread(int minDaysTillExpiry, decimal strikeSpread) box_spread(min_days_till_expiry: int, strike_spread: float) Selects four contracts to form Box Spread or Short Box Spread Option strategies. |
JellyRoll(decimal strikeFromAtm, int minNearDaysTillExpiry, int minFarDaysTillExpiry) 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 or Short Jelly Roll Option strategies. |
CallLadder(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal middleStrikeFromAtm, decimal lowerStrikeFromAtm) 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 or Bull Call Ladder Option strategies. |
PutLadder(int minDaysTillExpiry, decimal higherStrikeFromAtm, decimal middleStrikeFromAtm, decimal lowerStrikeFromAtm) 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 or Bull Put Ladder Option strategies. |
The preceding methods return an OptionFilterUniverse
, so you can chain the methods together.
// Example 1: Select a Straddle option.SetFilter(optionFilterUniverse => optionFilterUniverse.Straddle(30, 5, 10)); // Example 2: Select the contracts (including weeklys) that expire in the next 30 days that form an Iron Condor option.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().Strikes(-20, 20).Expiration(0, 30).IronCondor(30, 5, 10)); // Example 3: Select the 0DTE contracts that form an Strangle option.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().Expiration(0, 0).Strangle(30, 5, -10));
# Example 1: Select a Straddle option.set_filter(lambda option_filter_universe: option_filter_universe.straddle(30, 5, 10)) # 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.include_weeklys().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.include_weeklys().expiration(0, 0).strangle(30, 5, -10))
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. 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.
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(decimal min, decimal max) iv(min: float, max: float) ImpliedVolatility(decimal min, decimal max) implied_volatility(min: float, max: float) Selects a contract with implied volatility within the range you set. |
D(decimal min, decimal max) d(min: float, max: float) Delta(decimal min, decimal max) delta(min: float, max: float) Selects a contract with delta within the range you set. |
G(decimal min, decimal max) g(min: float, max: float) Gamma(decimal min, decimal max) gamma(min: float, max: float) Selects a contract with gamma within the range you set. |
R(decimal min, decimal max) r(min: float, max: float) Rho(decimal min, decimal max) rho(min: float, max: float) Selects a contract with rho within the range you set. |
V(decimal min, decimal max) v(min: float, max: float) Vega(decimal min, decimal max) vega(min: float, max: float) Selects a contract with vega within the range you set. |
T(decimal min, decimal max) t(min: float, max: float) Theta(decimal min, decimal max) theta(min: float, max: float) Selects a contract with theta within the range you set. |
OI(long min, long max) oi(min: int, max: int) OpenInterest(decimal min, decimal max) 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.
// Example 1: Select the contracts with delta between 0.25 and 0.75 option.SetFilter(optionFilterUniverse => optionFilterUniverse.Delta(0.25m, 0.75m)); // Example 2: Select the contracts (including weeklys) that expire in the next 90 days with implied volatility below 20% option.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().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.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().IV(0, 20).Expiration(0, 30).IronCondor(30, 5, 10));
# 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.include_weeklys().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.include_weeklys().iv(0, 20).expiration(0, 30).iron_condor(30, 5, 10))
Filter by Other Contract Properties
To set a contract filter, in the Initialize
initialize
method, call the SetFilter
set_filter
method of the Option
object.
// Select contracts that have a strike price within 1 strike level above and below the underlying price option.SetFilter(minStrike: -1, maxStrike: 1); // Select contracts that expire within 30 days option.SetFilter(minExpiry: TimeSpan.FromDays(0), maxExpiry: TimeSpan.FromDays(30)); // Select contracts that have a strike price within 1 strike level and expire within 30 days option.SetFilter(minStrike: -1, maxStrike: 1, minExpiry: TimeSpan.FromDays(0), maxExpiry: TimeSpan.FromDays(30)); // Select call contracts option.SetFilter(optionFilterUniverse => optionFilterUniverse.CallsOnly());
# 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:
SetFilter(int minStrike, int maxStrike) 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 |
SetFilter(TimeSpan minExpiry, TimeSpan maxExpiry) set_filter(minExpiry: timedelta, maxExpiry: timedelta) Selects the contracts that expire within the range you set. This filter runs asynchronously by default. |
SetFilter(int minStrike, int maxStrike, TimeSpan minExpiry, TimeSpan maxExpiry) 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 by default. |
SetFilter(Func<OptionFilterUniverse, OptionFilterUniverse> universeFunc) set_filter(universeFunc: Callable[[OptionFilterUniverse], OptionFilterUniverse]) Selects the contracts that a function selects. |
The following table describes the filter methods of the OptionFilterUniverse
class:
Strikes(int minStrike, int maxStrike) strikes(min_strike: int, max_strike: int) Selects contracts that are within |
CallsOnly() calls_only() Selects call contracts. |
PutsOnly() puts_only() Selects put contracts. |
StandardsOnly() standards_only() Selects standard contracts. |
IncludeWeeklys() include_weeklys() Selects non-standard weeklys contracts. |
WeeklysOnly() weeklys_only() Selects weekly contracts. |
FrontMonth() front_month() Selects the front month contract. |
BackMonths() back_months() Selects the non-front month contracts. |
BackMonth() back_month() Selects the back month contracts. |
Expiration(int minExpiryDays, int maxExpiryDays) expiration(min_expiryDays: int, max_expiryDays: int) Selects contracts that expire within a range of dates relative to the current day. |
Contracts(IEnumerable<Symbol> contracts) contracts(contracts: List[Symbol]) Selects a list of contracts. |
Contracts(Func<IEnumerable<Symbol>, IEnumerable< Symbol>> contractSelector) 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.
// Example 1: Select the front month call contracts option.SetFilter(optionFilterUniverse => optionFilterUniverse.CallsOnly().FrontMonth()); // Example 2: Select the contracts (including weeklys) that expire in the next 90 days option.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().Strikes(-20, 20).Expiration(0, 90)); // Example 3: Select the contracts (including weeklys) that expire in the next 30 days that form an Iron Condor option.SetFilter(optionFilterUniverse => optionFilterUniverse.IncludeWeeklys().Strikes(-20, 20).Expiration(0, 30).IronCondor(30, 5, 10));
# 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.include_weeklys().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 type (exclude 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 OnData
on_data
method.
Historical Data
To get historical chains for an Index Option, see Historical Data.
Examples
The following examples demonstrate some common practices for requesting Index Options universe data.
Example 1: Selecting for 0DTE Contracts
0DTE Options are option contracts that expire on the same day they are traded. To create a universe with 0DTE options, call the SetFilter
or set_filter
method. In this example, we will select 0DTE contracts within 1 strike price level and a Delta between 0.25 and 0.75. Then, we will go long on the highest strike price call contract of the SPX index and hold until expiry.
public class BasicIndexOptionAlgorithm : QCAlgorithm { private Option _option; public override void Initialize() { SetStartDate(2023, 1, 1); SetEndDate(2024, 1, 1); SetCash(100000); // Subscribe to the option chain. _option = AddIndexOption("SPX", "SPXW"); // Filter the option universe to only select 0DTE options. _option.SetFilter(u => u.IncludeWeeklys().Expiration(0, 0).Strikes(-1, 1)); // Filter the option universe by Delta. The last SetFilter call prevails. // _option.SetFilter(optionFilterUniverse => optionFilterUniverse.Delta(0.25m, 0.75m)); } public override void OnData(Slice slice) { // Get the option chain data. if (Portfolio.Invested || !slice.OptionChains.TryGetValue(_option.Symbol, out var chain)) { return; } // Sorted the call Option contracts according to their strike prices. var call = chain.Where(contract => contract.Right == OptionRight.Call).OrderBy(x => x.Strike).FirstOrDefault(); if (call == null) return; // Buy 1 0DTE call option contract for the SPX index. Buy(call.Symbol, 1); } }
class BasicIndexOptionAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2023,1,1) self.set_end_date(2024,1,1) self.set_cash(100_000) # Subscribe to the option chain. self._option = self.add_index_option("SPX", "SPXW") # Filter the option universe to only select 0DTE options. self._option.set_filter(lambda u: u.include_weeklys().expiration(0, 0).strikes(-1, 1)) # Filter the option universe by Delta. The last set_filter call prevails. # self._option.set_filter(lambda option_filter_universe: option_filter_universe.delta(0.25, 0.75)) def on_data(self, slice: Slice) -> None: if self.portfolio.invested: return # Get the option chain data. chain = slice.option_chains.get(self._option.symbol) if not chain: return # Sorted the call Option contracts according to their strike prices. calls = sorted([contract for contract in chain if contract.right == OptionRight.CALL], key=lambda x: x.strike) if not calls: return # Buy 1 0DTE call option contract for the SPX index. self.Buy(calls[0].symbol, 1)