IBKR API调用qualifyContracts报错:未找到期权合约定义求助
IBKR API
qualifyContracts 报错 "No security definition has been found" 解决方法 问题详情
调用qualifyContracts时遇到大量合约未找到的错误,错误信息如下:
Error 200, reqId 308: No security definition has been found for the request, contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=808.33, right='C', exchange='CBOE', currency='USD') Error 200, reqId 309: No security definition has been found for the request, contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=816.67, right='C', exchange='CBOE', currency='USD') Error 200, reqId 310: No security definition has been found for the request, contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=825.0, right='C', exchange='CBOE', currency='USD') Unknown contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=1.67, right='C', exchange='CBOE', currency='USD') Unknown contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=3.33, right='C', exchange='CBOE', currency='USD') Unknown contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=5.0, right='C', exchange='CBOE', currency='USD') Unknown contract: Option(symbol='TSLA', lastTradeDateOrContractMonth='20230303', strike=6.67, right='C', exchange='CBOE', currency='USD')
对应的代码:
from ib_insync import * from random import getrandbits if __name__ == '__main__': ib = IB() client_id = getrandbits(5) print('Connecting with the CLIENT ID = ', client_id) PORT = 4002 ib.connect('127.0.0.1', PORT, clientId=client_id) # contract = Contract(conId=76792991, exchange='SMART',currency='USD') contract = Stock('TSLA', 'SMART', 'USD') print('Setting Market Data Type') ib.reqMarketDataType(3) print('1') ib.qualifyContracts(contract) print('CON ID = ', contract.conId) chains = ib.reqSecDefOptParams(contract.symbol, '', contract.secType, contract.conId) cboe_chains = [c for c in chains if c.exchange == 'CBOE'] # # print(cboe_chains) # contracts = [Option(cboe_chains[0].underlyingConId, c.symbol, c.secType, c.exchange, c.currency, c.strike, c.right, # c.lastTradeDateOrContractMonth) for c in cboe_chains] opts = [] for chain in cboe_chains: print(chain) for strike in chain.strikes: print(strike) option = Option(symbol=chain.tradingClass, lastTradeDateOrContractMonth=chain.expirations[0], strike=strike, exchange='CBOE', currency='USD', right='C') opts.append(option) # # qualified_contract = ib.qualifyContracts(option) # print(qualified_contract) # print('-----------------------------------') print(opts) qualified_contract = ib.qualifyContracts(*opts) # Error comes here
错误原因
- 行权价范围无效:
reqSecDefOptParams返回的行权价包含大量不符合实际的极值(比如1.67、800+),这些合约在CBOE根本不存在。 - 交易所选择限制:强制指定CBOE交易所,部分合约可能仅在其他交易所上市。
- 批量请求无过滤:一次性请求所有行权价的合约,包含大量无效合约触发报错。
解决方法
1. 过滤无效行权价
根据标的当前价格,过滤掉超出合理范围的行权价(比如当前价格的±50%),只请求存在的合约。
2. 选择SMART交易所
使用SMART交易所让IB自动路由到有该合约的交易所,比指定单一交易所成功率更高。
3. 分批验证合约
批量请求前先测试少量合约,确认构造方式正确,避免一次性大量错误请求。
修改后的代码示例
from ib_insync import * from random import getrandbits if __name__ == '__main__': ib = IB() client_id = getrandbits(5) print('Connecting with the CLIENT ID = ', client_id) PORT = 4002 ib.connect('127.0.0.1', PORT, clientId=client_id) contract = Stock('TSLA', 'SMART', 'USD') ib.reqMarketDataType(3) ib.qualifyContracts(contract) print('CON ID = ', contract.conId) # 获取标的当前价格,用于过滤行权价 ticker = ib.reqMktData(contract, '', False, False) ib.sleep(2) # 等待IB返回市场数据 current_price = ticker.last if ticker.last else ticker.close print(f"当前TSLA价格: {current_price}") chains = ib.reqSecDefOptParams(contract.symbol, '', contract.secType, contract.conId) # 包含SMART和CBOE交易所的期权链 valid_chains = [c for c in chains if c.exchange in ['CBOE', 'SMART']] opts = [] for chain in valid_chains: # 过滤行权价范围:当前价格的50%到150% min_strike = current_price * 0.5 max_strike = current_price * 1.5 valid_strikes = [s for s in chain.strikes if min_strike <= s <= max_strike] for strike in valid_strikes: # 构造期权合约,使用SMART交易所 option = Option( symbol=contract.symbol, lastTradeDateOrContractMonth=chain.expirations[0], strike=strike, right='C', exchange='SMART', currency='USD' ) opts.append(option) if opts: # 先测试前5个合约,验证构造正确性 test_qualified = ib.qualifyContracts(*opts[:5]) print(f"测试合格合约: {test_qualified}") # 批量处理所有有效合约 qualified_contracts = ib.qualifyContracts(*opts) print(f"总共合格合约数量: {len(qualified_contracts)}") ib.disconnect()
关键点说明
- 等待市场数据:调用
reqMktData后需用ib.sleep()等待数据返回,确保当前价格有效。 - 灵活选择交易所:SMART交易所会自动匹配有该合约的交易所,减少合约未找到的概率。
- 过滤逻辑可调整:行权价范围可根据需求修改,比如扩大到±100%覆盖更多虚值/实值期权。
内容的提问来源于stack exchange,提问作者Volatil3
相关产品推荐
相关产品推荐

