跳转到内容

添加止盈和止损

止盈和止损通常用括号单实现:一张父订单用于建仓,后面挂两张子订单,一张止盈,一张止损。父订单成交后,子订单才会开始工作;其中一张子订单成交后,另一张通常会被取消。

官方参考:TWS API Documentation

订单方向示例订单类型作用
父订单BUYLMT买入建仓。
止盈单SELLLMT价格上涨到目标价时卖出。
止损单SELLSTP价格下跌到止损价时触发卖出。

如果父订单是卖出开仓,子订单方向通常要反过来。方向不要死记,要按“父订单建立仓位,子订单退出仓位”的逻辑理解。

两张子订单通过 parentId 绑定父订单。括号单常见写法是:

订单transmit原因
父订单False先放进 TWS,但不单独传递。
止盈单False等最后一张子单一起触发整组传递。
止损单True最后一张订单触发整组订单传递。

这里的 transmit 不是随便设置的。父订单如果一开始就 transmit=True,可能会先被单独提交;括号单通常希望三张订单作为一组进入 TWS,所以最后一张子订单才负责触发整组传递。

from ibapi.order import Order
def bracket_order(
parent_id: int,
quantity: float,
entry_price: float,
take_profit_price: float,
stop_loss_price: float,
) -> list[Order]:
parent = Order()
parent.orderId = parent_id
parent.action = "BUY"
parent.orderType = "LMT"
parent.totalQuantity = quantity
parent.lmtPrice = entry_price
parent.tif = "DAY"
parent.transmit = False
parent.orderRef = "bracket_parent"
take_profit = Order()
take_profit.orderId = parent_id + 1
take_profit.action = "SELL"
take_profit.orderType = "LMT"
take_profit.totalQuantity = quantity
take_profit.lmtPrice = take_profit_price
take_profit.parentId = parent_id
take_profit.tif = "DAY"
take_profit.transmit = False
take_profit.orderRef = "bracket_take_profit"
stop_loss = Order()
stop_loss.orderId = parent_id + 2
stop_loss.action = "SELL"
stop_loss.orderType = "STP"
stop_loss.totalQuantity = quantity
stop_loss.auxPrice = stop_loss_price
stop_loss.parentId = parent_id
stop_loss.tif = "DAY"
stop_loss.transmit = True
stop_loss.orderRef = "bracket_stop_loss"
return [parent, take_profit, stop_loss]

提交时按顺序发送:

for order in bracket_order(order_id, 1, 100.00, 110.00, 95.00):
app.placeOrder(order.orderId, contract, order)
字段中文说明
orderId每张订单必须有自己的订单 ID。
parentId子订单绑定父订单,值等于父订单的 orderId
transmit控制订单是否传递;括号单通常最后一张为 True
lmtPrice父限价单和止盈限价单使用。
auxPrice止损单的触发价。
orderRef建议区分父单、止盈单、止损单,方便排查。
  • 子订单方向通常和父订单相反。
  • parentId 必须等于父订单的 orderId
  • 最后一张订单 transmit=True 会触发整组订单传递。
  • 如果中途报错,应先取消相关订单,再重新提交完整括号单。
  • 括号单不等于没有风险。跳空、流动性不足、交易时段限制都可能导致止损成交价格和触发价不同。
  • 先用 what-if 和模拟账户小数量检查,再考虑更复杂的真实交易场景。