Duplicate order ID
See original GitHub issueI have run into this problem (with latest 0.9.63, but also if running with 0.9.62 from a poetry environment i still hold without updating to latest version).
The strange thing is that this is happening in a piece of software I did not touch in the last days (and worked perfectly fine on previous days), and started to show this problem yesterday, each time I create a new order from there. Rebooting the TWS and my piece of software didn’t help. Moreover, other users are successfully running this software without this error, both of us with latest TWS. I also reviewed TWS API settings, but nothing seemed out of place.
The error:
Canceled order: Trade(contract=Contract(secType='BAG', symbol='NVDA', exchange='SMART', currency='USD', comboLegs=[ComboLeg(conId=405841033, ratio=1, action='SELL', exchange='', openClose=0, shortSaleSlot=0, designatedLocation='', exemptCode=-1), ComboLeg(conId=446712248, ratio=1, action='BUY', exchange='', openClose=0, shortSaleSlot=0, designatedLocation='', exemptCode=-1)]), order=LimitOrder(orderId=322, clientId=20, action='BUY', totalQuantity=10, lmtPrice=0.05, transmit=False), orderStatus=OrderStatus(orderId=322, status='Cancelled', filled=0, remaining=0, avgFillPrice=0.0, permId=0, parentId=0, lastFillPrice=0.0, clientId=0, whyHeld='', mktCapPrice=0.0), fills=[], log=[TradeLogEntry(time=datetime.datetime(2020, 10, 29, 13, 17, 40, 708901, tzinfo=datetime.timezone.utc), status='PendingSubmit', message=''), TradeLogEntry(time=datetime.datetime(2020, 10, 29, 13, 18, 1, 982503, tzinfo=datetime.timezone.utc), status='Cancelled', message='Error 103, reqId 322: Duplicate order id')])
Error 103, reqId 325: Duplicate order id
I am not specifying reqIds: I am letting ib_insync take care of this.
I coded a minimal example which (at least in my case) reproduces the problem:
from ib_insync import IB, ComboLeg, Contract, LimitOrder
ib = IB()
ib.client.setConnectOptions('+PACEAPI')
ib.client.MaxRequests = 0 # Disables throttling
ib.connect('127.0.0.1', 7496, clientId=20)
combo = Contract(symbol='NVDA', secType='BAG', exchange='SMART', currency='USD', comboLegs=[
ComboLeg(conId=448268928, ratio=1, action='SELL'),
ComboLeg(conId=441119400, ratio=1, action='BUY')
])
# Create the order and launch a Trade referred to the option combo contract
#limit_order = LimitOrder('BUY', 2, 0.0, transmit=False, displaySize=1)
limit_order = LimitOrder('BUY', 1, 0.0, transmit=False)
ib.placeOrder(combo, limit_order)
ib.sleep(5)
ib.disconnect()
print('Done!')
Of course this happens also with any other combo, just using the same conId in the example for simplicity. How can I further investigate this problem?
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Ran into this recently and it looks like there’s a simple fix!
After initial connect, the max ID is being set here instead of using the proper API’s max value:
https://github.com/erdewit/ib_insync/blob/2c669c49759428760b85c5d4f6629cb31a13fbcc/ib_insync/wrapper.py#L373
Example of the error:
client.reqIds(0)
returns 566 because I have many canceled orders (due to API testing, etc).After my fix below, on startup the max request id is set properly to 566 and increments from there. (It appears the IBKR backend is only incrementing the minimum
reqId
value for trade requests and not market data requests too?)So the fix is to make
_reqIdSeq
initialization wait on a flag for the server-side max ID instead of assuming the highest current order ID is the maximum ID in the system (since it can’t see canceled orders, but those still consumed IDs which can’t repeat):(optionally, the
setId
could also be an instance variable onClient
itself if there’s a potential race condition between receiving both theself.accounts
update and thereqId
out of order)This can only happen if an order is sent when
ib.connect()
is not finished yet, which is not advisable. Afterib.connect()
has finished, all completed and open orders have been synchronized.