繁体   English   中英

盈透证券 API (IBAPI) - 使用 threading.Timer object 在数据连接中断时自动退出

[英]Interactive Brokers API (IBAPI) - Using threading.Timer object to auto exit when the data connection is broken

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

我一直在用threading.Timer object ( https://docs.python.org/3/library/that script显示脚本很好的方向) ) 就像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 本身时,它似乎不起作用。 下面是我的代码的简化版本。 逻辑是当应用程序启动时,定时器设置为 10 秒(或任何超过实时条之间 5 秒时间跨度的持续时间)的超时。 然后每次收到一个新柱时,计时器被取消,然后以相同的超时重新创建。 这意味着通常代码永远不会达到超时,除非与 tws 服务器的连接中断。

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

我认为这种技术可能是一种非常灵活且很好的方法,可以使任何实时数据收集应用程序变得健壮。 它只需要与每 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)的值 - 在这种情况下,脚本确实将 thx 退出到计时器......

这并不是对上述问题的真正答案,但对元问题的元答案是:使用ib-insync并快乐。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM