cover_image

基金套利,量化编程-盈透夜盘下单实战篇-6

东哥的平凡生活 静听烟雨任平生

最近文章中总有留言问如何加我这两个编程群。首先,没有IB账户的就不要折腾了,除非你就是想学习如何用AI来指导Python编程;其次,想先学习跨境基金对冲、无风险套利,为日后做点储备知识的读者,需先加入无敌大佬的群。见他1月4号的文章,如果能看明白,进了他的群再继续问吧。
我这两天忙于在"半自动交易群"和"轮动套利群"修复天天爆出来bug,忙的一塌糊涂:
有错就改,还是好学生:
在实践中发现错误,就要分析原因,尤其是我们做套利的,要对数字敏感,这玩意都是真金白银啊,要经常复习无敌的算法



抽出时间在筹备把手动点击下单变成全自动的 API发单,{这个功能属于我的自留地,两个群里都不会讲解,群里不要问,问了也不答,多给一个龙珠也不放出代码 。因为涉及交易,有风险,各自自己去实现就好 } , 即将大功告成之际,在我点击美股下单按键时,却发现IB盈透的委托单里面,没有任何反应啊。


倒是银河QMT的实盘、国金QMT的模拟盘很顺利,单子痛快地就发出去了。最近有几位读者看了我之前的文章介绍,也去开通了国金的账户,手中有粮,心中不愁。原本我还想继续琢磨通达信,结果前天群友说,现在官方都下载不了之前的通达信V7.72免费版本了,支持TQ交易的需要"收费用户"才能用;

那我就先不折腾通达信了。

回到IB,难道AI又偷偷摸摸给我“优化”程序了吗?

在做跨境 QDII LOF 套利,盈透证券(Interactive Brokers)的美股夜盘(Overnight)绝对是首选武器。我上个月做过测试,IB夜盘下单都是成功的,然后就去忙着前端页面优化、算法改良的事情去了。

于是,从前天开始,经历这一段令人抓狂的“见鬼”时光:同样的代码,之前能成功,今天不行了。然后,调试好了,在 TWS 电脑端测试完美下单,一旦切到轻量级的 IB Gateway 网关运行,订单就会瞬间石沉大海,或者被系统无情秒拒。

下面都是Gemini根据调试对话总结而成,我对它说的"shortSaleSlot"半信半疑。

今天,就来按真实的时间线复盘这次排雷之旅,彻底揭开这个盈透 API 最深层的“薛定谔的报错”之谜,为大家奉上最干净、最硬核的 IB 夜盘直连发单指南!


🌑 第一阶段:全盘溃败与那些我们走过的弯路

需求很简单:在A股的交易时刻(美东深夜夜盘时段),通过 API 发送指令,去 Blue Ocean、Moon等(盈透夜盘背后的暗池)直接挂单或卖空美股 ETF(如 XOP, GLD, USO)。

起初,我们理所当然地写下 action="SELL" 和 exchange="OVERNIGHT"。结果不论是 TWS 还是 Gateway,发单后全如泥牛入海,控制台只留下冰冷的:

ErrorCode: 201 | Msg: 委托单被拒绝 - 原因:委托单已丢弃。

为了解决这个 201 废单错误,我们开启了疯狂的“试错与走弯路”模式:

弯路 1:迷信 SMART 智能路由

我们怀疑直接指定 OVERNIGHT 太生硬,于是改成了盈透引以为傲的 exchange="SMART",并附带了 outsideRth=True(允许盘外交易)。结果:单子确实发成功了,但它并没有进入夜盘网络!而是变成了一个普通的日内单,被挂起等待美东凌晨 4 点的盘前时段才激活。真相:盈透为了保护散户免受夜盘低流动性带来的滑点伤害,系统默认禁止 SMART 路由自动参与夜盘交易。

弯路 2:自作聪明的 SSHORT (Error 321)

既然卖出 (SELL) 被 201 丢弃,我们想到:因为账户没有底仓,所以这是卖空。是不是 API 不认识无底仓的 SELL?于是我们在代码里强行把动作改成了 action="SSHORT"结果:惨遭系统更底层的拦截:ErrorCode: 321 | Msg: Invalid side field was entered真相:盈透的 Order 对象底层协议极度严格,action 字段只接受 BUY 或 SELL,根本不认识 SSHORT 这个词。


