I’m trying to get an option open interest using ib_async, but it does not show the open interest at all.
The code I have using ib_async is:
from ib_async import *
ib = IB()
ib.connect('127.0.0.1', 4001, clientId=138)
ib.reqMarketDataType(1)
option1 = [Option('GOOGL', '20250117', 195, 'C', 'SMART')]
ib.qualifyContracts(option1[0])
a=ib.reqMktData(option1[0],genericTickList='100',snapshot=False, regulatorySnapshot=False)
print(a)
print("-")
b=ib.reqTickers(Option('GOOGL', '20250117', 195, 'C', 'SMART'))
print("Volume ", b[0].volume)
print("callOpenInterest ", b[0].callOpenInterest)
print("putOpenInterest", b[0].putOpenInterest)
print("impliedVolatility ", b[0].impliedVolatility)
ib.disconnect()
the output of this code is
Ticker(contract=Option(conId=584786601, symbol='GOOGL', lastTradeDateOrContractMonth='20250117', strike=195.0, right='C', multiplier='100', exchange='SMART', currency='USD', localSymbol='GOOGL 250117C00195000', tradingClass='GOOGL'))
-
Volume 1385.0
callOpenInterest nan
putOpenInterest nan
impliedVolatility nan
which means that open interest is missing. Using the IBKR TWS API I can get the open interest but the way to there is a bit less user friendly
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum
import threading
import time
class IBApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.call_open_interest = None
self.reqId = 1
self.oi_received = False # Flag to track if tick 27 was received
def error(self, reqId, errorCode, errorString, advancedOrderRejectJson=''):
print(f"Error. Id: {reqId}, Code: {errorCode}, Msg: {errorString}")
def tickSize(self, reqId: int, tickType: int, size: float):
if tickType == TickTypeEnum.OPTION_CALL_OPEN_INTEREST:
self.call_open_interest = size
self.oi_received = True #set flag to true
print(f"TickSize. TickerId:", reqId, "TickType:", tickType, "Size: ", size)
else:
print("Not the expected tick type")
def tickSnapshotEnd(self, reqId):
print(f"TickSnapshotEnd. Ticker Id: {reqId}")
def run_loop(app):
app.run()
if __name__ == "__main__":
app = IBApp()
app.connect("127.0.0.1", 4001, clientId=20)
api_thread = threading.Thread(target=run_loop, args=(app,), daemon=True)
api_thread.start()
time.sleep(1)
contract = Contract()
contract.symbol = "GOOGL"
contract.secType = "OPT"
contract.exchange = "SMART"
contract.currency = "USD"
contract.lastTradeDateOrContractMonth = "20250117"
contract.strike = 195
contract.right = "C"
contract.multiplier = "100"
app.reqMktData(app.reqId, contract, genericTickList='101', snapshot=False, regulatorySnapshot=False, mktDataOptions=[]) #request tick 27
time.sleep(5) # Wait for a reasonable time for data
if app.oi_received: #check flag
print(f"Option Call Open Interest Size: {app.call_open_interest}")
else:
print("Did not receive Option Call Open Interest data within the timeout.")
app.disconnect()
The output of this code is
Error. Id: -1, Code: 2104, Msg: Market data farm connection is OK:usfarm.nj
Error. Id: -1, Code: 2104, Msg: Market data farm connection is OK:usopt
Error. Id: -1, Code: 2104, Msg: Market data farm connection is OK:usfarm
Error. Id: -1, Code: 2107, Msg: HMDS data farm connection is inactive but should be available upon demand.ushmds
Error. Id: -1, Code: 2158, Msg: Sec-def data farm connection is OK:secdefnj
Not the expected tick type
Not the expected tick type
Not the expected tick type
Not the expected tick type
Not the expected tick type
Not the expected tick type
Not the expected tick type
TickSize. TickerId: 1 TickType: 27 Size: 21890
Not the expected tick type
Option Call Open Interest Size: 21890
Does anyone use ib_async to get the option open interest and if so could you please share the way to request this data?