Skip to content

refactor: Unified Trading Account (UTA) + IBKR type system#67

Merged
luokerenx4 merged 14 commits intomasterfrom
dev
Mar 16, 2026
Merged

refactor: Unified Trading Account (UTA) + IBKR type system#67
luokerenx4 merged 14 commits intomasterfrom
dev

Conversation

@luokerenx4
Copy link
Copy Markdown
Contributor

Summary

  • Introduce UnifiedTradingAccount (UTA) class — consolidates broker + git + guards into a single business entity
  • Use IBKR types (@traderalice/ibkr) as the single source of truth for all trading types (Contract, Order, Execution, OrderState)
  • Rename ITradingAccountIBroker, providers/brokers/
  • Delete scattered wireAccountTrading() + AccountResolver + external Map pattern
  • Inline operation-dispatcher and wallet-state-bridge into UTA
  • Slim adapter.ts from 744 to ~300 lines (pure AI tool shell)
  • Add comprehensive test coverage: 71 broker tests, 36 UTA tests
  • Include spec files in tsc typecheck, fix all type errors
  • Align frontend types with IBKR-renamed backend fields
  • Update README with UTA architecture documentation

Stats

13 commits, 62 files changed, +3719 / -3813 (net -94 lines)

Test plan

  • npx tsc --noEmit — zero errors (including spec files)
  • npx vitest run — 820 tests passing
  • Frontend typecheck clean
  • Portfolio page renders with new field names

🤖 Generated with Claude Code

luokerenx4 and others added 14 commits March 16, 2026 13:53
Replace Alice's custom trading types (OrderRequest, Order, Contract, etc.)
with IBKR types from @traderalice/ibkr as the single source of truth.

Key changes:
- Delete contract.ts replica, use IBKR Contract class directly
- Add contract-ext.ts declaration merge for aliceId on IBKR Contract
- Operation becomes discriminated union (no more Record<string, unknown>)
- ITradingAccount.placeOrder takes (Contract, Order) instead of OrderRequest
- Position/AccountInfo field names aligned to IBKR conventions
- operation-dispatcher simplified from 120 to 30 lines (no more `as` casts)
- Alpaca and CCXT providers adapted to read IBKR Order fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ker, CcxtAccount → CcxtBroker

Broker connection layer renamed to avoid naming collision with upcoming
TradingAccount (UTA) class. From UTA's perspective, the execution layer
is a broker — it places orders, queries positions, and talks to exchanges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UTA consolidates broker + git + guards into a single business entity.
Replaces the scattered wireAccountTrading() + AccountSetup tuple +
external Map<string, AccountSetup> pattern.

- New UnifiedTradingAccount class owns TradingGit, guards, and broker
- Business methods (stagePlaceOrder, commit, push) live on UTA
- AccountManager now manages UTA[] instead of IBroker[]
- Source routing (resolve/resolveOne) moved to AccountManager
- adapter.ts slimmed from 744 to 300 lines (pure AI tool shell)
- factory.ts deleted (logic absorbed into UTA constructor)
- main.ts no longer maintains external accountSetups Map

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns folder name with IBroker interface naming convention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- interfaces.ts → brokers/types.ts (IBroker, Position, AccountInfo, etc.)
- platform.ts + platform-factory.ts → brokers/factory.ts (IPlatform + config helpers)
- brokers/index.ts controls all exports
- createAccountFromConfig renamed to createBrokerFromConfig
- Old root-level interfaces.ts, platform.ts, platform-factory.ts deleted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Coverage goes from 34 to 71 tests across both brokers.
All IBroker interface methods now have at least one happy-path
and one error-path test case.

New test areas: getContractDetails, modifyOrder, cancelOrder,
closePosition, getAccount, getOrders, getQuote, getMarketClock,
getCapabilities, getPositions (CCXT), close (CCXT).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove **/*.spec.ts from tsconfig exclude so tsc covers tests
- Fix mock module import paths (./types → ../types, ../core → ../../core)
- Add missing required fields in spec files (paper, sandbox, guards)
- Add non-null assertions for possibly-undefined values in specs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ive tests

- Inline operation-dispatcher and wallet-state-bridge into UTA constructor
- Delete standalone files (operation-dispatcher.ts, wallet-state-bridge.ts)
- Migrate existing tests to UnifiedTradingAccount.spec.ts
- Add 25 new tests covering: stagePlaceOrder IBKR field mapping,
  stageModifyOrder, stageClosePosition, stageCancelOrder, git flow
  edge cases, sync, guards rejection/pass, savedState restore
- UTA test coverage: 11 → 36 tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getOperationSymbol and formatOperationChange crashed on old-format
commits that stored params instead of IBKR Contract/Order objects.
Added ?. guards so log/show gracefully return 'unknown' instead of
throwing. Also deleted all old-format commit.json files from data/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Trading routes use UTA directly via accountManager.get() instead of
  ctx.getAccountGit() indirection
- Remove getAccountGit from EngineContext interface and main.ts
- Add optional chaining in getOperationSymbol and formatOperationChange
  for resilience against old-format commits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Position: qty→quantity (string), avgEntryPrice→avgCost,
currentPrice→marketPrice, remove unrealizedPnLPercent (compute inline),
remove costBasis, add realizedPnL, leverage now optional.

AccountInfo: cash→totalCashValue, equity→netLiquidation,
remove portfolioValue/totalMargin/dayTradeCount, add margin fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- undici 7.22→7.24.4 (6 CVEs: WebSocket crashes, CRLF injection, HTTP smuggling)
- file-type 21.3.0→21.3.2 (2 CVEs: ZIP bomb, ASF parser loop)
- @modelcontextprotocol/sdk 1.26→1.27.1
- pnpm overrides: force alpaca axios to 0.30.3, strip its runtime eslint dep
- Also upgrade undici in opentypebb subpackage

Remaining 2: rollup (tsup dep), express-rate-limit (mcp-sdk dep) — waiting on upstream.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The ibkr package exports from ./dist/ and needs to be built before
Vitest can resolve it. Add it to the build chain alongside opentypebb.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@luokerenx4 luokerenx4 merged commit de43197 into master Mar 16, 2026
2 checks passed
@luokerenx4 luokerenx4 deleted the dev branch March 16, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant