Interactive Brokers API(IBAPI)-使用threading.Timer对象在数据连接断开时自动退出

问题描述 投票:1回答:1

我一直在尝试一种机制,该机制请求实时数据(例如reqRealTimeBars),并在数据连接断开时自动使脚本退出。

我一直在用threading.Timer对象(https://docs.python.org/3/library/threading.html#timer-objects)进行测试,这在该方向上显示出良好的希望:例如,该脚本(如下)是一个无限循环,就像Eclient.run()一样,但是它会在3秒后退出,这与计时器预期的一样]

import threading
import time
import sys
import _thread

def exit():
    _thread.interrupt_main()

if __name__ == '__main__':
    t = threading.Timer(3.0, exit)
    t.start()
    while True:
        time.sleep(3)

但是,当我尝试将相同的逻辑应用于Eclient时,它似乎不起作用。下面是我的代码的简化版本。逻辑是在启动应用程序时,将计时器设置为具有10s的超时(或任何超过实时栏之间5s时间跨度的持续时间)。然后,每次接收到新的小节时,计时器都会被取消,然后以相同的超时时间重新创建。这意味着,除非与tws服务器的连接断开,否则代码通常不会达到超时。

要测试以下代码:tws,然后启动此脚本。它应该开始在控制台中打印数据。然后,手动关闭tws。这将断开连接。通常,在10秒钟之后,尚未“刷新”的计时器应触发exit功能并使程序停止,就像上面的示例一样。但是,它只是保持空闲状态,仍在等待传入的数据。如果有人可以看看,那真是太棒了。

我认为,这项技术可以使任何实时数据收集应用程序变得强大起来,是一种非常灵活和不错的方法。它只需要与每隔x分钟运行一次该脚本的cronjob结合,然后在开始时添加一些额外的逻辑,以防止它已经运行时再次运行。

from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.contract import Contract
from datetime import timedelta, datetime as dt

import threading
import _thread


def exit():
    _thread.interrupt_main()


class App(EWrapper, EClient):

    def __init__(self):
        EWrapper.__init__(self)
        EClient.__init__(self, wrapper=self)
        self.timeout = threading.Timer(10.0, exit)
        self.timeout.start()


    def realtimeBar( self, reqId, datetime, open_, high, low, close, volume, wap, count):
        bar = {
                'open' : open_,
                'high' : high,
                'low' : low,
                'close' : close,
                'volume' : volume
                }
        print(bar)  
        self.refresh_timeout(reqId)


    def refresh_timeout(self, reqId):
        self.timeout.cancel()
        self.timeout = threading.Timer(10.0, exit)
        self.timeout.start()


def make_contracts(app):
    contract  = Contract()
    contract.__dict__.update({'symbol' : 'CL', 'exchange' : 'NYMEX', 'secType': 'FUT', 'lastTradeDateOrContractMonth' : '202008'})
    app.reqRealTimeBars(i, contract, 5, "TRADES", 0, [])


if __name__ == '__main__':
    app = App()
    app.connect("127.0.0.1", 4002, clientId=0)
    make_contracts(app)
    app.run()

[请注意,我已经进行了尝试,将超时设置为<5s(例如3s)-在这种情况下,脚本确实退出了计时器……

我一直在尝试实现一种机制,该机制请求实时数据(例如reqRealTimeBars),并在数据连接断开的情况下自动使脚本退出。我一直在做测试...

python multithreading infinite-loop interactive-brokers ib-api
1个回答
0
投票

这实际上不是对所陈述问题的答案,但是对元问题的元答案是:使用ib-insync并感到高兴。

© www.soinside.com 2019 - 2024. All rights reserved.