跳转到内容

接收合约详情

reqContractDetails() 发出请求后,TWS 会通过两个回调返回结果:

def contractDetails(self, reqId, contractDetails):
...
def contractDetailsEnd(self, reqId):
...

contractDetails() 可能触发一次,也可能触发多次。contractDetailsEnd(reqId) 表示这个请求编号的合约详情已经返回完毕。

字段中文含义说明
reqId请求编号和你调用 reqContractDetails(reqId, contract) 时传入的编号对应。
contractDetails.contract合约对象包含 conIdsymbolsecTypeexchange 等。
contractDetails.longName合约长名称例如 APPLE INC
contractDetails.marketName市场名称IBKR 返回的市场名。
contractDetails.minTick最小报价单位例如 0.01
contractDetails.validExchanges可用交易所逗号分隔的字符串。
contractDetails.marketRuleIds市场规则 ID和交易所列表通常按位置对应。
contractDetails.timeZoneId交易时区例如 US/Eastern
contractDetails.tradingHours交易时段字符串较长,适合单独解析。
contractDetails.liquidHours流动性较好的时段不等同于完整交易时间。

ContractDetails 字段很多,可以按用途理解。

这些字段大多在 contractDetails.contract 里:

字段中文含义
contract.conIdIBKR 合约 ID
contract.symbol标的代码
contract.secType证券类型
contract.exchange路由或交易所
contract.primaryExchange主要交易所
contract.currency币种
contract.localSymbol本地代码
contract.tradingClass交易类别
字段中文含义使用场景
minTick最小报价单位价格步长、报价显示、下单价格校验
validExchanges可用交易所选择路由或排查交易所问题
marketRuleIds市场规则 ID继续调用 reqMarketRule() 查价格增量规则
orderTypes支持的订单类型判断某合约能否使用某类订单
priceMagnifier价格放大系数某些衍生品或债券价格显示相关
minSize最小数量部分产品的数量限制
sizeIncrement数量增量部分产品的数量步长
suggestedSizeIncrement建议数量增量展示或默认下单数量时可参考
字段中文含义使用场景
timeZoneId交易所时区历史 K 线、交易时段解析
tradingHours交易时段判断完整可交易时间
liquidHours流动性较好的时段风控或展示参考
contractMonth合约月份期货、期权等衍生品
realExpirationDate真实到期日期权、期货等到期判断
lastTradeTime最后交易时间到期日附近交易逻辑
字段中文含义
longName合约长名称
industry行业
category类别
subcategory子类别
stockType股票类型
descAppend追加描述

这些字段常见于期权、期货期权、结构化产品等:

字段中文含义
underConId底层合约 ID
underSymbol底层标的代码
underSecType底层证券类型

新手调试时可以直接打印。正式程序里,更建议先转成字典,后面写日志、数据库或接口返回都更清楚。

def contractDetails(self, reqId, details):
contract = details.contract
row = {
"reqId": reqId,
"conId": contract.conId,
"symbol": contract.symbol,
"secType": contract.secType,
"exchange": contract.exchange,
"primaryExchange": contract.primaryExchange,
"currency": contract.currency,
"localSymbol": contract.localSymbol,
"tradingClass": contract.tradingClass,
"longName": details.longName,
"minTick": details.minTick,
"timeZoneId": details.timeZoneId,
"validExchanges": details.validExchanges,
"marketRuleIds": details.marketRuleIds,
}
self.rows.append(row)
CONNECTED=True
REQUEST_SENT=True
CONTRACT_DETAILS_END_RECEIVED=True
CONTRACT_DETAILS_ROW_COUNT=1
SEC_TYPE_COUNTS=STK:1
EXCHANGE_COUNTS=SMART:1
PRIMARY_EXCHANGE_COUNTS=NASDAQ:1
FIRST_CONID=265598
FIRST_SYMBOL=AAPL
FIRST_LOCAL_SYMBOL=AAPL
FIRST_TRADING_CLASS=NMS
FIRST_LONG_NAME=APPLE INC
FIRST_MIN_TICK=0.01
FIRST_TIME_ZONE_ID=US/Eastern
FIRST_MARKET_NAME=NMS
FIRST_VALID_EXCHANGES=SMART,AMEX,NYSE,CBOE,PHLX,ISE,CHX,ARCA,NASDAQ,DRCTEDGE,BEX,BATS,EDGEA,BYX,IEX,EDGX,FOXRIVER,PEARL,NYSENAT,LTSE,MEMX,IBEOS,OVERNIGHT,TPLUS0,PSX,T24X
INFO_CODES=2104,2106,2158
NON_INFO_ERROR_COUNT=0
IS_CONNECTED_AFTER_DISCONNECT=False

这里最值得保存的是:

字段为什么重要
conId=265598可以用它精确引用 AAPL 股票。
primaryExchange=NASDAQ帮助消除股票同代码歧义。
tradingClass=NMS交易类别,后面查期权链或交易规则时常见。
minTick=0.01下单价格需要符合最小价格单位。
timeZoneId=US/Eastern历史数据和交易时段要按交易所时区理解。

validExchangesmarketRuleIds 怎么对应?

Section titled “validExchanges 和 marketRuleIds 怎么对应?”

它们通常是两个逗号分隔的字符串,位置一一对应。比如第 1 个交易所对应第 1 个市场规则 ID。真正要查价格增量规则时,还需要继续调用 reqMarketRule()

可以展示给开发者看,但不建议直接当作最终风控判断。它是交易所时区下的复杂字符串,包含日期、开收盘时间、休市信息等,正式系统应单独解析。

正常请求结束时会来。程序不要只等第一条 contractDetails(),否则遇到多条结果时会提前结束。更稳的做法是:收集所有 contractDetails(),等 contractDetailsEnd() 后再统一处理。

能不能把 minTick 当成所有价格增量规则?

Section titled “能不能把 minTick 当成所有价格增量规则?”

不能。minTick 是基础最小报价单位。很多产品在不同价格区间有不同价格增量,应该再结合 marketRuleIdsreqMarketRule() 判断。