[Python] impliedVolatility always nan in IBKR API

Discussão em 'Python' iniciado por Stack, Março 15, 2025.

  1. Stack

    Stack Membro Participativo

    I am currently trying to pull implied volatility data for a list of stocks via the IBKR API using the ib_async (formerly ib_insync) python library. Problem is that no matter what I try, the values for implied volatility always remain nan while they can be received within the TWS itself. I am subscribed to live data incl. options data.

    I tried two ways for requesting ticker data:

    1. Requesting data only once via ib.reqTickers function:

    from ib_async import * #importing the ib_async classes and functions
    import pandas as pd

    ib = IB()
    #use this for TWS
    ib.connect('127.0.0.1', 7497, clientId=1, readonly=True)

    # Set market data type to delayed data
    ib.reqMarketDataType(1) # 3 = delayed data

    #Define simple collection of test symbols
    symbols = ['GME', 'AAPL', 'RIVN']

    contracts = []
    contractdata = []

    for symbol in symbols:
    contract = Stock(symbol, 'SMART', 'USD')
    contracts.append(contract)

    # Qualify contracts and fetch market data once
    contracts = ib.qualifyContracts(*contracts)
    tickers = ib.reqTickers(*contracts)

    for t in tickers:
    try:
    # Store Tick data
    data = {
    "Symbol": t.contract.symbol,
    "Last": t.last,
    "Volume": t.volume,
    "Implied Volatility": t.impliedVolatility,
    }
    contractdata.append(data)
    except Exception:
    pass # Skip any invalid data

    # Convert Data into Pandas DataFrames
    data_df = pd.DataFrame(contractdata)

    print(data_df)

    ib.disconnect()


    returns:

    Symbol Last Volume Implied Volatility
    0 GME 22.94 20481.0 NaN
    1 AAPL 212.65 270901.0 NaN
    2 RIVN 10.64 94368.0 NaN

    1. Requesting a live feed of ticker data via ib.reqMktData

    from ib_async import *

    ib = IB()
    #use this for TWS
    ib.connect('127.0.0.1', 7497, clientId=1, readonly=True)

    ib.reqMarketDataType(1)

    #Define simple collection of test symbols
    symbols = ['GME', 'AAPL', 'RIVN']

    #Subscribe to live data for a list of symbols
    for symbol in symbols:
    contract = Stock(symbol, 'SMART', 'USD')
    ib.reqMktData(contract, '', False, False)

    def onPendingTickers(tickers):
    print('pending tickers event received')
    for t in tickers:
    print(t.contract.symbol, t.last, t.volume, t.impliedVolatility)

    #Event Subscription: The pendingTickersEvent is an event that gets triggered when there are new tickers data available.
    ib.pendingTickersEvent += onPendingTickers
    ib.sleep(30)
    #Event Unsubscription
    ib.pendingTickersEvent -= onPendingTickers

    ib.disconnect()


    returns

    GME 22.89 20182.0 nan
    pending tickers event received
    AAPL 212.61 262905.0 nan
    pending tickers event received
    AAPL 212.61 262905.0 nan
    pending tickers event received
    RIVN 10.65 91547.0 nan
    [...]


    As it can be seen, for both methods, impliedVolatility is always returned nan, even for very long subscription durations for the live feed (tried till duration 1800s with same result). The only hints I found focused on the fact, that not every ticker is filled instantly so one must sometimes just wait long enough. However, via subscribing to the the live data feed and updating on every ticker event, this should be covered as a potential cause?

    Thanks for any hint what I might miss here!

    Continue reading...

Compartilhe esta Página