fix: IBKR contract identity + E2E improvements#82
Merged
luokerenx4 merged 6 commits intomasterfrom Mar 22, 2026
Merged
Conversation
Upstream layers (staging, AI tools) construct thin contracts with only symbol populated. TWS rejects orders/queries missing exchange and currency. Default to SMART routing and USD — non-USD markets and forex will need explicit currency from the caller. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
IBroker now declares getNativeKey(contract) and resolveNativeKey(key) so each broker defines its own uniqueness semantics: - Alpaca: ticker symbol - CCXT: unified market symbol (ETH/USDT:USDT) - IBKR: conId (globally unique numeric ID) UTA's stampAliceId and stagePlaceOrder/stageClosePosition now delegate to broker instead of guessing symbol/localSymbol. Fixes IBKR orders being rejected due to missing secType/exchange/currency — conId alone is sufficient for TWS to resolve the full contract. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… connections - getMarketClock: try reqCurrentTime with 3s timeout, fallback to local time if TWS doesn't respond. TODO: per-contract tradingHours query. - vitest.e2e.config: use pool=forks + singleFork so all E2E files share a single process. Module-level broker singletons (setup.ts) now actually share state — fixes IBKR clientId collision on second connection attempt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add limit order place → query → cancel tests for IBKR and Alpaca brokers, plus UTA-level limit order stage → push → cancel tests. These run any time (exchanges accept limit orders outside trading hours). Existing market order / fill tests remain under market hours guard. Three-tier E2E structure: 1. Connectivity — any time 2. Order lifecycle — any time (limit orders) 3. Fill + position — market hours only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eKey IBKR tests now discover contracts via searchContracts to get conId, then build aliceId using broker.getNativeKey() — matching the real AI workflow. Alpaca tests also unified to use getNativeKey for consistency. resolveNativeKey string fallback adds secType='STK' for legacy symbol-based aliceIds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
getNativeKey()andresolveNativeKey()— IBKR uses conId (globally unique), Alpaca uses ticker, CCXT uses unified symbol. UTA delegates to broker instead of guessing symbol/localSymbol.Test plan
pnpm buildpassespnpm test— 880 tests passpnpm test:e2e— 39 passed, 12 skipped (fill tests skip outside market hours)🤖 Generated with Claude Code