Skip to content

Options Data API Guide

The trade_calc library provides several functions to fetch options data using yfinance. These functions make it easy to retrieve expiration dates, options chains, and specific option prices.

Installation

The library already includes yfinance as a dependency:

uv sync

Available Functions

1. get_expiration_dates(ticker: str)

Quickly fetch available expiration dates for a ticker without pulling full options data.

Returns: List of expiration dates in 'YYYY-MM-DD' format, or None if unavailable.

Example:

from trade_calc import get_expiration_dates

# Get all available expiration dates
expirations = get_expiration_dates('AAPL')
print(f"Available expirations: {expirations}")
# Output: ['2024-12-20', '2024-12-27', '2025-01-03', ...]

2. get_options_chain(ticker: str, expiration_date: str)

Retrieve the complete options chain (all calls and puts) for a specific expiration date.

Returns: Dictionary with current price, calls list, and puts list, or None if unavailable.

Example:

from trade_calc import get_options_chain

# Get options chain for a specific expiration
chain = get_options_chain('AAPL', '2024-12-20')

print(f"Current price: ${chain['current_price']:.2f}")
print(f"Number of call strikes: {len(chain['calls'])}")
print(f"Number of put strikes: {len(chain['puts'])}")

# Access specific options
for call in chain['calls'][:5]:  # First 5 calls
    print(f"Strike: ${call['strike']}, Bid: ${call['bid']}, Ask: ${call['ask']}")

3. get_option_prices(ticker: str, expiration_date: str, strike: float, option_type: str = 'both')

Get pricing information for specific option(s) at a particular strike.

Parameters: - ticker: Stock ticker symbol - expiration_date: Expiration date in 'YYYY-MM-DD' format - strike: Strike price to look up - option_type: 'call', 'put', or 'both' (default: 'both')

Returns: Dictionary with call and/or put pricing information, or None if unavailable.

Example:

from trade_calc import get_option_prices

# Get both call and put prices at a specific strike
prices = get_option_prices('AAPL', '2024-12-20', 180.0)

print(f"Call mid price: ${prices['call']['mid']:.2f}")
print(f"Put mid price: ${prices['put']['mid']:.2f}")
print(f"Call IV: {prices['call']['implied_volatility']:.2%}")
print(f"Put IV: {prices['put']['implied_volatility']:.2%}")

# Get only call prices
call_only = get_option_prices('AAPL', '2024-12-20', 180.0, option_type='call')
print(f"Call bid: ${call_only['call']['bid']:.2f}")

4. fetch_options_data_yfinance(ticker: str)

Comprehensive function that fetches all options data for all expirations (existing function).

Returns: Dictionary with current price, all expiration dates, and complete options chains.

Example:

from trade_calc import fetch_options_data_yfinance

# Get all options data for a ticker
data = fetch_options_data_yfinance('AAPL')

print(f"Current price: ${data['current_price']:.2f}")
print(f"Expirations: {data['expirations']}")

# Access specific expiration
chain = data['options_chains']['2024-12-20']
print(f"Calls: {len(chain['calls'])} strikes")
print(f"Puts: {len(chain['puts'])} strikes")

Complete Example

Here's a complete example that demonstrates finding ATM options:

from trade_calc import get_expiration_dates, get_options_chain, get_option_prices

def find_atm_options(ticker: str):
    """Find at-the-money options for the nearest expiration."""

    # Step 1: Get expiration dates
    expirations = get_expiration_dates(ticker)
    if not expirations:
        print(f"No options available for {ticker}")
        return

    # Step 2: Get options chain for nearest expiration
    nearest_exp = expirations[0]
    chain = get_options_chain(ticker, nearest_exp)
    if not chain:
        print(f"Could not fetch options chain for {ticker}")
        return

    # Step 3: Find ATM strike
    current_price = chain['current_price']
    atm_strike = min(
        chain['calls'], 
        key=lambda x: abs(x['strike'] - current_price)
    )['strike']

    # Step 4: Get prices for ATM options
    prices = get_option_prices(ticker, nearest_exp, atm_strike)

    print(f"\n{ticker} ATM Options Analysis")
    print(f"{'=' * 50}")
    print(f"Current Price: ${current_price:.2f}")
    print(f"Expiration: {nearest_exp}")
    print(f"ATM Strike: ${atm_strike:.2f}")
    print(f"\nCall Option:")
    print(f"  Bid/Ask: ${prices['call']['bid']:.2f} / ${prices['call']['ask']:.2f}")
    print(f"  Mid: ${prices['call']['mid']:.2f}")
    print(f"  IV: {prices['call']['implied_volatility']:.2%}")
    print(f"\nPut Option:")
    print(f"  Bid/Ask: ${prices['put']['bid']:.2f} / ${prices['put']['ask']:.2f}")
    print(f"  Mid: ${prices['put']['mid']:.2f}")
    print(f"  IV: {prices['put']['implied_volatility']:.2%}")
    print(f"\nStraddle Price: ${prices['call']['mid'] + prices['put']['mid']:.2f}")

# Run the example
find_atm_options('AAPL')

Data Structure

Options Chain Structure

{
    'ticker': str,              # Ticker symbol (e.g., 'AAPL')
    'current_price': float,     # Current stock price
    'expiration_date': str,     # Expiration date 'YYYY-MM-DD'
    'calls': [                  # List of call options
        {
            'strike': float,
            'bid': float,
            'ask': float,
            'last': float,
            'implied_volatility': float,
            'volume': int,
            'open_interest': int,
        },
        ...
    ],
    'puts': [...]               # List of put options (same structure)
}

Option Prices Structure

{
    'ticker': str,
    'current_price': float,
    'expiration_date': str,
    'strike': float,
    'call': {                   # Only if option_type includes 'call'
        'bid': float,
        'ask': float,
        'last': float,
        'mid': float,           # Calculated as (bid + ask) / 2
        'implied_volatility': float
    },
    'put': {                    # Only if option_type includes 'put'
        'bid': float,
        'ask': float,
        'last': float,
        'mid': float,
        'implied_volatility': float
    }
}

Error Handling

All functions return None if: - The ticker is invalid - No options data is available - Network errors occur - The specified expiration date doesn't exist

Always check for None before accessing the returned data:

expirations = get_expiration_dates('INVALID')
if expirations is None:
    print("Could not fetch expiration dates")
else:
    print(f"Found {len(expirations)} expirations")

Performance Considerations

  • get_expiration_dates() is the fastest - only fetches expiration dates
  • get_options_chain() fetches one expiration - moderate speed
  • fetch_options_data_yfinance() fetches all expirations - slowest but most comprehensive
  • get_option_prices() uses get_options_chain() internally, so it fetches the full chain for that expiration

For best performance, use the most specific function for your needs.