提交订单
placeOrder(orderId, contract, order) 是 TWS API 的核心下单接口。它会把 Contract 和 Order 一起发送给 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。
模拟下单流程示例
Section titled “模拟下单流程示例”下面示例提交一张 AAPL BUY 1 LMT 100.00 的模拟限价单。限价单不会像市价单那样主动追价,更适合观察 openOrder()、orderStatus() 和撤单流程。
from ibapi.contract import Contractfrom 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))模拟账户返回
Section titled “模拟账户返回”OPEN_ORDER=orderId=26;symbol=AAPL;action=BUY;orderType=LMT;totalQuantity=1;lmtPrice=100.0;whatIf=False;transmit=True;status=PreSubmittedORDER_STATUS=orderId=26;status=PreSubmitted;filled=0;remaining=1;avgFillPrice=0.0;permId=1466795665;clientId=98400PreSubmitted 表示订单已经通过 API 进入 TWS/IBKR 的处理流程,但还没有成交。这个状态对远离市场价格的限价买单很常见。
同一笔测试随后改价到 100.01,并被主动撤单:
ORDER_STATUS=orderId=26;status=Submitted;filled=0;remaining=1;avgFillPrice=0.0ORDER_STATUS=orderId=26;status=Cancelled;filled=0;remaining=1;avgFillPrice=0.0filled=0、remaining=1 说明这笔订单没有成交,只是完成了提交、改单、撤单流程。
最小完整回调
Section titled “最小完整回调”下单后至少要监听三个回调:
| 回调 | 用途 |
|---|---|
openOrder() | 返回订单对象、合约和初始状态。 |
orderStatus() | 返回成交数量、剩余数量、状态变化。 |
error() | 返回订单拒绝、取消、风控提示和系统消息。 |
不要只看 placeOrder() 是否执行完。placeOrder() 本身只是发送请求,订单是否通过、是否成交、是否被取消,都要看回调。
复杂订单先在 TWS 里确认
Section titled “复杂订单先在 TWS 里确认”IBKR 官方资料强调:TWS 能创建的多数订单类型和属性,API 才更可能支持。复杂订单在写代码前,建议先在 TWS 手工创建同样的合约、订单类型和属性组合;如果 TWS 界面里该订单类型不可选或被置灰,API 通常也不会绕过这个限制。
这个原则尤其适用于:
- 括号单、OCA、条件订单。
- 期权、期货、外汇、债券等非普通股票产品。
- IB Algo、盘前盘后、特殊有效期或高级路由属性。
- 第一张模拟订单用
LMT,数量用1。 - 限价不要使用市价附近的激进价格,避免立即成交导致不好观察。
- 每个测试订单都设置
orderRef,便于日志和 TWS 订单监控里识别。 - 下单脚本结束前主动
cancelOrder()清理测试订单;只有无法确认指定订单是否已经取消时,才考虑用reqGlobalCancel()兜底。 - 看到
202委托单被取消并不一定是错误,主动撤单也会走这个提示。