跳转到内容

提交订单

placeOrder(orderId, contract, order) 是 TWS API 的核心下单接口。它会把 ContractOrder 一起发送给 TWS,然后由 TWS 做合约校验、价格校验、订单保护、保证金检查和路由处理。

官方参考:IBKR Campus: Placing Orders using TWS Python API

app.placeOrder(order_id, contract, order)
参数中文意思
order_id订单 ID,通常来自 nextValidId()
contract要交易的合约。
order买卖方向、数量、价格、订单类型等委托参数。

同一个 orderId 只能代表一张订单。修改订单时会再次调用 placeOrder(),但要复用原来的 orderId

下面示例提交一张 AAPL BUY 1 LMT 100.00 的模拟限价单。限价单不会像市价单那样主动追价,更适合观察 openOrder()orderStatus() 和撤单流程。

from ibapi.contract import Contract
from ibapi.order import Order
def aapl_contract() -> Contract:
contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
return contract
def buy_limit_order(price: float) -> Order:
order = Order()
order.action = "BUY"
order.orderType = "LMT"
order.totalQuantity = 1
order.lmtPrice = price
order.tif = "DAY"
order.transmit = True
order.orderRef = "IBKR_CN_DOCS_ORDERS_PROBE"
return order
app.placeOrder(order_id, aapl_contract(), buy_limit_order(100.00))
OPEN_ORDER=orderId=26;symbol=AAPL;action=BUY;orderType=LMT;totalQuantity=1;lmtPrice=100.0;whatIf=False;transmit=True;status=PreSubmitted
ORDER_STATUS=orderId=26;status=PreSubmitted;filled=0;remaining=1;avgFillPrice=0.0;permId=1466795665;clientId=98400

PreSubmitted 表示订单已经通过 API 进入 TWS/IBKR 的处理流程,但还没有成交。这个状态对远离市场价格的限价买单很常见。

同一笔测试随后改价到 100.01,并被主动撤单:

ORDER_STATUS=orderId=26;status=Submitted;filled=0;remaining=1;avgFillPrice=0.0
ORDER_STATUS=orderId=26;status=Cancelled;filled=0;remaining=1;avgFillPrice=0.0

filled=0remaining=1 说明这笔订单没有成交,只是完成了提交、改单、撤单流程。

下单后至少要监听三个回调:

回调用途
openOrder()返回订单对象、合约和初始状态。
orderStatus()返回成交数量、剩余数量、状态变化。
error()返回订单拒绝、取消、风控提示和系统消息。

不要只看 placeOrder() 是否执行完。placeOrder() 本身只是发送请求,订单是否通过、是否成交、是否被取消,都要看回调。

IBKR 官方资料强调:TWS 能创建的多数订单类型和属性,API 才更可能支持。复杂订单在写代码前,建议先在 TWS 手工创建同样的合约、订单类型和属性组合;如果 TWS 界面里该订单类型不可选或被置灰,API 通常也不会绕过这个限制。

这个原则尤其适用于:

  • 括号单、OCA、条件订单。
  • 期权、期货、外汇、债券等非普通股票产品。
  • IB Algo、盘前盘后、特殊有效期或高级路由属性。
  • 第一张模拟订单用 LMT,数量用 1
  • 限价不要使用市价附近的激进价格,避免立即成交导致不好观察。
  • 每个测试订单都设置 orderRef,便于日志和 TWS 订单监控里识别。
  • 下单脚本结束前主动 cancelOrder() 清理测试订单;只有无法确认指定订单是否已经取消时,才考虑用 reqGlobalCancel() 兜底。
  • 看到 202 委托单被取消并不一定是错误,主动撤单也会走这个提示。