如何提前提交IBKR MOO母单,成交后基于实际成交价设置TP/SL
IB_insync 实现MOO母单成交后自动挂TP/SL子单
核心方案
放弃依赖tick行情,提前提交MOO买入母单,通过监听IB返回的订单成交状态,拿到真实成交均价后立即计算并挂止盈止损子单——这是完全规避开盘行情延迟/缺失问题的可靠方案。
具体实现步骤
- 提前挂MOO母单:构造
MarketOrder时指定outsideRth=True,确保订单在美东9:30开盘时执行,而非盘前或盘中随意成交。 - 监听成交状态:通过订单对象的
status字段或IB的订单状态事件,实时捕捉母单成交信号,直接取IB返回的avgFillPrice作为真实入场价——这比任何tick数据都准确。 - 提交TP/SL子单:用成交均价计算止盈止损价位,分别提交限价止盈单和止损单,可选设置
parentId关联母单方便管理。
代码示例
from ib_insync import IB, MarketOrder, LimitOrder, StopOrder from datetime import datetime import pytz # 初始化IB连接 ib = IB() ib.connect('127.0.0.1', 7497, clientId=2) # 对应你的TWS/IBGW端口和clientId # 定义合约(以AAPL为例) contract = ib.qualifyContracts(ib.contract('AAPL'))[0] # 1. 提前提交MOO买入母单 moo_order = MarketOrder(action='BUY', totalQuantity=100, outsideRth=True) moo_trade = ib.placeOrder(contract, moo_order) # 回调函数处理订单成交 def handle_order_status(order): if order.status == 'Filled': fill_price = order.avgFillPrice print(f"[{datetime.now(pytz.timezone('America/New_York'))}] 母单成交,均价: {fill_price:.2f}") # 计算TP/SL(这里用2%止盈,2%止损,可按需修改) tp_price = fill_price * 1.02 sl_price = fill_price * 0.98 # 提交止盈单 tp_order = LimitOrder(action='SELL', totalQuantity=100, lmtPrice=tp_price) ib.placeOrder(contract, tp_order) # 提交止损单 sl_order = StopOrder(action='SELL', totalQuantity=100, stopPrice=sl_price) ib.placeOrder(contract, sl_order) print(f"已提交止盈单({tp_price:.2f})和止损单({sl_price:.2f})") # 可选:取消监听避免重复触发 ib.orderStatusEvent -= handle_order_status # 绑定订单状态监听事件 ib.orderStatusEvent += handle_order_status # 保持脚本运行监听事件 ib.run()
关键注意点
- 绝对不要用tick.last:IB订单的
avgFillPrice是官方确认的成交均价,完全避免开盘时tick数据延迟、缺失或不准确的问题。 - MOO单的
outsideRth参数:必须设为True,否则订单会变成普通市价单,可能在盘前就成交,不符合你9:30进场的需求。 - 时区同步:用
pytz确保脚本时间与美东时间一致,避免提前或延后提交订单。 - 回调 vs 循环检查:用
orderStatusEvent回调比轮询更高效,能在成交瞬间触发子单提交,几乎无延迟。
内容的提问来源于stack exchange,提问作者Fakhar Hassan
相关产品推荐
相关产品推荐

