跳转到内容

Order 与 Contract 对象

TWS API 下单时不是只发送“买 AAPL 1 股”这么一句话,而是同时发送两个对象:

对象作用常见字段
Contract说明交易什么合约symbolsecTypeexchangecurrencyprimaryExchangeconId
Order说明怎样交易actionorderTypetotalQuantitylmtPricetiftransmitwhatIf

可以把 Contract 理解成“标的身份证”,把 Order 理解成“委托单指令”。两者缺一不可:合约不清楚,TWS 不知道交易哪个产品;订单字段不清楚,TWS 不知道买卖方向、数量、价格和有效期。

官方参考:TWS API Documentation

下面是最常见的美股股票合约写法。SMART 表示让 IBKR 智能路由选择交易所,USD 表示美元计价。

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

如果同一个代码在多个市场都存在,可以补 primaryExchange。例如 AAPL 在 NASDAQ 主上市:

contract.primaryExchange = "NASDAQ"

更稳的做法是先用 reqContractDetails() 查到明确的 conId,后续关键订单可以保存并复用这个合约编号。

from ibapi.order import Order
def buy_limit_order(quantity: float, limit_price: float) -> Order:
order = Order()
order.action = "BUY" # BUY 买入,SELL 卖出
order.orderType = "LMT" # LMT 是限价单
order.totalQuantity = quantity # 数量
order.lmtPrice = limit_price # 限价
order.tif = "DAY" # DAY 表示当日有效
order.transmit = True # True 才会传给 TWS/IBKR 处理
order.orderRef = "strategy_a" # 自定义引用,方便排查
return order

MKT 市价单不需要 lmtPrice,但新手调试不建议从市价单开始。限价单更容易控制风险,也更容易解释为什么订单没有成交。

请求 AAPL 股票合约详情时,可以得到下面这类关键信息:

CONTRACT_DETAIL=conId=265598;symbol=AAPL;secType=STK;exchange=SMART;primaryExchange=NASDAQ;marketRuleIds=4563...;minTick=0.01
MARKET_RULE=marketRuleId=4563;lowEdge=0.0;increment=0.01

这说明:

  • AAPL 的 conId265598
  • 主上市交易所是 NASDAQ
  • 返回的最小价格变动单位是 0.01
  • 后续下单、WhatIf、改单、撤单都可以基于这个合约对象继续。
app.placeOrder(order_id, contract, order)
参数来源说明
order_idnextValidId()API 客户端侧订单编号。改单时必须复用原订单 ID。
contract自己构造或合约详情查询结果告诉 TWS 交易哪个产品。
order自己构造告诉 TWS 买卖方向、数量、价格、订单类型等。

placeOrder() 只是发送请求。订单是否被接受、是否触发风控、是否成交、是否被取消,都要看后续回调。

问题表现处理方式
secType 写错找不到合约或返回多个不确定合约股票用 STK,期权用 OPT,期货用 FUT
exchange 乱写合约详情为空或下单被拒美股新手先用 SMART
没有 currency合约解析不稳定美股写 USD
限价不符合最小跳动下单被拒先查 marketRuleIdsreqMarketRule()
代码只构造 OrderplaceOrder() 无法知道交易哪个标的必须同时传 Contract
改单换了新 orderIdTWS 当成新订单修改同一张订单必须复用原 orderId