Repository navigation
feat(trade): add US asset APIs and make fund/margin calls AP-only - #613
Merged
Merged
Conversation
US data-center accounts have no fund holdings or margin-ratio data, so these calls now fail fast with a region error instead of an opaque server error. Document the restriction in the Rust, C, C++ and Java method docs.
Add four US-only TradeContext methods (async + blocking), all behind dc_restrict(DcRegion::Us): - us_cash_and_buy_power: GET /v1/us/assets/cash-and-buy-power - us_available_holding: GET /v1/us/assets/available-holding - us_transaction_history: POST /v1/us/assets/transaction-history - us_exchange_rates: GET /v1/us/assets/exchange-rates The exchange-rate response is a two-level map upstream; flatten it into a sorted list that keeps both map keys on each entry.
- Python: sync and async methods, result classes, and openapi.pyi stubs - Node.js: napi methods, result types and GetUSTransactionHistoryOptions; regenerate index.d.ts - Java: JNI entry points returning JSON, like the existing US stubs - Note the AP-only restriction on fund_positions and margin_ratio in the Python and Node.js docs
The gateway's counterID2Symbol transform adds symbol and keeps counter_id, so the counter_id alias on USTransaction.symbol made serde fail with a duplicate-field error on real responses. Also document what the two exchange-rate map keys are (account channel and rate type), confirmed against US prod responses.
This was referenced Oct 22, 2026
Merged
Merged
# Conflicts: # CHANGELOG.md
GET /v1/us/assets/overview returns crypto_list entries with the same fields as stock_list (quantity, market, name, prices, today_pl, ...), but USCryptoEntry only kept five of them, so a crypto holding had no quantity. Mirror the stock entry's fields in Rust, Python and Node.js, correct the symbol doc (bare pair code such as BTCUSD; the user-facing symbol is <symbol>.<market>), and add a test using the response shapes returned by US prod.
GET /v1/trade/order returns HTTP 500 for US data-center accounts because the order gateway panics on US orders (seen in the LBUS UAT and reproduced on US prod). Fail fast with a region error instead and point US callers at us_order_detail in every layer's docs.
hogan-yuan
added a commit
to longbridge/openapi-go
that referenced
this pull request
Oct 22, 2026
GET /v1/trade/order returns HTTP 500 for US data-center accounts because the order gateway panics on US orders. Fail fast with RegionRestrictedError and point US callers at USOrderDetail, matching longbridge/openapi#613.
…to AP account_balance (/v1/asset/account), cash_flow (/v1/asset/cashflow), stock_positions (/v1/asset/stock) and PortfolioContext::exchange_rate (/v1/asset/exchange_rates) fail with gateway code 12 for US data-center accounts. Guard them with dc_restrict(DcRegion::Ap) so US tokens get a region error without a request, and point US callers at the us_* equivalents in every layer's docs. Also state that fund_positions and margin_ratio have no US equivalent, and add unit tests that all AP-only trade/portfolio methods reject a us_ token.
Append a path-based hint to the HttpClientError::DcRegionRestricted message so callers and LLM agents know what to call instead: the us_* equivalent for AP-only asset/order APIs, "no US equivalent" for fund positions and margin ratio, and a US-accounts-only note for US APIs. The existing message stays as the prefix and the variant's fields are unchanged. Also add the AP-only and "US token required" notes to the blocking trade/portfolio wrappers, and fix the AsyncPortfolioContext stub that pointed at the sync TradeContext.
The region-error hint named Rust/Python methods, but the text is shared by Node.js, Java, C/C++ and MCP servers whose names differ. Name the alternative by HTTP endpoint instead, cover every dc_restrict call site in both directions, and state when there is no equivalent.
…ints at AP endpoints GET /v3/trade/execution/all answers HTTP 500 code 12 for US accounts. Guard all_executions with dc_restrict(DcRegion::Ap) and hint at GET /v1/trade/execution/history. AP accounts calling US fundamentals now get pointed at the matching /v1/quote/ endpoints, and the exchange-rates hint uses the same wording as the other US hints.
hogan-yuan
added a commit
to longbridge/openapi-go
that referenced
this pull request
Oct 23, 2026
## Why LBUS accounts can't read balances, cash flow or exchange rates: the generic `/v1/asset/*` and `/v1/risk/margin-ratio` endpoints are AP-only and return `code 12` on US. Ports longbridge/openapi#613. ## What - New `TradeContext` methods: `USCashAndBuyPower`, `USAvailableHolding`, `USTransactionHistory`, `USExchangeRates` (paths `/v1/us/assets/cash-and-buy-power`, `/available-holding`, `/transaction-history`, `/exchange-rates`). US region check as for the other US methods. - `FundPositions` and `MarginRatio` now check for the AP region. Note: the existing region check treats OAuth sessions as AP, so it doesn't stop OAuth US users. That behaviour is pre-existing and unchanged here. - The exchange-rate map is flattened as in the Rust SDK. Transaction timestamps (unix seconds as a number or string) are parsed into `time.Time`. - CHANGELOG updated. ## Testing - `go test ./trade/...` passes. The only failure in `go test ./...` is the pre-existing `config.Test_YamlConfig`, whose testdata file is missing from the repo. - The real US prod responses for all four endpoints parse correctly through the SDK code path. ## Updated after real-data review Checked against masked US prod responses. Fixed in ab672b7: - `USCryptoEntry` now has the same fields as `USStockEntry` (`Quantity`, `Market`, `Name`, prices, `TodayPL`, ...). Before, it had no `Quantity`. The `Symbol` doc is corrected: it is the bare pair code, and the user-facing symbol is `Symbol.Market`. - `USTransaction.Symbol` no longer falls back to `counter_id`. Prod always sends the user-facing `symbol` alongside `counter_id`, and the fallback would expose an internal id. This matches the Rust SDK. - Added `TestUSAssetProdShapes`. `go test ./trade/...` passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Merged
hogan-yuan
added a commit
that referenced
this pull request
Oct 23, 2026
Release **v5.3.0**. Bumps workspace `5.2.2` → `5.3.0`. Minor bump: new US-account APIs, and calls that only work in the AP data center now fail fast with a region error. ### New since v5.2.2 (#613) - **Added:** US-account asset methods on `TradeContext` — `us_cash_and_buy_power`, `us_available_holding`, `us_transaction_history`, `us_exchange_rates` (Rust async + blocking, Node.js, Python; Java JNI entry points). US data-center tokens only. - **Changed:** `account_balance`, `cash_flow`, `stock_positions`, `fund_positions`, `margin_ratio`, `order_detail`, `all_executions` and `PortfolioContext.exchange_rate` are AP-only. A US data-center account gets `HttpClientError::DcRegionRestricted` without a request, instead of gateway code 12 / HTTP 500. - **Changed:** the `DcRegionRestricted` message keeps its existing text and appends `; <hint>` naming the alternative endpoint. Code that matches the message by exact equality must be updated; prefix matching keeps working. - **Fixed:** `Execution.side` defaults to `Unknown` when the response omits it (US `/v1/trade/execution/history`), so `history_executions` no longer fails to deserialize. - **Fixed:** `USCryptoEntry` carries the full set of fields returned by the gateway (`quantity`, `market`, `name`, prices, ...). - **Fixed:** `option_chain_info_by_date` calls `POST /v1/quote/options/strikes`. Verified on a Longbridge US production account before merge: all new US methods return data, `history_executions` parses fills without `side`, and every AP-only method returns the region error with its hint. Only `Cargo.toml` (workspace version + internal dep reqs) and `CHANGELOG.md` change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hogan-yuan
added a commit
to longbridge/longbridge-terminal
that referenced
this pull request
Oct 26, 2026
> **Draft:** depends on longbridge/openapi#613. Before merging, drop the two `chore(deps): TEMP …` commits and bump `longbridge` to the released version. ## Why On LBUS accounts, `longbridge portfolio` and `assets` fail with `code 12 internal server error`. In the US UAT (4.3 / 5.4), the trace shows `GET /v1/asset/account` → `unknown service PortfolioAsset`. The same happens for `cash-flow`, `exchange-rate`, `fund-positions`, `margin-ratio` and the matching `serve` methods. The generic asset endpoints are AP-only, and only `positions` already branched to the US API. ## What (US accounts only; AP behaviour unchanged) | Command | US account | |---|---| | `assets` | `us_cash_and_buy_power`: buying power, cash per currency, margin status | | `portfolio` | `us_asset_overview` + `us_cash_and_buy_power` | | `cash-flow` | `us_transaction_history`, paging through all pages | | `exchange-rate` | `us_exchange_rates` | | `fund-positions`, `margin-ratio` | Clear "not available for US accounts" error, no request sent | | `serve` | New `trade.us_*` methods. AP-only methods return a clear error naming the US equivalent | Also: - Fixes the empty Symbol column in the US `positions` table. - Updates help text, `--schema` and READMEs. - A separate commit bumps the SDK to the published 5.2.2 and handles the new `OrderStatus::DelayedNotReported`. Not included: the TUI portfolio for US accounts, and using `us_available_holding` in the sell flow. ## Testing - `cargo test`: all pass. 13 new tests cover routing, no AP call on US, paging, JSON shape and serve errors. - `cargo clippy`: the only new warnings are 5 `double_must_use` from `async_trait`, the same as on every existing trait method. - Not run against a live account. ## Updated after real-data review Checked against masked US prod responses. Changes in 93af6fe, with the SDK lock bumped to cab79039 in b56b028: - `positions` / `portfolio`: crypto entries get a `full_symbol` (`BTCUSD.BKKT`) built from the bare `symbol` plus `market`, the same way stock entries already have one. The crypto table now shows Qty / Cost / Last / Today P&L, since the SDK now returns them. - `exchange-rate`: a US account gets one row per rate type (`am`, `reference`) for the same pair. A `rate_type` column (`spec_key`) now tells those rows apart, and `--schema` explains `universal_key` (account channel, e.g. `us_lb_apex`) and `spec_key` (rate type). - `cash-flow`: the transaction `symbol` is already user-facing, so the `counter_id` conversion was removed. - `cargo test` passes (915 unit tests, plus the integration tests). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hogan-yuan
added a commit
to longbridge/longbridge-mcp
that referenced
this pull request
Oct 26, 2026
> **Draft:** depends on longbridge/openapi#613. Before merging, drop the two `chore(deps): TEMP …` commits and bump `longbridge` to the released version. ## Why For LBUS accounts, `stock_positions`, `account_balance`, `cash_flow` and `exchange_rate` fail with `code 12`, because they call AP-only endpoints (US UAT 5.2 / 5.4). `stock_positions` even called the AP endpoint before the US overview supplement, so it never succeeded for US accounts. `fund_positions` and `margin_ratio` have no US equivalent. ## What (US accounts only; AP behaviour unchanged) | Tool | US account | |---|---| | `stock_positions` | `us_asset_overview` only (US fields at top level; output schema covers both shapes) | | `account_balance` | `us_cash_and_buy_power` | | `cash_flow` | `us_transaction_history`, size 100, up to 20 pages, `truncated` + note when capped | | `exchange_rate` | `us_exchange_rates`. `bid`/`offer` are dropped when equal to `average` | | `fund_positions`, `margin_ratio` | Added to `AP_ONLY_TOOLS` (hidden from and rejected for US accounts) | Tool descriptions are updated in en / zh-CN / zh-HK. The gateway routes are live in prod and bound to `account.read` / `trade.read` on the HK and US scope registries. ## Testing - `cargo +nightly fmt --check`, `cargo clippy --all-features --all-targets` (0 warnings), `cargo test` (389 passed). - Not yet run against a live US account through MCP. ## Updated after real-data review Checked against masked US prod responses. Changes in 9052862, with the SDK lock bumped to cab79039 in 592e1f6: - `stock_positions` (US): `crypto_list` entries now include `quantity`, `name` and prices. Their `symbol` is qualified with the market (`BTCUSD` becomes `BTCUSD.BKKT`). The output schema and the descriptions (en / zh-CN / zh-HK) list these fields. - `exchange_rate` (US): the descriptions say `universal_key` is the account channel (e.g. `us_lb_apex`) and `spec_key` is the rate type (e.g. `am`, `reference`). The tests use those keys. - `cargo +nightly fmt`, `cargo clippy --all-features --all-targets` (0 warnings), `cargo test` (391 passed). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hogan-yuan
added a commit
to longbridge/skills
that referenced
this pull request
Oct 26, 2026
…ount limits (#68) ## Why Found in the LBUS user acceptance test: - **5.4 "show my positions" failed for an LBUS account.** The base skill tells the model to always run `portfolio` for "my portfolio". On LBUS accounts the current CLI's `portfolio` calls AP-only endpoints and fails with `internal server error` (code 12). `positions` works. - **5.5 / 5.x: order confirmation is described wrong.** `references/order.md` was a stale capture of the old CLI help ("prompts for confirmation"). The CLI now previews by default and only acts when the same command is re-run with `--execute <CODE>`. `--execute` appeared nowhere in this repo. ## What - `longbridge-portfolio/references/order.md`: refreshed the captured `longbridge order --help` (CLI 0.30.0) and added the preview → confirm → `--execute <CODE>` flow, with "never execute before the user confirms". - `longbridge-portfolio/SKILL.md`: - The Auth section explains the dry-run default. - New "Longbridge US accounts" section: use `positions` for holdings, cash and buying power; fund positions, margin ratio and executions are not available for US accounts; fall back to `positions` if `portfolio` / `assets` / `cash-flow` fail on an older CLI. - Two new error-handling rows for the AP-only region error and the code 12 case. - `longbridge/SKILL.md`: one-line LBUS note next to the `portfolio` example. Follow-ups, not in this PR: - Once longbridge/longbridge-terminal#337 ships (US support for `portfolio`, `assets`, `cash-flow`, `exchange-rate`), the "older CLI" fallback note can be narrowed to a version. - Once longbridge/openapi#613 is released, add the new US SDK methods to `references/*-sdk/trade-context.md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hogan-yuan
added a commit
to longbridge/developers
that referenced
this pull request
Oct 26, 2026
…1297) ## Why LBUS users follow the asset docs and get `code 12`: the generic asset endpoints are AP-only, and the docs don't say so or point to the US endpoints (US UAT 3.3). ## What - New pages (en / zh-CN / zh-HK) under `trade/asset/`: Cash and Buying Power, Available Holding, Transaction History, Exchange Rates (US). The API reference (`openapi.yaml`) gets the 4 endpoints too. Examples are in Python, Python async, Node.js, Rust and Go. Java is not included because the Java SDK does not expose these methods yet. - An "AP accounts only" notice on Account Assets, Stock Positions, Fund Positions, Cash Flow, Margin Ratio and Exchange Rates, linking to the US equivalents. Fund positions and margin ratio are marked not available for US accounts. - Getting Started: US accounts are pointed to `us_asset_overview` / `us_cash_and_buy_power` for balances. SDK: longbridge/openapi#613. The endpoints are already live on the prod gateway. ## Testing - `autocorrect --lint` passes. `openapi.yaml` parses. The Node.js and Go examples type-check against the SDK branches. - The site build was not run here (`bun run build:canary` should be run before merge). ## Also in this PR Doc fixes from the LBUS UAT replies: - Order Details is marked AP-only and points US accounts to `us_order_detail`. Today Orders and History Orders recommend `us_query_orders` for US accounts (UAT 3.4). - Paper trading: the MCP prerequisites and the general FAQ say LBUS has no paper accounts, and tell users to test with the paper account's own credentials (UAT 3.6). - Error codes: added `403308` (scope not authorized), with the fix and the no-securities-account/no-permission case. The MCP troubleshooting section links to it (UAT 3.x / 5.5). - Getting Started: new OAuth scopes section (`watchlist`, `account.read`, `trade.read`, `trade.write`, and the production ids `4/6/10/11` from longbridge-mcp; other ids are treated as opaque) and a Sign Out section (delete the stored token file, or `longbridge auth logout`) (UAT 2.3). - CLI `order` / `grid`: replaced "prompts for confirmation" / `-y` / `--dry-run` with the actual preview + `--execute <CODE>` flow (UAT 5.5). - CLI `portfolio` / `assets` / `cash-flow` / `exchange-rate`: one-line note that LBUS should use `positions` for now, with US support coming in longbridge/longbridge-terminal#337 (UAT 4.3 / 5.4). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Why
LBUS (US data-center) accounts can't read balances, cash flow or exchange rates through the SDK: the generic
/v1/asset/*and/v1/risk/margin-ratioendpoints are AP-only. On US they returncode 12 internal server error, because the gateway reportsunknown service PortfolioAsset(the backend isn't deployed in US). This was found in the US UAT (items 3.3 / 4.3 / 5.4).What
New
TradeContextmethods for US accounts (dc_restrict(DcRegion::Us)):us_cash_and_buy_power(currency)GET /v1/us/assets/cash-and-buy-powerus_available_holding(opts)GET /v1/us/assets/available-holdingus_transaction_history(opts)POST /v1/us/assets/transaction-historyus_exchange_rates()GET /v1/us/assets/exchange-rateslb-portfolio-libertyschemas (read via inner-gateway reflection). The exchange-rate response is a two-level map keyed by account channel (e.g.us_lb_apex) and rate type (am/reference). The SDK flattens it intoexchanges[]and keeps both keys on each entry.fund_positionsandmargin_ratioare now AP-only (dc_restrict(DcRegion::Ap)), so US accounts get a clear region error instead ofcode 12. US accounts have no fund holdings or margin-ratio data.openapi.pyi), Node.js (napi;index.d.tsregenerated with@napi-rs/cli3.8.0), Java JNI layer.us_asset_overviewetc.), which are not exposed there either.Gateway
All four routes are deployed to prod.
transaction-history(559) andexchange-rates(558) are new.available-holding(440) now hassymbol2CounterID, so callers passAAPL.US. The routes are also bound to MCP scopes (account.read/trade.read) on the HK and US registries.Testing
cargo test -p longbridge --lib: 76 passed. Clippy shows no new warnings. Python and Node built locally, and the new methods were checked by importing them.f8877d2ab: the gateway returns bothsymbolandcounter_id, so the earliercounter_idalias caused a duplicate-field error.Related
Updated after real-data review
Checked against masked US prod responses (overview, cash-and-buy-power, available-holding, transaction-history, exchange-rates). The new types match. One gap fixed in cab7903:
USCryptoEntry(used byus_asset_overview) kept only 5 of the fields prod returns for a crypto holding, so it had noquantity. It now has the same fields asUSStockEntry(quantity,market,name, prices,today_pl,position_side, ...) in Rust, Python and Node.js. Thesymboldoc now says it is the bare pair code (BTCUSD), and the user-facing symbol is<symbol>.<market>. Also added a test using the prod response shapes (current_pageas a number,us_lb_apex/am/referencekeys, numeric-string timestamps).cargo test -p longbridge --libpasses (77 tests).index.d.tswas regenerated with@napi-rs/cli@3.8.0.🤖 Generated with Claude Code