跳转到内容

修改订单

TWS API 修改订单不是调用一个单独的 modifyOrder(),而是复用原来的 orderId 再次调用 placeOrder()

# 第一次提交
app.placeOrder(order_id, contract, buy_limit_order(100.00))
# 修改同一张订单的限价
app.placeOrder(order_id, contract, buy_limit_order(100.01))

关键点是:order_id 必须相同。不同的 orderId 会被 TWS 当成新订单。

先提交 AAPL BUY 1 LMT 100.00,再把同一张订单改成 100.01,TWS 返回:

OPEN_ORDER=orderId=26;symbol=AAPL;action=BUY;orderType=LMT;totalQuantity=1;lmtPrice=100.0;status=PreSubmitted
OPEN_ORDER=orderId=26;symbol=AAPL;action=BUY;orderType=LMT;totalQuantity=1;lmtPrice=100.01;status=Submitted

这说明修改后的订单仍然是同一个 orderId=26,只是限价变化了。状态可能经历 PreSubmittedPendingSubmitSubmitted 等多个阶段,同一个状态也可能重复推送。

字段是否常见说明
lmtPrice常见修改限价。
auxPrice常见修改止损触发价或止损限价辅助价格。
totalQuantity谨慎可能受已成交数量影响,不能小于已成交数量。
tif谨慎部分订单状态下不能改。
outsideRth谨慎取决于产品、交易时段和订单状态。
action不建议买卖方向变化通常应撤单后重下。
contract不建议标的变化应新建订单。

修改订单失败通常有几类原因:

  • 订单已经成交、取消或失效,不能再改。
  • 修改后的价格不符合最小价格增量。
  • 修改后的价格触发订单保护或风控限制。
  • 修改字段不被该订单类型、产品或交易所支持。
  • 同一个订单正在撤单过程中,TWS 暂时不接受修改。

程序里要同时保存 orderIdpermIdorderId 是该 API 客户端使用的编号,permId 是 IBKR 为订单生成的永久编号,更适合跨客户端排查。

再次调用 placeOrder() 不代表修改一定成功。程序要等 openOrder() 返回新的价格,或者 orderStatus() / error() 给出结果,再更新业务状态。