跳转到内容

Contract 对象

Contract 的作用,是告诉 TWS / IB Gateway:你要查询或交易的到底是哪一个金融工具。

只写 AAPL 这个字符串不够。IBKR API 需要更完整的描述,例如“这是美国股票、用美元计价、通过 SMART 路由”。后面的行情、历史 K 线、合约详情、下单、成交过滤,都会反复用到这个对象。

from ibapi.contract import Contract
contract = Contract()
contract.symbol = "AAPL" # 标的代码:苹果公司
contract.secType = "STK" # 证券类型:股票
contract.exchange = "SMART" # 路由:交给 IBKR 智能路由
contract.currency = "USD" # 币种:美元

翻译成人话就是:

我要找 AAPL 这只美股,产品类型是股票,通过 SMART 智能路由,计价币种是 USD。

如果 Contract 写错,后面不是没有返回,就是返回多条歧义结果,严重时可能查错标的或下到错误标的。

要做什么常用接口为什么需要 Contract
查合约详情reqContractDetails()确认合约是否能唯一定位,并拿到 conId 等精确字段
查实时行情reqMktData()告诉 TWS 要订阅哪个标的
拉历史 K 线reqHistoricalData()告诉 TWS 要拉哪个标的的历史数据
下单placeOrder()告诉 TWS 要交易哪个标的
查成交reqExecutions()可以按合约过滤成交记录
查期权链reqSecDefOptParams()先确定底层合约,再查可用到期日和行权价

学习阶段可以先写最少字段。正式系统里,更稳的做法是先用 reqContractDetails() 查一次,保存 TWS 返回的 conIdprimaryExchangelocalSymboltradingClass 等字段。

Python API 的 Contract 对象常见字段如下。不是每种产品都要填满,重点是按产品类型填对关键字段。

字段中文含义常见示例说明
conIdIBKR 合约 ID265598最精确的合约标识。已知 conId 时,可以减少代码歧义。
symbol标的代码AAPLEURES股票代码、外汇基础货币、期货根代码、期权底层代码等。
secType证券类型STKOPTFUTCASH决定这是什么产品。写错后,行情、历史数据和下单等接口通常无法返回正确结果。
lastTradeDateOrContractMonth到期日或合约月份20260619202606期权、期货、期货期权常用。股票和外汇通常不填。
lastTradeDate最后交易日20260619API 对象中存在的字段,实际开发更常用 lastTradeDateOrContractMonth
strike行权价200期权必填字段之一。
right看涨/看跌CPC 表示 Call,看涨;P 表示 Put,看跌。
multiplier合约乘数10050美股期权常见 100,期货和指数期权要以合约详情返回为准。
exchange交易所或路由SMARTIDEALPROGLOBEX股票常用 SMART,外汇常用 IDEALPRO,期货常用具体交易所。
primaryExchange主要交易所NASDAQNYSE用来消除同代码歧义;不要写成 SMART
currency计价币种USDHKDEUR美股通常是 USD,港股通常是 HKD
localSymbol本地代码AAPLESM6TWS 或交易所使用的本地显示代码,合约详情里常见。
tradingClass交易类别NMSSPXES股票、期权、期货合约详情和交易规则里常见。
includeExpired是否包含已过期合约True / False查询历史期货合约时可能用到;不能用来交易过期合约。
secIdType证券 ID 类型ISINCUSIPSEDOLRIC用外部证券编码定位合约时使用。
secId证券 ID 值US0378331005secIdType 配合使用,例如 AAPL 的 ISIN。
description合约描述APPLE INC描述性字段,通常来自返回结果,不作为主要定位条件。
issuerId发行人 ID返回值为准部分产品或数据接口可能返回,普通入门开发很少手写。
comboLegsDescrip组合腿描述返回值为准组合订单相关。一般由 TWS 返回或由组合腿构造推导。
comboLegs组合腿列表ComboLeg 列表组合合约使用,例如期权价差、股票组合。
deltaNeutralContractDelta Neutral 合约DeltaNeutralContract高级期权/Delta Neutral 策略使用。

最常用的字段组合是:

symbol + secType + exchange + currency

最可靠的字段是:

conId

conId 不建议靠猜。应该通过合约详情或合约搜索接口拿到。

secType 是最容易写错、也最影响返回结果的字段。

secType中文含义常见用途
STK股票美股、港股等股票
OPT股票或指数期权AAPL 期权、SPX 期权等
FUT期货ES、NQ、CL 等期货
FOP期货期权期货合约上的期权
CASH外汇EUR.USD、USD.JPY
IND指数SPX、VIX 等指数
CFD差价合约CFD 产品,是否可用取决于账户和地区
BAG组合合约组合订单、价差交易
BOND债券债券合约
FUND基金共同基金等

美股股票的学习示例通常这样写:

from ibapi.contract import Contract
def stock_contract(symbol: str, currency: str = "USD") -> Contract:
contract = Contract()
contract.symbol = symbol # 股票代码,例如 AAPL
contract.secType = "STK" # STK 表示股票
contract.exchange = "SMART" # 美股常用 SMART 智能路由
contract.currency = currency # 美股通常是 USD
return contract
aapl = stock_contract("AAPL")

