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
Section titled “为什么先学 Contract”如果 Contract 写错,后面不是没有返回,就是返回多条歧义结果,严重时可能查错标的或下到错误标的。
| 要做什么 | 常用接口 | 为什么需要 Contract |
|---|---|---|
| 查合约详情 | reqContractDetails() | 确认合约是否能唯一定位,并拿到 conId 等精确字段 |
| 查实时行情 | reqMktData() | 告诉 TWS 要订阅哪个标的 |
| 拉历史 K 线 | reqHistoricalData() | 告诉 TWS 要拉哪个标的的历史数据 |
| 下单 | placeOrder() | 告诉 TWS 要交易哪个标的 |
| 查成交 | reqExecutions() | 可以按合约过滤成交记录 |
| 查期权链 | reqSecDefOptParams() | 先确定底层合约,再查可用到期日和行权价 |
学习阶段可以先写最少字段。正式系统里,更稳的做法是先用 reqContractDetails() 查一次,保存 TWS 返回的 conId、primaryExchange、localSymbol、tradingClass 等字段。
Python API 的 Contract 对象常见字段如下。不是每种产品都要填满,重点是按产品类型填对关键字段。
| 字段 | 中文含义 | 常见示例 | 说明 |
|---|---|---|---|
conId | IBKR 合约 ID | 265598 | 最精确的合约标识。已知 conId 时,可以减少代码歧义。 |
symbol | 标的代码 | AAPL、EUR、ES | 股票代码、外汇基础货币、期货根代码、期权底层代码等。 |
secType | 证券类型 | STK、OPT、FUT、CASH | 决定这是什么产品。写错后,行情、历史数据和下单等接口通常无法返回正确结果。 |
lastTradeDateOrContractMonth | 到期日或合约月份 | 20260619、202606 | 期权、期货、期货期权常用。股票和外汇通常不填。 |
lastTradeDate | 最后交易日 | 20260619 | API 对象中存在的字段,实际开发更常用 lastTradeDateOrContractMonth。 |
strike | 行权价 | 200 | 期权必填字段之一。 |
right | 看涨/看跌 | C、P | C 表示 Call,看涨;P 表示 Put,看跌。 |
multiplier | 合约乘数 | 100、50 | 美股期权常见 100,期货和指数期权要以合约详情返回为准。 |
exchange | 交易所或路由 | SMART、IDEALPRO、GLOBEX | 股票常用 SMART,外汇常用 IDEALPRO,期货常用具体交易所。 |
primaryExchange | 主要交易所 | NASDAQ、NYSE | 用来消除同代码歧义;不要写成 SMART。 |
currency | 计价币种 | USD、HKD、EUR | 美股通常是 USD,港股通常是 HKD。 |
localSymbol | 本地代码 | AAPL、ESM6 | TWS 或交易所使用的本地显示代码,合约详情里常见。 |
tradingClass | 交易类别 | NMS、SPX、ES | 股票、期权、期货合约详情和交易规则里常见。 |
includeExpired | 是否包含已过期合约 | True / False | 查询历史期货合约时可能用到;不能用来交易过期合约。 |
secIdType | 证券 ID 类型 | ISIN、CUSIP、SEDOL、RIC | 用外部证券编码定位合约时使用。 |
secId | 证券 ID 值 | US0378331005 | 与 secIdType 配合使用,例如 AAPL 的 ISIN。 |
description | 合约描述 | APPLE INC | 描述性字段,通常来自返回结果,不作为主要定位条件。 |
issuerId | 发行人 ID | 返回值为准 | 部分产品或数据接口可能返回,普通入门开发很少手写。 |
comboLegsDescrip | 组合腿描述 | 返回值为准 | 组合订单相关。一般由 TWS 返回或由组合腿构造推导。 |
comboLegs | 组合腿列表 | ComboLeg 列表 | 组合合约使用,例如期权价差、股票组合。 |
deltaNeutralContract | Delta Neutral 合约 | DeltaNeutralContract | 高级期权/Delta Neutral 策略使用。 |
最常用的字段组合是:
symbol + secType + exchange + currency最可靠的字段是:
conId但 conId 不建议靠猜。应该通过合约详情或合约搜索接口拿到。
证券类型 secType
Section titled “证券类型 secType”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 的主要挂牌交易所exchange 和 primaryExchange 不一样:
| 字段 | 作用 |
|---|---|
exchange="SMART" | 告诉 IBKR 用智能路由执行或查询。 |
primaryExchange="NASDAQ" | 告诉 IBKR 这只股票主要挂牌在 NASDAQ,用来消除歧义。 |
AAPL 参考结果
Section titled “AAPL 参考结果”使用 TWS 模拟账户请求 AAPL + STK + SMART + USD 的合约详情,无账户敏感信息输出如下:
CONNECTED=TrueREQUEST_SENT=TrueCONTRACT_DETAILS_END_RECEIVED=TrueCONTRACT_DETAILS_ROW_COUNT=1SEC_TYPE_COUNTS=STK:1EXCHANGE_COUNTS=SMART:1PRIMARY_EXCHANGE_COUNTS=NASDAQ:1FIRST_CONID=265598FIRST_SYMBOL=AAPLFIRST_LOCAL_SYMBOL=AAPLFIRST_TRADING_CLASS=NMSFIRST_LONG_NAME=APPLE INCFIRST_MIN_TICK=0.01FIRST_TIME_ZONE_ID=US/EasternFIRST_MARKET_NAME=NMSFIRST_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,T24XINFO_CODES=2104,2106,2158NON_INFO_ERROR_COUNT=0IS_CONNECTED_AFTER_DISCONNECT=False这个结果说明:
symbol + secType + exchange + currency已经能唯一定位 AAPL 股票。- TWS 返回的
conId=265598是更精确的合约 ID。 primaryExchange=NASDAQ说明 AAPL 的主要交易所不是SMART。validExchanges是可用交易所或路由列表,不等于一定都适合下单。正式下单仍要结合订单类型、账户权限、交易时段和风险提示。
按 conId 写法
Section titled “按 conId 写法”拿到 conId 后,可以用更精确的方式描述合约:
contract = Contract()contract.conId = 265598 # AAPL 的 IBKR 合约 IDcontract.exchange = "SMART" # 查询或交易时仍建议写清路由contract.currency = "USD" # 写清币种,减少歧义只写 conId 在很多场景也能工作,但实际项目里建议保留 exchange 和 currency,日志和排查会更清楚。
期权必须写得更完整,只写 symbol="AAPL" 和 secType="OPT" 通常无法唯一定位。
option = Contract()option.symbol = "AAPL" # 期权底层标的option.secType = "OPT" # OPT 表示期权option.exchange = "SMART" # 美股期权常用 SMARToption.currency = "USD" # 美股期权通常是 USDoption.lastTradeDateOrContractMonth = "20260619" # 到期日,格式 YYYYMMDDoption.strike = 200 # 行权价option.right = "C" # C=看涨,P=看跌option.multiplier = "100" # 美股股票期权常见乘数期权字段不要靠猜。更稳的流程是先查期权链,拿到可用到期日、行权价、交易类别和乘数,再拼 Contract。
外汇使用 secType="CASH",并且 symbol 和 currency 分别代表两个货币。
fx = Contract()fx.symbol = "EUR" # 基础货币fx.secType = "CASH" # CASH 表示外汇fx.exchange = "IDEALPRO" # IBKR 外汇常用 IDEALPROfx.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 里实际交易所、tradingClass、localSymbol 更复杂。正式系统建议先用合约详情确认,再保存返回字段。
用证券 ID 定位
Section titled “用证券 ID 定位”有些系统会用 ISIN、CUSIP、SEDOL、RIC 等外部编码定位证券。这时可以使用 secIdType 和 secId:
contract = Contract()contract.secIdType = "ISIN" # 证券 ID 类型contract.secId = "US0378331005" # AAPL 的 ISINcontract.exchange = "SMART"contract.currency = "USD"即使使用证券 ID,也建议用 reqContractDetails() 再确认返回的 conId、symbol、primaryExchange 是否符合预期。
组合合约 BAG
Section titled “组合合约 BAG”组合合约使用 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 或 SELLleg.exchange = "SMART"
combo.comboLegs = [leg]组合合约不要手写未知 conId。每条腿都应先通过合约详情确认。
| 误区 | 正确理解 |
|---|---|
只写 symbol 就够了 | 不够。至少要知道证券类型、交易所或路由、币种。 |
primaryExchange 写 SMART | 不对。SMART 是路由,primaryExchange 是主交易所。 |
conId 可以随便猜 | 不建议。应该通过合约详情或搜索接口拿到。 |
| 股票和期权字段差不多 | 不一样。期权还需要到期日、行权价、看涨/看跌、乘数等字段。 |
validExchanges 里有某交易所就一定能交易 | 不一定。还要看账户权限、产品权限、订单类型和交易时段。 |
| 查行情成功就代表能下单 | 不一定。行情权限、合约定义、交易权限和下单风控是不同层面的检查。 |