ib_async
ib_async copied to clipboard
How to stop an ib_async script without causing IBGateway issues.
The problem that I am having goes something like this:
- Open IBGateway and authenticate
- Run my program which uses
reqHistoricalDatawithkeepUpToDate=True - Program runs fine and data stream is kept up-to-date as expected
- Stop program using keyboard interrupt (ctrl+c)
- Run program again
- Wait for about 1 minute
- Receive error message:
Error 162, reqId 4403: Historical Market Data Service error message:API historical data query cancelled: 4403, contract: Future(conId=603558932, symbol='ES', lastTradeDateOrContractMonth='20250321', multiplier='50', exchange='CME', currency='USD', localSymbol='ESH5', tradingClass='ES') - Close IBGateway, then go back to step 1
How can I stop my program at-will without screwing up whatever is going on behind the scenes in the Gateway? Has anyone else had this issue before?
please check this notebook https://nbviewer.org/github/ib-api-reloaded/ib_async/blob/main/notebooks/basics.ipynb at the end it shows how to disconnect.
and the API documentation for disconnect
That is an odd situation because the gateway should be releasing all data requests/subscriptions/resources when your client disconnects from the gateway.
Feel free send a more complete example, but I don't see how the gateway would be the problem here.
Another potential cause: IBKR does enforce account-wide "pacing limitations" for trying to access too much market data too quickly, so if you start->stop->start->stop the same data feed many times (even across restarts), it's possible their upstream rate limiting is stopping new requests until the server-side service timeout resets your permissions again.
Thanks all for the replies. I think this stems somehow from how I am stopping my program. For testing/debugging, I need a way to stop the program ad-hoc, and I have been using ctrl+c to interrupt and stop the program. To test if this was the factor which is causing these problems, I wrote a simple test script:
from ib_async import *
if __name__ == '__main__':
try:
ib = IB()
ib.connect(port=7496)
contract = Future(symbol="ES", lastTradeDateOrContractMonth="202503", exchange="CME")
hist_data = ib.reqHistoricalData(
contract, endDateTime="", durationStr="2 D", barSizeSetting="5 secs",
whatToShow="TRADES", useRTH=False) # keepUpToDate=True
df = util.df(hist_data)
print(df)
finally:
ib.disconnect()
As long as I don't interrupt the program with ctr+c, I can run this simple script over and over again. I believe this rules out the rate-limit hypothesis. Additionally, I don't think I am ever hitting the limits described in the docs.
The problem comes when I run this program but interrupt it before it comes to a stop. Re-running after interrupting the program causes the error I described in my initial post. The only way to reconnect is to close the Gateway, re-open it, and log back in.
I don't really know what to make of this... is there a "safe" way to stop the program while its running?
One of my scripts also uses reqHistoricalData with keepUpToDate=True.
To catch an user interrupt resp. CTRL + C, I always insert an except like this:
try:
...
ib.connect()
...
except KeyboardInterrupt:
ib.disconnect()
print("Abborted")
exit()
Maybe this helps... I have never had your problem.
Thank you @August1328! Specifically catching the KeyboardInterrupt seems to have solved my problem. Maybe my understanding of how try... finally works is flawed, but I thought finally would execute no matter what.
Glad to hear.
I was just looking through the docs... Shall we add an example to the documentation, how to avoid issues if you use try? For example in the 'Code recipes' page? I am not familiar how to make changes to a repo, but I can give it a try.