execution: implement IbkrAdapter venue adapter#14
Merged
marwinsteiner merged 7 commits intomainfrom Feb 22, 2026
Merged
Conversation
Add IbkrAdapter class with NotImplementedError stubs for all VenueAdapter ABC methods. Includes status mapping (_IB_STATUS_MAP), _require_ib helper, properties (name, is_connected, supported_order_types), and test wireframe with 14 passing tests covering properties and status mapping. Add ib_async as optional dependency (sysls[ibkr]) and dev dependency.
Implement connect() with ib_async import guard (raises SyslsConnectionError if not installed), async connectAsync call with host/port/clientId/account params, and error wrapping for connection failures. Implement disconnect() that calls ib.disconnect() and clears state, safe to call multiple times. 7 new tests covering connect success, account param, import error, connection failure, disconnect, disconnect-when-not-connected, and async context manager.
Implement _to_ib_contract() mapping sysls Instrument to ib_async Contract subclasses: Stock (equity), Option (with space-separated symbol parsing for underlying/expiry/strike/right), Future, and Forex (CRYPTO_SPOT, uses IDEALPRO exchange). Unsupported asset classes raise OrderError. Implement _to_ib_order() mapping OrderRequest to ib_async Order subclasses: MarketOrder, LimitOrder, StopOrder, StopLimitOrder. Validates required price fields and raises OrderError for missing values. 15 new tests covering all contract types, order types, edge cases, and error conditions.
Implement submit_order() that builds ib_async Contract + Order from sysls types, calls placeOrder via asyncio.to_thread, emits OrderAccepted on the bus, and returns the venue order ID. Implement cancel_order() that looks up the trade by orderId in openTrades(), calls cancelOrder via asyncio.to_thread, and emits OrderCancelled. Raises OrderError if the order is not found. Implement get_order_status() that searches trades() by orderId and maps the IB status string. Add _wrap_ib_error() helper mapping Python exception types to sysls exceptions (ConnectionError/OSError -> SyslsConnectionError, ValueError -> OrderError, others -> VenueError). 7 new tests covering submit, submit error, not-connected, cancel, cancel-not-found, get_order_status found/not-found.
Implement get_positions() that calls ib.positions() via asyncio.to_thread, builds Instrument from each contract using _build_instrument_from_contract, and skips zero-quantity positions. Supports STK, OPT, FUT, CASH contract types mapped to sysls AssetClass. Implement get_balances() that calls ib.accountValues() via asyncio.to_thread, filters for CashBalance tags (excluding BASE currency), parses Decimal values, and skips zeros. Add _build_instrument_from_contract() helper with _SEC_TYPE_MAP mapping IB secType strings to AssetClass. Extracts multiplier from contract. 11 new tests covering instrument building (5 contract types), positions (empty, long, short, skip-zero), and balances (filtered, empty).
Add comprehensive error wrapping tests covering all exception type mappings: ConnectionError/OSError/TimeoutError -> SyslsConnectionError, ValueError -> OrderError, RuntimeError -> VenueError. Add edge case tests for invalid Decimal parsing in get_balances() and multiple instruments in get_positions(). Total: 61 tests, all passing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements
IbkrAdapter(VenueAdapter)-- a thin translation layer between sysls's normalized order types and Interactive Brokers TWS/Gateway API via theib_asynclibrary (successor toib_insync).What's included
connectAsync()with import guard, host/port/clientId/account params,SyslsConnectionErrorwrapping_to_ib_contract): maps sysls Instrument to ib_async Stock, Option (with space-separated symbol parsing), Future, Forex_to_ib_order): maps OrderRequest to MarketOrder, LimitOrder, StopOrder, StopLimitOrder with price validationplaceOrderviaasyncio.to_thread, emitsOrderAcceptedon busopenTrades(), callscancelOrder, emitsOrderCancelledtrades()by orderId, maps IB status strings via_IB_STATUS_MAPib.positions(), builds Instrument from contract (STK/OPT/FUT/CASH), skips zerosib.accountValues(), filters CashBalance tags, parses Decimal, excludes BASE_wrap_ib_error): ConnectionError/OSError/TimeoutError -> SyslsConnectionError, ValueError -> OrderError, others -> VenueErrorib_async>=1.0as optional dep (sysls[ibkr]) and dev dependencyChanges
src/sysls/execution/venues/ibkr.py-- 536 lines (new)tests/execution/test_ibkr.py-- 1029 lines (new), 61 testspyproject.toml-- 2 lines changedCommits (6 atomic)
execution: add IBKR adapter wireframe with stubsexecution: implement IbkrAdapter connect/disconnect lifecycleexecution: implement IBKR contract and order building helpersexecution: implement IBKR submit_order and cancel_orderexecution: implement IBKR get_positions and get_balancesexecution: add IBKR error wrapping and edge case testsTest plan
uv run pytest tests/execution/test_ibkr.py -v)ruff check src/ tests/-- cleanruff format --check src/ tests/-- cleanib_async-- no real TWS/Gateway connection needed