Skip to content

Commit

Permalink
Fixing the issue with TWS API Bust events (err code 10225) (#396)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladisld authored May 28, 2020
1 parent f1bc0cf commit 26b2654
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
19 changes: 17 additions & 2 deletions backtrader/feeds/ibdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def start(self):
else:
self._state = self._ST_START # initial state for _load
self._statelivereconn = False # if reconnecting in live state
self._subcription_valid = False # subscription state
self._storedmsg = dict() # keep pending live message (under None)

if not self.ib.connected():
Expand Down Expand Up @@ -410,14 +411,15 @@ def stop(self):

def reqdata(self):
'''request real-time data. checks cash vs non-cash) and param useRT'''
if self.contract is None:
if self.contract is None or self._subcription_valid:
return

if self._usertvol:
self.qlive = self.ib.reqMktData(self.contract, self.p.what)
else:
self.qlive = self.ib.reqRealTimeBars(self.contract)

self._subcription_valid = True
return self.qlive

def canceldata(self):
Expand Down Expand Up @@ -446,7 +448,7 @@ def _load(self):
if True:
return None

# Code invalidated until further checking is done
# Code invalidated until further checking is done
if not self._statelivereconn:
return None # indicate timeout situation

Expand All @@ -473,6 +475,7 @@ def _load(self):
continue # to reenter the loop and hit st_historback

if msg is None: # Conn broken during historical/backfilling
self._subcription_valid = False
self.put_notification(self.CONNBROKEN)
# Try to reconnect
if not self.ib.reconnect(resub=True):
Expand All @@ -489,6 +492,7 @@ def _load(self):
elif msg == -1100: # conn broken
# Tell to wait for a message to do a backfill
# self._state = self._ST_DISCONN
self._subcription_valid = False
self._statelivereconn = self.p.backfill
continue

Expand All @@ -500,6 +504,14 @@ def _load(self):

elif msg == -1101: # conn broken/restored tickerId gone
# The message may be duplicated
self._subcription_valid = False
if not self._statelivereconn:
self._statelivereconn = self.p.backfill
self.reqdata() # resubscribe
continue

elif msg == -10225: # Bust event occurred, current subscription is deactivated.
self._subcription_valid = False
if not self._statelivereconn:
self._statelivereconn = self.p.backfill
self.reqdata() # resubscribe
Expand Down Expand Up @@ -561,14 +573,17 @@ def _load(self):
msg = self.qhist.get()
if msg is None: # Conn broken during historical/backfilling
# Situation not managed. Simply bail out
self._subcription_valid = False
self.put_notification(self.DISCONNECTED)
return False # error management cancelled the queue

elif msg == -354: # Data not subscribed
self._subcription_valid = False
self.put_notification(self.NOTSUBSCRIBED)
return False

elif msg == -420: # No permissions for the data
self._subcription_valid = False
self.put_notification(self.NOTSUBSCRIBED)
return False

Expand Down
10 changes: 10 additions & 0 deletions backtrader/stores/ibstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,16 @@ def error(self, msg):
q.put(-msg.errorCode)
self.cancelQueue(q)

elif msg.errorCode == 10225:
# 10225-Bust event occurred, current subscription is deactivated.
# Please resubscribe real-time bars immediately.
try:
q = self.qs[msg.id]
except KeyError:
pass # should not happend but it can
else:
q.put(-msg.errorCode)

elif msg.errorCode == 326: # not recoverable, clientId in use
self.dontreconnect = True
self.conn.disconnect()
Expand Down

0 comments on commit 26b2654

Please sign in to comment.