Skip to content

Options Chains

Fetching a Chain

chain = client.get_options_chain("AAPL", expiration="2026-04-17")

print(f"Symbol:     {chain.symbol}")
print(f"Expiration: {chain.expiration}")
print(f"Calls:      {len(chain.calls)}")
print(f"Puts:       {len(chain.puts)}")

Exploring Contracts

Each contract is an OptionContract dataclass with full Greeks:

for call in chain.calls:
    print(
        f"  {call.strike:>8.2f} call | "
        f"Mark: ${call.mark:.2f} | "
        f"IV: {call.iv:.0%} | "
        f"Delta: {call.delta:+.2f} | "
        f"Vol: {call.volume:,} | "
        f"OI: {call.open_interest:,}"
    )

Available Fields

Field Type Description
symbol str Underlying ticker
option_type str "call" or "put"
strike float Strike price
expiration str Expiration date (YYYY-MM-DD)
mark float Mid-market price
bid / ask float Bid and ask prices
iv float Implied volatility (decimal, e.g., 0.35 = 35%)
delta float Delta
gamma float Gamma
theta float Theta (daily decay)
vega float Vega
volume int Day's trading volume
open_interest int Open interest

Computed Properties

# Volume / Open Interest ratio — useful for unusual activity detection
print(f"Vol/OI: {call.vol_oi_ratio:.2f}")

# Cost per contract (mark × 100)
print(f"Cost: ${call.cost_per_contract:.2f}")

Index Options (SPX, NDX, VIX, RUT)

pyhood supports index options out of the box. Use the base index symbol — pyhood handles the API differences automatically.

Index options use different Robinhood API paths than equity options: instrument lookup goes through /indexes/ instead of /instruments/, chains return tradable_chain_ids (plural) instead of tradable_chain_id, and the chain_symbol sent to /options/instruments/ is a variant of the ticker (e.g. SPXW for SPX weekly options, NDXP for NDX).

You don't need to worry about any of this — just pass the base symbol:

# Index options work exactly like equity options
chain = client.get_options_chain("SPX", expiration="2026-04-17")
for call in chain.calls:
    print(f"  {call.strike} call | IV: {call.iv:.0%} | Delta: {call.delta:.2f}")

# Expirations
expirations = client.get_options_expirations("SPX")

# Order placement
order = client.buy_option(
    symbol="SPX", strike=5800.0, expiration="2026-04-17",
    option_type="call", quantity=1, price=42.50,
)

Supported index symbols: SPX, NDX, VIX, RUT, XSP

Index Symbol Chain Symbol (internal) Description
SPX SPXW S&P 500 Index (weekly)
NDX NDXP Nasdaq-100 Index
VIX VIXW CBOE Volatility Index (weekly)
RUT RUTW Russell 2000 Index (weekly)
XSP XSP Mini-SPX Index

Filtering by Type

# Calls only
chain = client.get_options_chain("AAPL", expiration="2026-04-17", option_type="call")

# Puts only
chain = client.get_options_chain("AAPL", expiration="2026-04-17", option_type="put")

Getting Available Expirations

expirations = client.get_options_expirations("AAPL")
print(expirations)
# ['2026-03-21', '2026-03-28', '2026-04-04', '2026-04-17', ...]

Trading Options in IRA Accounts

pyhood supports options trading in IRA accounts. Pass account_number to buy_option or sell_option:

order = client.buy_option(
    symbol="NKE", strike=55.0, expiration="2026-04-02",
    option_type="call", quantity=3, price=1.60,
    account_number="YOUR_IRA_ACCOUNT",
)

IRA accounts are limited to Level 2 options: long calls, long puts, covered calls, and cash-secured puts. Spreads and multi-leg strategies are not available. See Account docs for details.

Viewing Option Positions

Use get_option_positions() to get fully resolved option positions with live market data, P&L, and Greeks:

positions = client.get_option_positions()

for p in positions:
    print(
        f"{p.symbol} ${p.strike} {p.option_type} exp {p.expiration} | "
        f"qty: {p.quantity} | "
        f"cost: ${p.cost_basis:.0f} | "
        f"value: ${p.current_value:.0f} | "
        f"P&L: ${p.unrealized_pl:.2f} ({p.unrealized_pl_pct:+.1f}%) | "
        f"delta: {p.delta:.3f} | IV: {p.iv:.1%}"
    )

For IRA accounts, pass account_number:

positions = client.get_option_positions(account_number="YOUR_IRA_ACCOUNT")

OptionPosition Fields

Field Type Description
symbol str Underlying ticker
option_type str "call" or "put"
strike float Strike price
expiration str Expiration date (YYYY-MM-DD)
quantity int Number of contracts
average_open_price float Average entry price per share
cost_basis float Total cost basis
current_mark float Current mid-market price per share
current_value float Current total value (mark × qty × 100)
unrealized_pl float Unrealized P&L in dollars
unrealized_pl_pct float Unrealized P&L as percentage
strategy str Strategy type (e.g. "long_call")
delta float Position delta
iv float Implied volatility (decimal)
theta float Theta (daily decay)

Example: Find High Vol/OI Calls

chain = client.get_options_chain("AAPL", expiration="2026-04-17", option_type="call")

unusual = [c for c in chain.calls if c.vol_oi_ratio > 2.0 and c.open_interest > 500]

for c in sorted(unusual, key=lambda x: x.vol_oi_ratio, reverse=True):
    print(f"  {c.strike} call | Vol/OI: {c.vol_oi_ratio:.1f} | Vol: {c.volume:,} | OI: {c.open_interest:,}")