Universes

Equity Options

Introduction

An Equity Options universe lets you select a basket of contracts for a single Option. LEAN models Option subscriptions as a universe of Option contracts.

Create Universes

To add a universe of Equity Option contracts, in the Initializeinitialize method, call the AddOptionadd_option method. This method returns an Option object, which contains the canonical Symbolsymbol. You can't trade with the canonical Option Symbolsymbol, but save a reference to it so you can easily access the Option contracts in the OptionChain that LEAN passes to the OnDataon_data method.

UniverseSettings.Asynchronous = true;
var option = AddOption("SPY");
_symbol = option.Symbol;
self.universe_settings.asynchronous = True
option = self.add_option("SPY")
self._symbol = option.symbol

The following table describes the AddOptionadd_option method arguments:

ArgumentData TypeDescriptionDefault Value
tickerstringstrThe underlying Equity ticker. To view the supported underlying Equity tickers, see Supported Assets.
resolutionResolution?Resolution/NoneTypeThe resolution of the market data. To view the supported resolutions, see Resolutions. The Equity resolution must be less than or equal to the Equity Option resolution. For example, if you set the Equity resolution to minute, then you must set the Equity Option resolution to minute, hour, or daily.Nonenull
marketstringstrThe underlying Equity market.Nonenull
fillForwardfill_forwardboolIf true, the current slice contains the last available data even if there is no data at the current time.Truetrue
leveragedecimalfloatThe leverage for this Equity.Security.NullLeverageSecurity.NULL_LEVERAGE
extendedMarketHoursextended_market_hoursboolA flag that signals if LEAN should send data during pre- and post-market trading hours.Falsefalse

If you add an Equity Option universe but don't have a subscription to the underlying Equity, LEAN automatically subscribes to the underlying Equity with the following settings:

SettingValue
Fill forwardSame as the Option universe
Leverage0
Extended Market HoursSame as the Option universe
Data NormalizationDataNormalizationMode.RawDataNormalizationMode.RAW

If you already have a subscription to the underlying Equity but it's not RawRAW data normalization, LEAN automatically changes it to RawRAW.

To override the default pricing model of the Option, set a pricing model.

option.price_model = OptionPriceModels.crank_nicolson_fd();
option.price_model = OptionPriceModels.crank_nicolson_fd()

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

Filter Contracts

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 OnDataon_data method.

To set a contract filter, in the Initializeinitialize method, call the SetFilterset_filter method of the Option object. The following table describes the available filter techniques:

Method
Description
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 minStrikem_strike to -1 and maxStrikemax_strike to 1, LEAN selects the contracts that have a strike of $300 or $305. This filter runs asynchronously by default.
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.
// 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 filter methods of the OptionFilterUniverse class:

MethodDescription
Strikes(int minStrike, int maxStrike)strikes(min_strike: int, max_strike: int)Selects contracts that are within minStrikem_strike strikes below the underlying price and maxStrikemax_strike strikes above the underlying price.
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(TimeSpan minExpiry, TimeSpan maxExpiry)expiration(min_expiry: timedelta, max_expiry: timedelta)Selects contracts that expire within a range of dates relative to the current day.
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.
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.
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))

# Example 3: 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))

To perform thorough filtering on the OptionFilterUniverse, define an isolated filter method.

// In Initialize
option.SetFilter(Selector);
    
private OptionFilterUniverse Selector(OptionFilterUniverse optionFilterUniverse)
{
    var symbols = optionFilterUniverse.PutsOnly();
    var strike = symbols.Select(symbol => symbol.ID.StrikePrice).Min();
    symbols = symbols.Where(symbol => symbol.ID.StrikePrice == strike);
    return optionFilterUniverse.Contracts(symbols);
}
# In initialize
option.set_filter(self._contract_selector)
    
def _contract_selector(self, option_filter_universe: OptionFilterUniverse) -> OptionFilterUniverse:
    symbols = option_filter_universe.puts_only()
    strike = min([symbol.id.strike_price for symbol in symbols])
    symbols = [symbol for symbol in symbols if symbol.id.strike_price == strike]
    return option_filter_universe.contracts(symbols)

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.

Navigate Option Chains

OptionChain objects represent an entire chain of Option contracts for a single underlying security. They have the following properties:

To get the OptionChain, index the OptionChainsoption_chains property of the Slice with the canonical Symbolsymbol. After you get the OptionChain, you can sort and filter the Option contracts in the chain.

public override void OnData(Slice slice)
{
    if (slice.OptionChains.TryGetValue(_symbol, out var chain))
    {
        // Example: Find 5 put contracts that are closest to at-the-money (ATM) and have the farthest expiration
        var contracts = chain
            .Where(x => x.Right == OptionRight.Put)
            .OrderByDescending(x => x.Expiry)
            .ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))
            .Take(5);

        // Select the contract with the delta closest to -0.5
        var contract = contracts.OrderBy(x => Math.Abs(-0.5m - x.Greeks.Delta)).FirstOrDefault();
    }
}
def on_data(self, slice: Slice) -> None:
    chain = slice.option_chains.get(self._symbol)
    if chain:
        # Example: Find 5 put contracts that are closest to at-the-money (ATM) and have the farthest expiration
        contracts = [x for x in chain if x.right == OptionRight.PUT]
        contracts = sorted(sorted(contracts, \
            key = lambda x: abs(chain.underlying.price - x.strike)), \
            key = lambda x: x.expiry, reverse=True)[:5]
    
        # Select the contract with the delta closest to -0.5
        contract = sorted(contracts, key=lambda x: abs(-0.5 - x.greeks.delta))[0]

You can also loop through the OptionChainsoption_chains property to get each OptionChain.

public override void OnData(Slice slice)
{
    foreach (var kvp in slice.OptionChains)
    {
        var canoncialSymbol = kvp.Key;
        var chain = kvp.Value;
        var contracts = chain.Contracts;
    }
}
def on_data(self, slice: Slice) -> None:
    for canonical_symbol, chain in slice.option_chains.items():
        contracts = chain.contracts

Selection Frequency

By default, Equity Option universes run at the first time step of each day to select their contracts.

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: