[Python] currentPrice doesn't return values for SPY but does for AAPL

Discussão em 'Python' iniciado por Stack, Fevereiro 8, 2025.

  1. Stack

    Stack Membro Participativo

    I am writing a python script to various information off of yfinance. When I pull option chain info for individual stocks using the code, it works. When trying SPY as the ticker, it breaks.

    The stock.info 'currentPrice' seems to be breaking for SPY (and other ETFs as well). I have looked into documentation but I cannot find anything that shows that SPY or other ETFs have a different nomenclature for current price.

    import yfinance as yf
    import pandas as pd

    def get_option_chain(ticker, date=None):
    """
    Fetch option chain data for a specific security from Yahoo Finance

    Parameters:
    ticker (str): Stock ticker symbol (e.g., 'AAPL', 'MSFT')
    date (str): Optional expiration date in 'YYYY-MM-DD' format

    Returns:
    tuple: (calls_df, puts_df) DataFrames containing calls and puts data
    """
    try:
    # Create ticker object
    stock = yf.Ticker(ticker)

    # Get option chain
    if date:
    opt = stock.option_chain(date)
    else:
    # Get the first available expiration date if none specified
    expirations = stock.options
    if not expirations:
    raise ValueError(f"No options available for {ticker}")
    opt = stock.option_chain(expirations[0])

    # Extract calls and puts
    calls = opt.calls
    puts = opt.puts

    # Add some useful calculated columns
    current_price = stock.info['currentPrice']
    calls['moneyness'] = (current_price / calls['strike']).round(3)
    puts['moneyness'] = (current_price / puts['strike']).round(3)

    # Format the output
    for df in [calls, puts]:
    df['impliedVolatility'] = (df['impliedVolatility'] * 100).round(2)
    df['lastPrice'] = df['lastPrice'].round(2)
    df['bid'] = df['bid'].round(2)
    df['ask'] = df['ask'].round(2)

    return calls, puts

    except Exception as e:
    print(f"Error fetching option chain: {str(e)}")
    return None, None

    def main():
    # Example usage
    ticker = 'SPY' # Change this to your desired ticker

    # Get all available expiration dates
    stock = yf.Ticker(ticker)
    expiration_dates = stock.options

    print(f"\nAvailable expiration dates for {ticker}:")
    for date in expiration_dates:
    print(date)

    # Loop through each expiration date and get the option chain
    all_calls = []
    all_puts = []
    for date in expiration_dates:
    calls, puts = get_option_chain(ticker, date)
    if calls is not None and puts is not None:
    calls['expirationDate'] = date # Add expiration date to calls DataFrame
    puts['expirationDate'] = date # Add expiration date to puts DataFrame
    all_calls.append(calls)
    all_puts.append(puts)

    # Concatenate all calls and puts DataFrames
    all_calls_df = pd.concat(all_calls, ignore_index=True)
    all_puts_df = pd.concat(all_puts, ignore_index=True)

    # Display some basic information or save to CSV
    print(f"\nAll Calls for {ticker}:")
    print(all_calls_df[['strike', 'lastPrice', 'bid', 'ask', 'volume', 'impliedVolatility', 'moneyness', 'expirationDate']].head())

    print(f"\nAll Puts for {ticker}:")
    print(all_puts_df[['strike', 'lastPrice', 'bid', 'ask', 'volume', 'impliedVolatility', 'moneyness', 'expirationDate']].head())

    # Optionally save to CSV
    all_calls_df.to_csv(f"{ticker}_all_calls.csv", index=False)
    all_puts_df.to_csv(f"{ticker}_all_puts.csv", index=False)

    if __name__ == "__main__":
    main()


    error message

    Continue reading...

Compartilhe esta Página