feat(1.0): IBKR mock + IbTwsClient (ib_insync), tests#55
feat(1.0): IBKR mock + IbTwsClient (ib_insync), tests#55IamJasonBian wants to merge 3 commits intomainfrom
Conversation
- In-memory IBKR-style client: connect/disconnect, account summary tags, positions, MKT/LMT orders, optional market auto-fill, last-price test hooks - tests/brokers/test_ibkr_mock.py - trading_system.version and README/package.json bumped to 1.0.0 - Export __version__ from trading_system Made-with: Cursor
- IbTwsClient: connect to TWS (7496 paper / 7497 live), account values, positions, limit order, cancel by id - Event-loop bootstrap for ib_insync/eventkit on Python 3.10+ - Lazy-export IbTwsClient from brokers package to avoid import cost for mock-only - tests: unittest.mock for read/write; optional live tests (TWS_INTEGRATION, TWS_PLACE_ORDER) - requirements: ib_insync; pytest marker integration; README TWS section Made-with: Cursor
Made-with: Cursor
Code Review — PR #55Overall: Clean addition of an IBKR mock client and a live TWS client via Issues
Strengths
Generated by Claude Code |
Redundancy Review — PR #55Focused follow-up on redundant code patterns in this PR and across open branches. Within this PR
Cross-PR redundancy (branches #32, #53, #55)
RecommendationStart by extracting Generated by Claude Code |
Context
allocation-engine 1.0.0 adds broker-style plumbing: an offline mock and a real TWS / IB Gateway client (paper or live socket).
What was added
Offline
trading_system/brokers/ibkr_mock.py—MockIbkrClient: in-memory account tags, positions, MKT/LMT/canceltests/brokers/test_ibkr_mock.pyLive TWS (
ib_insync)trading_system/brokers/ib_tws_client.py—IbTwsClient/TwsClientConfig: connect, account values, positions, limit order, cancel by idrequirements.txt:ib_insynctrading_system/brokers/__init__.pyso mock-only imports stay cheap; event-loop bootstrap for Python 3.10+ /eventkittests/brokers/test_ib_tws_client_mocked.py— mocked read/write (no TWS)tests/brokers/test_ib_tws_live.py— optional live tests (TWS_INTEGRATION=1, optionalTWS_PLACE_ORDER=1on paper 7496 only)Note:
IbTwsClientcurrently exposes limit orders only (noMarketOrderwrapper). To trigger an immediate-style buy you either use a limit near the last price, extend the client withib_insync.MarketOrder, or drive MockIbkrClient for simulation.Version
trading_system/version.py,package.json, README 1.0.0; README Interactive Brokers (TWS API) sectionpytest.ini:integrationmarkerVerified
pytest tests/brokers/test_ibkr_mock.py— passpytest tests/brokers/test_ib_tws_client_mocked.py— passTWS_INTEGRATION=1 pytest tests/brokers/test_ib_tws_live.pywith TWS API enabledNote: full repo
pytest tests/may still have unrelated failures; broker tests are isolated.If a buy order does not trigger or submit (TWS / API)
Work through these in order; the TWS log (View → Message Log or API messages) often states the exact rejection reason.
Read-Only mode: false— keep it that way for orders)client_idper concurrent connection. If a stale Python process holds the id, TWS can reject; pick another (e.g. setTWS_CLIENT_IDin the live test env) or close the other appplace_limit_ordermust qualify the contract (qualifyContracts). If the symbol fails, check SMART vs required primary exchange, USDcurrencyfor US equities, and that the symbol exists (no typo)MarketOrderpath in code or place a limit at/through the last price and watch for a fillOrderif you add market/limit with extended hoursIbTwsClientdoes not yet wire intoExecutor/SafeCashBot; production buy paths still go through Robinhood in the rest of the repo. To “trigger a buy” from the trading engine you need a follow-up: injectIbTwsClient(or a shared protocol) into execution and mapTradeTask→place_limit_order/MarketOrderScreenshots (last two, 2026-04-22)
On-disk copies are in
docs/pr-55-attachments/on this branch (filenames:ibkr-tws-1.png,ibkr-tws-2.png).1. Gateway / TWS startup (04:19) — usfarm connect thread,
ndc1.ibllc.com:4000, first hop64.190.197.40, SSL on.2. API stream (04:22) — market/HMDS/secdef farms OK;
AccountCodeU24673021,AccountReadytrue,AccountTypeINDIVIDUAL, accrued fields 0.00 (BASE/USD) at capture time.Debug
If anything above blocks you, paste the exact message from TWS (order rejection / API) on the next PR and we can map it to a code or config change.