如果遇到同代码歧义,可以补主要交易所:

aapl.primaryExchange = "NASDAQ" # AAPL 的主要挂牌交易所

exchangeprimaryExchange 不一样:

字段作用
exchange="SMART"告诉 IBKR 用智能路由执行或查询。
primaryExchange="NASDAQ"告诉 IBKR 这只股票主要挂牌在 NASDAQ,用来消除歧义。

使用 TWS 模拟账户请求 AAPL + STK + SMART + USD 的合约详情,无账户敏感信息输出如下:

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

这个结果说明:

  • symbol + secType + exchange + currency 已经能唯一定位 AAPL 股票。
  • TWS 返回的 conId=265598 是更精确的合约 ID。
  • primaryExchange=NASDAQ 说明 AAPL 的主要交易所不是 SMART
  • validExchanges 是可用交易所或路由列表,不等于一定都适合下单。正式下单仍要结合订单类型、账户权限、交易时段和风险提示。

拿到 conId 后,可以用更精确的方式描述合约:

contract = Contract()
contract.conId = 265598 # AAPL 的 IBKR 合约 ID
contract.exchange = "SMART" # 查询或交易时仍建议写清路由
contract.currency = "USD" # 写清币种,减少歧义

只写 conId 在很多场景也能工作,但实际项目里建议保留 exchangecurrency,日志和排查会更清楚。

期权必须写得更完整,只写 symbol="AAPL"secType="OPT" 通常无法唯一定位。

option = Contract()
option.symbol = "AAPL" # 期权底层标的
option.secType = "OPT" # OPT 表示期权
option.exchange = "SMART" # 美股期权常用 SMART
option.currency = "USD" # 美股期权通常是 USD
option.lastTradeDateOrContractMonth = "20260619" # 到期日,格式 YYYYMMDD
option.strike = 200 # 行权价
option.right = "C" # C=看涨,P=看跌
option.multiplier = "100" # 美股股票期权常见乘数

期权字段不要靠猜。更稳的流程是先查期权链,拿到可用到期日、行权价、交易类别和乘数,再拼 Contract

外汇使用 secType="CASH",并且 symbolcurrency 分别代表两个货币。

fx = Contract()
fx.symbol = "EUR" # 基础货币
fx.secType = "CASH" # CASH 表示外汇
fx.exchange = "IDEALPRO" # IBKR 外汇常用 IDEALPRO
fx.currency = "USD" # 报价货币

上面代表 EUR.USD。如果要查 USD.JPY,通常写 symbol="USD"currency="JPY"

期货通常要写根代码、交易所、币种和合约月份:

future = Contract()
future.symbol = "ES" # 标普 500 E-mini 根代码
future.secType = "FUT" # FUT 表示期货
future.exchange = "CME" # 交易所
future.currency = "USD" # 币种
future.lastTradeDateOrContractMonth = "202606" # 合约月份,格式 YYYYMM

有些期货在 TWS 里实际交易所、tradingClasslocalSymbol 更复杂。正式系统建议先用合约详情确认,再保存返回字段。

有些系统会用 ISIN、CUSIP、SEDOL、RIC 等外部编码定位证券。这时可以使用 secIdTypesecId

contract = Contract()
contract.secIdType = "ISIN" # 证券 ID 类型
contract.secId = "US0378331005" # AAPL 的 ISIN
contract.exchange = "SMART"
contract.currency = "USD"

即使使用证券 ID,也建议用 reqContractDetails() 再确认返回的 conIdsymbolprimaryExchange 是否符合预期。

组合合约使用 secType="BAG",并通过 comboLegs 指定每条腿。它比普通股票、期权复杂得多,常用于期权价差或多腿组合。

from ibapi.contract import ComboLeg
combo = Contract()
combo.symbol = "AAPL" # 组合底层或显示标的
combo.secType = "BAG" # BAG 表示组合合约
combo.currency = "USD"
combo.exchange = "SMART"
leg = ComboLeg()
leg.conId = 123456 # 某条腿的合约 ID,需要先查出来
leg.ratio = 1 # 比例
leg.action = "BUY" # BUY 或 SELL
leg.exchange = "SMART"
combo.comboLegs = [leg]

组合合约不要手写未知 conId。每条腿都应先通过合约详情确认。

误区正确理解
只写 symbol 就够了不够。至少要知道证券类型、交易所或路由、币种。
primaryExchangeSMART不对。SMART 是路由,primaryExchange 是主交易所。
conId 可以随便猜不建议。应该通过合约详情或搜索接口拿到。
股票和期权字段差不多不一样。期权还需要到期日、行权价、看涨/看跌、乘数等字段。
validExchanges 里有某交易所就一定能交易不一定。还要看账户权限、产品权限、订单类型和交易时段。
查行情成功就代表能下单不一定。行情权限、合约定义、交易权限和下单风控是不同层面的检查。