如何在Interactive Brokers新API(9.73)及ib_insync中获取成交价格与佣金
用ib_insync获取市价单的成交价格与佣金
嘿,我之前在ib_insync上处理过一模一样的需求,给你梳理下两种靠谱的方法,不管是实时监听成交还是事后查询都能用:
方法一:通过事件监听实时获取成交信息
ib_insync是事件驱动的框架,我们可以给IB对象绑定orderStatusEvent回调,当订单状态更新为Filled时,就能直接拿到成交的价格和佣金细节。
举个实际的代码例子:
from ib_insync import IB, Order, Contract # 连接IB网关 ib = IB() ib.connect('127.0.0.1', 7497, clientId=1) # 定义订单状态变化的回调函数 def handle_order_status(order): # 当订单完全成交时 if order.status == 'Filled': # 获取所有成交记录,筛选当前订单的明细 order_fills = [fill for fill in ib.fills() if fill.order.orderId == order.orderId] for fill in order_fills: print(f"成交价格: {fill.execution.price}") print(f"单批佣金: {fill.commissionReport.commission}") print(f"佣金货币: {fill.commissionReport.currency}") print(f"该批成交数量: {fill.execution.shares}") # 绑定回调事件 ib.orderStatusEvent += handle_order_status # 创建合约(以AAPL股票为例) aapl_contract = Contract(symbol='AAPL', secType='STK', exchange='SMART', currency='USD') # 创建市价单 mkt_order = Order(action='BUY', totalQuantity=1, orderType='MKT') # 下单 trade = ib.placeOrder(aapl_contract, mkt_order) # 保持连接监听事件 ib.run()
方法二:下单后主动查询成交记录
如果不需要实时监听,也可以在下单后等待订单成交,再主动查询成交信息。这种方式适合脚本式的操作,不用一直挂着监听:
from ib_insync import IB, Order, Contract ib = IB() ib.connect('127.0.0.1', 7497, clientId=2) # 创建合约和市价单 contract = Contract(symbol='MSFT', secType='STK', exchange='SMART', currency='USD') order = Order(action='SELL', totalQuantity=1, orderType='MKT') # 下单并获取trade对象 trade = ib.placeOrder(contract, order) # 等待订单状态更新(比固定sleep更可靠) ib.waitOnUpdate() # 检查订单是否成交 if trade.order.status == 'Filled': # 通过trade对象直接获取该订单的所有成交明细 for fill in trade.fills: print(f"成交价格: {fill.execution.price}") print(f"总佣金: {fill.commissionReport.commission}") print(f"成交时间: {fill.execution.time}") # 也可以查询所有成交记录,筛选目标订单 all_fills = ib.fills() target_fills = [f for f in all_fills if f.order.orderId == trade.order.orderId] for fill in target_fills: print(f"另一种方式获取的成交价格: {fill.execution.price}") ib.disconnect()
几个关键注意点
- 市价单可能会分多笔成交(比如流动性不足时),所以一定要遍历所有对应的
Fill对象,不要只取第一个,避免遗漏部分成交的价格和佣金 commissionReport.commission是单批成交的佣金,如果有多笔成交,需要自己累加得到总佣金- 用
ib.waitOnUpdate()代替固定的ib.sleep()更靠谱,它会等待IB的消息更新后再继续执行,不会因为网络延迟导致查询不到成交信息
内容的提问来源于stack exchange,提问作者bmiljevic
相关产品推荐
相关产品推荐

