Limits
What a caller has to know before writing against ib_async-dx, sorted by what kind of thing it is: where ib_async on the engine behaves differently from ib_async over a gateway, what is taken and not applied, and what is the venue’s answer rather than this package’s.
ib_async runs as itself, so its calls, its arguments and its answers are its
own. What differs is what its IB reads off a transport with no socket
underneath, and what the engine does that a gateway does not. What a gateway
refuses is refused as a gateway refuses it, on errorEvent. What is taken and
not applied is named below, where it happens. Where the engine answers as a gateway does, and
a program might not expect it to, Running ib_async itself says
so.
Where it differs from a gateway
connectaddresses nothing.hostandportare accepted and not used, and the port does not choose paper or live: the session is paper unlessconnectis givenpaper=False.clientIdis carried into the login.- One program per login. Each program is its own session on the login, and a second program on the same login, or a gateway, takes the session from the first; the venue says which host took it. Programs that share one gateway login under their own client ids each need a login of their own here.
- Every session hears every order on the account, whatever its
clientId:trades(),openTrades(),reqOpenOrders()andopenOrderEventinclude the account’s orders placed elsewhere — in TWS, on the phone, or by a program under another client id. Over a gateway, a program is told of its own orders only, unless it connects as client 0 or as the gateway’s master client, or asks withreqAllOpenOrders(). - A request a gateway reroutes is refused. Asked for a quote or a book on
a contract the venue serves under another, a contract for difference
standing for a share among them, a gateway tells the program where to ask
instead, and ib_async, which has no handler for that, hears nothing. Here
the request is refused in the venue’s words, on
errorEvent. - A pass’s ticks reach a ticker in the engine’s order. The engine states
a quote’s prices before its sizes, and a price is handed over with the size
that goes with it, so the bid, ask and last a pass states land in
ticker.ticksafter the other ticks of that pass. The ticker’s fields end the pass as they would over a gateway. connectionStats()counts the messages each way, as ib_async’s client does: a request is one sent, and what reaches ib_async’s wrapper one received. Its byte counts are the session’s protocol bytes with the venue, as the engine counts them, where ib_async’s are the bytes on its socket to a gateway.- The engine checks each option list as a gateway checks it. On nine of
the eleven requests a gateway reads a list on —
reqMktData,placeOrder(the order’sorderMiscOptions),reqMktDepth,reqHistoricalData,reqScannerSubscription,reqRealTimeBars,reqNewsArticle,reqHistoricalNewsandreqHistoricalTicks— the one key taken ismanual, valued 0 or 1, and it changes nothing a gateway sends. The other two,calculateImpliedVolatilityandcalculateOptionPrice, take no key at all. An entry with no key or no value is refused with 320, a key the request does not take with 10337 and another value with 10338, onerrorEventunder the request’s number, and the request is not sent. Where the venue lifts the checks for the account (NOAPIMISCVLDamong itsenabledFeatures()), no key or value is refused on those grounds, and amanualthat does not read as the number 0 or 1 is still refused, with 321.reqFundamentalDatareads no list, as a gateway reads none:fundamentalDataOptionsis taken, and nothing in it is checked or applied. - An account named on an account request is checked as a gateway checks
it.
groupNameonreqAccountSummary, the account onreqAccountUpdates, and the account onreqPnLandreqPnLSingleare refused where a gateway refuses them, in its words. On a login holding one account, the account named onreqAccountUpdatesis ignored, as a gateway ignores it. On a login holding several, each request answers for the account it names, andAllonreqAccountSummaryfor every account the login holds.modelCode, an advisor group andAllNonPropare taken and not applied, and so isAllonreqPnL,reqPnLSingle,reqAccountUpdatesMultiandreqPositionsMulti, which answer for the session’s account; the engine logs a warning once per session saying so. IBClaunches nothing, and holds the login it names.ib_async_dx.IBCis ib_async’s with no gateway to launch: the engine logs in onconnect, and rebuilds a dropped connection on the session it already holds. Starting it holds itsuseridandpassword, on a live session wheretradingModeis'live'and on paper otherwise, as the gateway it would launch holds a login; a connect in the same context that names no login of its own logs in with it, and an emptyuseridorpasswordis read fromIB_USERNAMEorIB_PASSWORD. A login named onconnect, or given toattach, comes first. Terminating it ends every session that login opened, as stopping a gateway ends the sessions connected to it, and from whichever context it is terminated, no connect logs in with it afterwards. ib_async’s ownWatchdog, handed one, is a reconnect loop: it starts the IBC and connects itsIBin a task of its own, so eachWatchdoglogs in with its own IBC’s login, and when the session ends it connects again. Its probes and timeouts are ib_async’s own. A session that ends because another program or a gateway logged in on the same login is one theWatchdogconnects again, which takes it back. The paths, the Java settings and the FIX login are a gateway’s, and nothing reads them. Nor is IBC’s ownconfig.ini: a login or aTradingModekept there is not read, souseridandpasswordare given to theIBCor left to the environment, and atradingModeleft empty is paper. Where theIBC’s login is used, itstradingMode, notconnect’spaper, decides whether the session is live.
A restart is a new login
The session lives in the program’s process and ends with it. A gateway held
its login while a program restarted; here each start logs in, and on a live
account that login waits on the second factor. The session is kept in
~/.ib_dx/session-<user>-<paper|live> unless connect is given another
sessionFile, and a start naming a session the venue still holds is answered
with a challenge rather than a full login. The venue lets a session go soon
after its process ends, so that covers a quick restart only.
What ib_async itself does not have
reqCurrentTimeInMillisis in the documented API and not in ib_async.ib_async_dx.IBadds it, with its…Asynctwin; see Beyond ib_async.
The venue’s answer, not this package’s
These are the venue’s answers, as the engine’s sessions have met them, and none is something this package decides. They are written down because a program meeting one for the first time reads it as a fault here.
- Market depth depends on the entitlement. A venue the account is not entitled to refuses by name. A book asked for on no particular venue is acknowledged and then produces nothing, which is what an account with no aggregate entitlement is told. It does not error.
- News headlines and corporate events need subscriptions. Without a news subscription the providers list comes back and every query is empty; without a Wall Street Horizon subscription the calendar’s schema arrives and its events are empty.
- The protocol is not published. The venue can change it without notice.
The engine’s own limits — what it measures, and what no session has settled yet — are set out in ib-dx’s documentation.