求助:使用IB Python API发送跨期期货价差订单失败
问题排查:IB Python API期货价差订单未生效
以下是针对你的代码的几个关键排查点和修复建议:
1. 程序未保持运行导致订单未发送
ib_insync基于异步事件循环,你的代码在调用ib.placeOrder后立即结束程序,此时订单可能还未完成发送到TWS的流程。需要在代码末尾添加事件循环保持运行:
ib.run() # 保持程序运行,等待订单处理
或者等待订单状态更新:
order_status = ib.waitOnUpdate(timeout=10) # 等待10秒确认订单状态
2. 订单Action字段冗余(或需调整)
对于BAG类型的期货价差合约,订单的action字段可以省略——ComboLegs中已经定义了每个合约的买卖方向,重复设置可能导致TWS解析冲突。尝试删除spread_order.action = 'BUY',让组合方向完全由legs定义。
3. 补充ComboLeg的openClose参数
期货合约的ComboLeg需要明确指定开平仓状态,默认值为0(开仓),但显式设置可以避免TWS解析错误:
leg1.openClose = 0 leg2.openClose = 0
4. 使用ib_insync原生Bag类创建组合合约
ib_insync提供了专门的Bag类,比手动创建Contract对象更简洁且不易出错:
contract = Bag( symbol='SR3', secType='BAG', exchange='CME', currency='USD', comboLegs=[leg1, leg2] )
5. 验证合约ConID正确性
虽然你手动发送订单正常,但仍建议通过API验证ConID对应的合约是否正确,避免因合约过期或ID变更导致问题:
# 验证leg1的ConID contract_details = ib.reqContractDetails(Contract(conId=385575897)) print(contract_details[0].contract) # 验证leg2的ConID contract_details = ib.reqContractDetails(Contract(conId=385575856)) print(contract_details[0].contract)
修复后的完整代码示例
from ib_insync import * ib = IB() ib.connect('127.0.0.1', 7497, clientId=3) # 创建组合腿 leg1 = ComboLeg( conId=385575897, # SR3Z7 ratio=1, action="BUY", exchange="CME", openClose=0 ) leg2 = ComboLeg( conId=385575856, # SR3M8 ratio=1, action="SELL", exchange="CME", openClose=0 ) # 使用Bag类创建组合合约 contract = Bag( symbol='SR3', secType='BAG', exchange='CME', currency='USD', comboLegs=[leg1, leg2] ) # 创建订单 spread_order = Order() spread_order.orderType = "MKT" spread_order.totalQuantity = 1 spread_order.smartComboRoutingParams = [TagValue('NonGuaranteed', '1')] # 发送订单 order = ib.placeOrder(contract, spread_order) # 等待订单处理,保持程序运行 ib.run()
内容的提问来源于stack exchange,提问作者Cleisson Cavalcante
相关产品推荐
相关产品推荐

