Skip to content

feat: support IBKR spot FX orders - #105

Merged
felipecsl merged 1 commit into
mainfrom
feat/fx-orders
Sep 28, 2026
Merged

felipecsl merged 1 commit into
mainfrom
feat/fx-orders

Conversation

@felipecsl

Copy link
Copy Markdown
Member

Summary

Closes #104. This covers CLI layers 2–4 of the issue. It uses @huskly/ibkr-gateway-client 0.18.0 (huskly/ibkr-gateway#106), which runs on @huskly/ibkr-client 4.1.0 (huskly/ibkr-client#134).

  • fx preview <pair> <side> <quantity> --limit <price> [--tif DAY|GTC] [--json] and fx submit <preview-id> --confirm [--operator] [--json]. The broker is IBKR only; --broker schwab fails with "FX orders are available for IBKR only."
  • src/forex/:
    • forexPair.ts accepts USD.JPY, USD/JPY, and USDJPY, and refuses bad codes and a pair whose base equals its quote.
    • forexOrder.ts holds the types and the canonical intent schema.
    • forexGatewayAdapter.ts and forexOrderService.ts implement the flow: LMT only, whole base-currency units, DAY/GTC, and no session.
  • Shared workflow, not a copy: src/orders/singleOrderWorkflow.ts holds the preview store, expiry, content-hash ID, idempotent submit, and recovery. The equity and FX services both use it. src/cli/guardedOrderCommands.ts holds the shared CLI parts (broker flag, side/TIF parsing, --confirm, and warning acknowledgement).
  • MCP: fx_order_preview and fx_order_submit take the same inputs as the CLI.
  • Formatting:
    • formatMoney(value, currencyCode, digits?) is new, and currencyFormatUsd is now a wrapper around it.
    • formatForexPrice shows a limit in the quote currency with FX precision, for example ¥147.255.
    • Quantities are in the base currency, and What-If amounts are in the account base currency that the gateway states.
    • orders shows FX prices and average fills in the quote currency, taken from the BASE.QUOTE leg, and never with $. The Current column stays - for FX; FX quotes are a later layer.
  • Order reads: the IBKR order leg schema accepts CASH. Before this change, orders would fail once an FX order existed.
  • Status, recovery, reconcile, cancel: the existing order commands handle these. The shared execution store accepts the FX intent.

Fixes found on the way

  • isOptionIntent treated every non-STK single record as an option, so it would also have claimed FX records. It now matches OPT/FOP only.
  • Gateway 0.18.0 adds currency to every preview response. The strict spread-preview schema would have rejected it, so the derivative preview result, schema, and DTO now carry currency too.

Not in scope

  • Layer 5: STP FX orders and FX quotes in quote --broker ibkr.
  • The FX "odd lot" check has no threshold in the CLI. The preview shows the IBKR warning as the broker states it.

Tests

  • test/forex/forexPair.test.ts: valid pairs, USDJPY, USD/JPY, bad codes, and a same-currency pair.
  • test/forex/forexOrderService.test.ts: contract mismatch, bad terms, odd-lot warning, preview expiry, idempotent submit, uncertain-write recovery, and separation from equity records in the shared store.
  • test/cli/forexOrders.test.ts: Schwab rejection, the --json DTO shape, JPY price formatting, and input validation.
  • test/mcp/forexOrders.test.ts, test/format.test.ts, and an FX case in test/cli/orders.test.ts.
  • yarn check passes (357 tests), and yarn build passes.

I did not run a live preview. The local gateway credentials fail authentication on main too.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-09-25T18:43:52.181907Z 772ce99 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@felipecsl
felipecsl merged commit 6495210 into main Sep 28, 2026
1 check passed
@felipecsl
felipecsl deleted the feat/fx-orders branch September 28, 2026 01:06
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.

Support IBKR spot FX orders (e.g. USD.JPY)

1 participant