如何异步运行ib_insync循环以保持与TWS实例同步?
解决ib_insync阻塞循环导致TWS数据不同步问题
你的核心问题是阻塞式while True循环占用了主线程,导致ib_insync无法及时处理TWS发来的实时消息(比如持仓更新、订单确认)。ib_insync基于asyncio实现,需要主线程有空余时间处理消息队列,否则会出现数据不同步、订单ID丢失等问题。
改写后的异步代码
import asyncio from ib_insync import * from datetime import date import time # 初始化全局变量(根据实际需求调整) stocks_list = [] ticker = "替换为你的目标股票代码" gain = 0 # 替换为实际计算逻辑 price = 0 # 替换为实际价格获取逻辑 async def trading_loop(ib): while True: time_stamp = time.strftime("%H:%M") today = str(date.today()) if today == '2023-05-24' and time_stamp > '04:00': if ticker not in stocks_list: print(ticker) print(gain) print(price) send_price = round((price * 1.10), 2) try: stock = Stock(ticker, 'SMART', 'USD') order = LimitOrder('BUY', 100, send_price, outsideRth=True) sell_trade = ib.placeOrder(stock, order) print(sell_trade) stocks_list.append(ticker) except Exception as e: print(e) # 获取并打印持仓 portfolio = ib.portfolio() if portfolio: for position in portfolio: print(position) # 注意:原代码固定价格0.9600,请根据实际策略调整 stock = Stock(ticker, 'SMART', 'USD') order = LimitOrder('BUY', 50, 0.9600, outsideRth=True, tif='DAY') sell_trade = ib.placeOrder(stock, order) print(sell_trade) # 让出时间给ib_insync处理TWS消息,避免阻塞 await asyncio.sleep(1) # 可根据策略需求调整循环间隔 if __name__ == "__main__": ib = IB() ib.connect() # 如需指定TWS端口/IP,添加参数如ib.connect('127.0.0.1', 7497, clientId=1) try: ib.run(trading_loop(ib)) # 启动异步循环 finally: ib.disconnect()
关键改进说明
- 异步循环替代阻塞循环:用
async def定义异步任务,通过ib.run()启动,确保ib_insync能在循环间隙处理TWS的消息回调。 await asyncio.sleep():必须添加该语句,让主线程让出时间处理消息队列,否则依然会出现阻塞问题。- 修复原代码缺陷:
- 修正了缩进错误(原代码中
if today语句不在while True块内) - 用
ticker not in stocks_list替代count,更高效且易读 - 修正时间格式为
%H:%M,确保和'04:00'的比较逻辑正确
- 修正了缩进错误(原代码中
- ib_insync消息机制适配:ib_insync依赖asyncio事件循环处理TWS的实时推送,阻塞主线程会导致这些推送无法被及时处理,进而出现持仓数据滞后、订单状态更新不及时等问题。
内容的提问来源于stack exchange,提问作者Hayden
相关产品推荐
相关产品推荐

