跳转到内容

合约详情

get_contract_details() 用来把一个较粗略的合约描述,交给 TWS 解析成完整的合约详情。很多 API 请求都依赖准确的合约对象,例如行情、历史数据、下单和期权链。如果合约定义不清楚,后面的请求很容易返回空结果、歧义合约或合约不存在错误。

它对应原始 TWS API 的:

reqContractDetails(reqId, contract)
-> contractDetails(reqId, contractDetails)
-> contractDetailsEnd(reqId)

同步封装会等待 contractDetailsEnd(),然后返回 ContractDetails 对象列表。

本地官方源码中的定义如下:

def get_contract_details(self, contract, timeout=5):
req_id = self.get_next_valid_id()
self.reqContractDetails(req_id, contract)
return self._wait_for_response(req_id, "contract_details", timeout)

参数说明:

参数含义
contractibapi.contract.Contract 对象,用来描述要查询的金融工具
timeout等待 contractDetailsEnd() 的秒数

返回值是 ContractDetails 列表。股票等明确合约通常返回 1 条;期权、期货、模糊交易所或模糊到期日时,可能返回多条。

from ibapi.contract import Contract
from ibapi.sync_wrapper import TWSSyncWrapper, ResponseTimeout
def stock_contract(symbol: str, currency: str = "USD") -> Contract:
contract = Contract()
contract.symbol = symbol # 股票代码,例如 AAPL
contract.secType = "STK" # STK 表示股票
contract.exchange = "SMART" # SMART 表示使用 IBKR 智能路由
contract.currency = currency # 计价币种
return contract
app = TWSSyncWrapper(timeout=8)
try:
if not app.connect_and_start("127.0.0.1", 7497, 946):
raise RuntimeError("连接 TWS API 失败")
details = app.get_contract_details(stock_contract("AAPL"), timeout=8)
print(f"DETAIL_COUNT={len(details)}")
if details:
item = details[0]
contract = item.contract
print(f"SYMBOL={contract.symbol}")
print(f"CON_ID={contract.conId}")
print(f"SEC_TYPE={contract.secType}")
print(f"EXCHANGE={contract.exchange}")
print(f"PRIMARY_EXCHANGE={contract.primaryExchange}")
print(f"CURRENCY={contract.currency}")
print(f"LOCAL_SYMBOL={contract.localSymbol}")
print(f"MIN_TICK={item.minTick}")
print(f"TIME_ZONE_ID={item.timeZoneId}")
except ResponseTimeout:
print("已经发送合约详情请求,但没有在超时时间内收到 contractDetailsEnd 回调")
finally:
app.disconnect_and_stop()

使用 TWS 模拟账户、127.0.0.1:7497、独立 clientId 检查 AAPL 股票合约时,输出类似:

CONNECTED=True
DETAIL_COUNT=1
SYMBOL=AAPL
CON_ID=265598
SEC_TYPE=STK
EXCHANGE=SMART
PRIMARY_EXCHANGE=NASDAQ
CURRENCY=USD
LOCAL_SYMBOL=AAPL
MIN_TICK=0.01
TIME_ZONE_ID=US/Eastern
IS_CONNECTED_AFTER_STOP=False

这说明 TWS 已经把 AAPL + STK + SMART + USD 解析成了一个明确的美国股票合约。

新手最容易卡在 Contract 对象。下面是股票请求最常用的输入字段:

字段中文含义示例说明
symbol标的代码AAPL股票代码、期货代码或期权底层代码
secType证券类型STK股票是 STK,期权是 OPT,期货是 FUT
exchange路由交易所SMART股票通常用 SMART,也可以指定具体交易所
currency计价币种USD美股通常是 USD
primaryExchange主交易所NASDAQ用来消除同代码多市场歧义,查询时可选,下单时常有帮助
conIdIBKR 合约 ID265598最准确的合约标识;拿到后可直接复用

学习阶段可以先用 symbol + secType + exchange + currency 查询;正式系统里建议保存 conIdprimaryExchangelocalSymbol 等字段,后面的请求更稳定。

ContractDetails 是比 Contract 更完整的说明。常用字段包括:

字段中文含义用途
contract完整合约对象行情、历史数据、下单可直接使用
minTick最小价格跳动价格校验、限价单价格四舍五入
timeZoneId交易所时区历史数据时间处理、交易时段判断
tradingHours可交易时段判断常规和扩展交易时间
liquidHours高流动性时段判断更接近常规交易的时段
longName合约全名UI 展示或日志
marketName市场名称辅助识别合约
validExchanges可用交易所列表判断是否可走某个交易所或路由

不要只用 symbol 做程序里的唯一标识。不同市场可能存在相同代码,期权和期货还会有到期日、行权价、乘数等额外维度。

如果返回多条 ContractDetails,说明输入条件不够精确。常见原因:

  • 只填了 symbol,没有填 secType
  • 股票没有指定 currencyprimaryExchange
  • 期货没有指定 lastTradeDateOrContractMonth
  • 期权没有指定到期日、行权价、方向或交易所。

处理方式是先打印返回列表里的 conIdsymbolsecTypeexchangeprimaryExchangecurrencylocalSymbol,确认真正要交易的合约,再把关键字段补回查询条件。

现象常见原因处理方式
返回空列表合约字段不完整或写错先用股票最小示例验证连接,再逐步增加字段
返回多条合约有歧义补充 primaryExchange、到期日、行权价或 conId
下单时报合约错误查询合约和下单合约不是同一个对象下单时尽量复用查询到的 details[0].contract
价格被拒绝限价不符合最小跳动价位使用 minTick 校验价格
时间段判断混乱忽略交易所时区使用 timeZoneId 和交易所日历处理时间

IBKR Campus: TWS API Documentation