erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.86k stars 780 forks source link

Watchdog probe causes Hard timeout when using paper mode due to "No market data permissions for IDEALPRO CASH" #298

Closed Snowhit3 closed 4 years ago

Snowhit3 commented 4 years ago

The line highlighted in the snippet below (from ibcontroller.py) causes TWS/gateway to restart when run in paper mode as IB complaints there are no market data permissions for EURUSD:

ERROR - ib_insync.wrapper - wrapper.py:981 - error() - Error 162, reqId 282: Historical Market Data Service error message:No market data permissions for IDEALPRO CASH, contract: Forex('EURUSD', exchange='IDEALPRO')
WARNING - ib_insync.Watchdog - ibcontroller.py:446 - runAsync() - Hard timeout
INFO - ib_insync.IBC - ibcontroller.py:165 - terminateAsync() - Terminating
SUCCESS: The process with PID 17500 (child process of PID 18096) has been terminated.
SUCCESS: The process with PID 18096 (child process of PID 2328) has been terminated.

It is therefore not possible to test a program using watchdog with a paper account before starting to use it with in live mode.

What other requests could be used in place of reqHistoricalDataAsync() to check that the application is alive while avoiding market data requests?

while self._runner:
    waiter = asyncio.Future()
    await waiter
    # soft timeout, probe the app with a historical request
    self._logger.debug('Soft timeout')
    self.softTimeoutEvent.emit(self)
    probe = self.ib.reqHistoricalDataAsync(
        Forex('EURUSD'), '', '30 S', '5 secs',
        'MIDPOINT', False)
    bars = None
    with suppress(asyncio.TimeoutError):
        bars = await asyncio.wait_for(probe, 4)
    if not bars:
        self.hardTimeoutEvent.emit(self) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        raise Warning('Hard timeout')
    self.ib.setTimeout(self.appTimeout)
erdewit commented 4 years ago

What other requests could be used in place of reqHistoricalDataAsync() to check that the application is alive while avoiding market data requests?

This type of request is used to specifically test if the data servers are up and running. A contract search for example can still succeed when the data servers are down, this is all handled by different servers in IB's backend.

When I wrote this code the assumption was that everyone has access to the EURUSD data. It appears that there are exceptions where this does not hold (for New Zealanders?). What can be done is to make the contract configurable.

erdewit commented 4 years ago

A Watchdog.probeContract field has been added to be able to specify what contract to use instead of EURUSD.