Chains Entity#

Chains represents the complete option-chain snapshot returned by Strategy.get_chains(). It behaves like a mapping but adds convenience helpers so you can focus on trading logic instead of dictionary plumbing.

At a glance#

spy_chains = self.get_chains(Asset("SPY"))  # -> Chains

# Quick introspection
print(spy_chains)          # <Chains exchange=SMART multiplier=100 expirations=30 calls=5000 puts=5000>

# Basic data access -------------------------------------------------
expiries   = spy_chains.expirations()           # list[str] of CALL expirations
put_dates  = spy_chains.expirations("PUT")      # list[str] of PUT expirations
strikes_atm = spy_chains.strikes(expiries[0])   # strikes list for first expiry, CALL side by default

# Calculate an at-the-money strike
underlying_px = self.get_last_price("SPY")
atm = min(strikes_atm, key=lambda s: abs(s - underlying_px))

# Pick the matching PUT strike for a credit spread
put_strikes = spy_chains.strikes(expiries[0], "PUT")
otm_put = max(s for s in put_strikes if s < underlying_px)

# Build an Asset object
contract = Asset(
    symbol="SPY",
    asset_type=Asset.AssetType.OPTION,
    expiration=expiries[0],
    strike=otm_put,
    right=Asset.OptionRight.PUT,
)

Design notes#

  • Chains inherits from dict so any existing code that used the raw mapping (chains["Chains"]["PUT"] …) keeps working.

  • All helper methods return lightweight Python types – no Pandas dependency.

  • Attribute summary:

    Chains attributes#

    Property

    Description

    calls

    Mapping {expiry: [strike, …]} for call contracts.

    puts

    Mapping {expiry: [strike, …]} for put contracts.

    multiplier

    Contract multiplier supplied by the data source (typically 100).

    exchange

    Primary routing exchange reported in the option chain payload.

API reference#

class lumibot.entities.chains.Chains(data: Dict[str, Any])#

Bases: dict

Dictionary-like container for option chains.

Behaves exactly like the raw dict previously returned by get_chains but also exposes convenience helpers and rich repr. Because it subclasses dict the old code paths that index into the structure (e.g. chains["Chains"]["PUT"] or chains.get("Chains")) continue to work unchanged.

calls() Dict[str, List[float]]#

Return the CALL side of the chain {expiration (YYYY-MM-DD): [strikes]}

expirations(option_type: str = 'CALL') List[str]#

List available expiration strings (YYYY-MM-DD) for the specified option type.

expirations_as_dates(option_type: str = 'CALL') List[date]#

List expiration dates for internal use.

get_option_chain_by_date(expiry_date: date, option_type: str = 'CALL') List[float]#

Get strikes for a date object (internal helper).

puts() Dict[str, List[float]]#

Return the PUT side of the chain {expiration (YYYY-MM-DD): [strikes]}

strikes(expiration: str | date | datetime, option_type: str = 'CALL') List[float]#

Return the strikes list for a given expiration (accepts string YYYY-MM-DD or date).

to_dict() Dict[str, Any]#

Return a shallow copy of the underlying dict.