2

私は、ライブ データ (など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 に適用しようとすると、うまくいかないようです。以下に、私のコードの簡略版を示します。ロジックは、アプリの起動時にタイマーが 10 秒 (またはリアルタイム バー間の 5 秒のタイムスパンよりも長い時間) のタイムアウトで設定されることです。その後、新しいバーが受信されるたびに、タイマーがキャンセルされ、同じタイムアウトで再作成されます。これは、通常、tws サーバーとの接続が切断されない限り、コードがタイムアウトに達することはないことを意味します。

以下のコードをテストするには、tws を開始してから、このスクリプトを開始します。コンソールでデータの出力を開始する必要があります。次に、tws を手動で閉じます。それは接続を切断します。exit通常、上記の例のように、「リフレッシュ」されていないタイマーが 10 秒後に関数をトリガーし、プログラムを停止させる必要があります。ただし、アイドル状態のままで、着信データを待機しています。誰かが見ることができれば、それは素晴らしいことです。

この手法は、ライブデータ収集アプリを堅牢にするための非常に機敏で優れた方法になると思います。そのスクリプトを x 分ごとに実行する cronjob と結合する必要があるだけであり、最初に追加のロジックを追加して、既に実行されている場合に 2 回目の実行を防止します。

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()

タイムアウトを5秒未満の値(たとえば3秒)に設定する試行を行ったことに注意してください-この場合、スクリプトはthxを終了してタイマーに...

4

1 に答える 1