🌅 第二阶段:拨云见日,正确的 API 卖空与合约姿势

在不断测试后,终于摸清了直连夜盘卖空的真正规范:

1. 破解做空“裸奔”陷阱

要卖空,动作依然得是 SELL,但必须显式带上“融券提供方”的隐形标签 shortSaleSlot!当直连暗池时,如果不带这个标签,交易所一看你没票可卖,就会按废单丢弃 (201)。

order.action = "SELL"
# 1代表从券商(盈透)处借券,这是 API 裸发卖空单的真正开关!
order.shortSaleSlot = 1 

💣 避坑指南二:画蛇添足的主交易所 (Error 2157)

为了防止系统认错股票,我习惯性地给合约带上主交易所,比如 primaryExchange = "ARCA"

但是在夜盘直连模式下,这反而成了致命伤!如果刚好遇到 Gateway 底层合约数据库网络不稳定(报 Sec-def数据场连接中断),网关收到带 ARCA 的夜盘单会直接陷入迷茫,再次将订单当作废单丢弃。

💡 终极解法: 夜盘路由必须极度纯净。夜盘就是 OVERNIGHT,不要带任何其他累赘!

contract.symbol = "XOP"
contract.secType = "STK"
contract.exchange = "OVERNIGHT" 
contract.currency = "USD"
# 绝对不要写 contract.primaryExchange = "ARCA"!

💣 避坑指南三:沉默的杀手,警告拦截 (Warning 10329)

当修复了上述问题,满心欢喜地再次发单,发现订单状态变成了 Cancelled,并且控制台出现了一行警告:

ErrorCode: 10329 | Msg: 该委托单将直接传递至OVERNIGHT。可在全局配置/API的预防设置部分指定限制。

注意!这根本不是报错,这是一个警告!意思是:“嘿,你放弃了 SMART 智能路由,强行直连夜盘,风险自负哦确认吗?”

在 TWS 中:可能曾经在弹窗上勾选过“不再提示”,所以 TWS 自动帮你点击了确认。在 Gateway 中:因为它没有图形界面,弹不出确认框,它为了保护你的安全,直接把订单拦截并取消了

💡 终极解法(无需改代码,只需改配置): 打开 IB Gateway 的设置面板:

  1. 导航到 配置 (Configure) -> API -> 设置 (Settings)-> 预防
  2. 勾选 👉 API委托跳过委托单预防设置 (Bypass Order Precautions for API Orders)
  3. 最关键的一步,勾选 👉 股票API委托单跳过重新传递委托单警告 (Bypass routing warning for stock API orders)

只要打上这个勾,Gateway 就会直接无视这句啰嗦的警告,让你的夜盘单畅通无阻!


🏆 终极代码模板(拿走即用)

历经重重磨难,这是标准100% 能在 IB Gateway 中存活的美股夜盘 API 发单模板:

from ibapi.contract import Contract
from ibapi.order import Order

# 1. 纯净的合约定义
contract = Contract()
contract.symbol = "XOP"       # 你的交易标的
contract.secType = "STK"
contract.exchange = "OVERNIGHT" # 唯一且正确的夜盘目的地
contract.currency = "USD"

# 2. 精确的订单定义
order = Order()
order.action = "SELL"         # 买入则为 "BUY"
order.shortSaleSlot = 1       # 卖空必带参数!(买入时可省略)
order.orderType = "LMT"
order.totalQuantity = 100
order.lmtPrice = 145.50
order.tif = "DAY"
order.outsideRth = True       # 允许盘外交易

# 发送订单
app.placeOrder(order_id, contract, order)

结语

做量化交易和底层 API 对接,就像在黑盒子里扫雷。有时候打败你的不是高深的算法,而是一个不起眼的客户端配置项,或者一个极其“智能”的客户端替你隐藏的底层逻辑。

坚持控制变量法,剥离主程序,用最极简的脚本独立验证,再配合官方底层的日志排查,这是攻克一切 API 疑难杂症的终极法宝。

祝各位夜盘狙击顺利,日进斗金!


继续滑动看下一个
静听烟雨任平生
向上滑动看下一个