合约详情
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)参数说明:
| 参数 | 含义 |
|---|---|
contract | ibapi.contract.Contract 对象,用来描述要查询的金融工具 |
timeout | 等待 contractDetailsEnd() 的秒数 |
返回值是 ContractDetails 列表。股票等明确合约通常返回 1 条;期权、期货、模糊交易所或模糊到期日时,可能返回多条。
查询 AAPL 股票合约
Section titled “查询 AAPL 股票合约”from ibapi.contract import Contractfrom 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=TrueDETAIL_COUNT=1SYMBOL=AAPLCON_ID=265598SEC_TYPE=STKEXCHANGE=SMARTPRIMARY_EXCHANGE=NASDAQCURRENCY=USDLOCAL_SYMBOL=AAPLMIN_TICK=0.01TIME_ZONE_ID=US/EasternIS_CONNECTED_AFTER_STOP=False这说明 TWS 已经把 AAPL + STK + SMART + USD 解析成了一个明确的美国股票合约。
Contract 输入字段
Section titled “Contract 输入字段”新手最容易卡在 Contract 对象。下面是股票请求最常用的输入字段:
| 字段 | 中文含义 | 示例 | 说明 |
|---|---|---|---|
symbol | 标的代码 | AAPL | 股票代码、期货代码或期权底层代码 |
secType | 证券类型 | STK | 股票是 STK,期权是 OPT,期货是 FUT |
exchange | 路由交易所 | SMART | 股票通常用 SMART,也可以指定具体交易所 |
currency | 计价币种 | USD | 美股通常是 USD |
primaryExchange | 主交易所 | NASDAQ | 用来消除同代码多市场歧义,查询时可选,下单时常有帮助 |
conId | IBKR 合约 ID | 265598 | 最准确的合约标识;拿到后可直接复用 |
学习阶段可以先用 symbol + secType + exchange + currency 查询;正式系统里建议保存 conId、primaryExchange、localSymbol 等字段,后面的请求更稳定。
ContractDetails 返回字段
Section titled “ContractDetails 返回字段”ContractDetails 是比 Contract 更完整的说明。常用字段包括:
| 字段 | 中文含义 | 用途 |
|---|---|---|
contract | 完整合约对象 | 行情、历史数据、下单可直接使用 |
minTick | 最小价格跳动 | 价格校验、限价单价格四舍五入 |
timeZoneId | 交易所时区 | 历史数据时间处理、交易时段判断 |
tradingHours | 可交易时段 | 判断常规和扩展交易时间 |
liquidHours | 高流动性时段 | 判断更接近常规交易的时段 |
longName | 合约全名 | UI 展示或日志 |
marketName | 市场名称 | 辅助识别合约 |
validExchanges | 可用交易所列表 | 判断是否可走某个交易所或路由 |
不要只用 symbol 做程序里的唯一标识。不同市场可能存在相同代码,期权和期货还会有到期日、行权价、乘数等额外维度。
多结果怎么处理
Section titled “多结果怎么处理”如果返回多条 ContractDetails,说明输入条件不够精确。常见原因:
- 只填了
symbol,没有填secType。 - 股票没有指定
currency或primaryExchange。 - 期货没有指定
lastTradeDateOrContractMonth。 - 期权没有指定到期日、行权价、方向或交易所。
处理方式是先打印返回列表里的 conId、symbol、secType、exchange、primaryExchange、currency、localSymbol,确认真正要交易的合约,再把关键字段补回查询条件。
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| 返回空列表 | 合约字段不完整或写错 | 先用股票最小示例验证连接,再逐步增加字段 |
| 返回多条 | 合约有歧义 | 补充 primaryExchange、到期日、行权价或 conId |
| 下单时报合约错误 | 查询合约和下单合约不是同一个对象 | 下单时尽量复用查询到的 details[0].contract |
| 价格被拒绝 | 限价不符合最小跳动价位 | 使用 minTick 校验价格 |
| 时间段判断混乱 | 忽略交易所时区 | 使用 timeZoneId 和交易所日历处理时间 |