Skip to main content

Protocol internals and extension boundary

ib_async implements the IB binary socket protocol directly; it does not wrap the official Python ibapi client. The high-level path is:

IB method -> Client encoder/throttled socket -> TWS/IBG
TWS/IBG -> Connection bytes -> Decoder -> Wrapper callback -> synchronized objects/events/futures

Client performs the version handshake, prefixes messages with a four-byte length, allocates IDs, applies throttling, encodes fields conditionally by server version, and emits socket lifecycle events. Decoder maps incoming message IDs and fields into Wrapper callback calls. Wrapper owns request futures/subscription containers and the synchronized object graph. IB pairs those pieces into blocking/async requests and ergonomic state access.

Server-version gatingโ€‹

Fields and requests are conditional on the negotiated server version. A current ib_async can connect to older TWS only within its supported min/max protocol range; newer fields are omitted or calls fail when the server is too old. Error 503 means TWS/IBG is too old for the API negotiation or operation.

Never patch an encoder by merely appending a field. Wire field position, version gates, unset encoding, and decoder symmetry must match IBKR's protocol. A misplaced field corrupts the rest of the message.

Public versus low-level APIsโ€‹

Use IB unless implementing a missing high-level wrapper. Client exposes nearly every outbound TWS API message but requires caller-managed request IDs and callback correlation. Wrapper methods are callback targets, not request methods. Subclassing Wrapper without preserving its state updates can silently break IB futures and events.

Private underscore members and decoder.py are not stable application APIs. They are omitted from the generated public reference by design. connection, client, and wrapper are documented because advanced integrations may legitimately inspect or extend them, but their surface is lower stability than IB.

Adding a missing endpoint safelyโ€‹

  1. Identify the official request, response callbacks, minimum server version, and field order.
  2. Add/version-gate the client encoder.
  3. Add decoder mapping and wrapper callbacks.
  4. Register request futures/subscriptions and cancellation cleanup.
  5. Expose an IB method without caller-supplied request ID.
  6. Test captured message fixtures, partial/invalid responses, errors, end callbacks, cancellation, disconnect, and duplicate callbacks.
  7. Regenerate this reference and document server-side limitations.

The exhaustive Client and Wrapper pages are useful protocol maps; they should not be read as a promise that every raw callback is safe to call directly.