Skip to content

feat(tools)!: sync longbridge SDK 5.1 additions - #157

Merged
sunli829 merged 1 commit into
mainfrom
feat/sync-sdk-5.1
Sep 22, 2026
Merged

sunli829 merged 1 commit into
mainfrom
feat/sync-sdk-5.1

Conversation

@sunli829

Copy link
Copy Markdown
Contributor

Summary

An audit of what the openapi SDK gained between 5.0 and 5.1 turned up
several additions that were never wired through here. This picks up five of
them.

The dependency moves from a pinned git rev back to crates.io. 1df0f560
predated the option-chain rewrite, and the branch note it carried (the
symbol-based, counter-id-free request contract) has since shipped in a
release — so the TODO goes away with it.

-longbridge = { git = "https://github.com/longbridge/openapi.git", rev = "1df0f560" }
+longbridge = "5.1"

Breaking: the option chain moved to an OpenAPI endpoint

option_chain_info_by_date is now backed by
GET /v1/gemini/option/option_chain_list instead of quote socket command
21 (openapi#588). This is not a URL swap — the response shape changed.

before after
strikePrices[]{strike_price, call{symbol, last_done, iv, delta, gamma}, put{...}} one entry per contract: {symbol, expiry_date, strike_price, direction, option_type, standard_attr, days_to_expiry}
a strike listed on one side only came back with an empty call_symbol/put_symbol it yields a single entry
carried quotes and Greeks carries neither — pass symbol to option_quote

Callers that read call.symbol / put.symbol must filter on direction
instead. The tool also gains standard_only, which drops the legacy
contracts left over from a corporate action (standard_attr: "Old").

Three stale cross-references are fixed along with it: option_quote and
option_chain_expiry_date_list both pointed at the old paired shape, and the
latter promised "strikes and Greeks" that this endpoint never returns.

option_chain_expiry_date_list is unchanged and still uses socket command
20 — deliberately out of scope upstream, since the new endpoint requires an
expiry_date and so cannot enumerate them.

Calendar spreads

submit_multileg_order now documents CalendarCallSpread and
CalendarPutSpread (openapi#590). The value is parsed via FromStr, so the
prose was the only thing gating them.

client_request_id

submit_order and submit_multileg_order gain the exchange-side idempotency
key. Two requests carrying the same value place one order, and the second
returns the original order_id — so a retry after a timeout or a dropped
connection cannot double-fill.

It is deliberately not part of dry_run::Scope. An idempotency key does
not change the order the user approved, and a caller that regenerates one
between the preview and the execute must not be told its confirmation code is
wrong. It is echoed in the preview, so the user can see a retry is guarded.

The existing execute gate and this key solve different halves of the same
problem: execute stops a second intended order, client_request_id stops
a second delivery of the first one.

OPTION_PRE_MARKET

Documented on outside_rth and on both attached-leg variants. The SDK has
parsed it since fc617e5ea; being absent from the schema made it unreachable
in practice.

Paper trading on the context path

create_config now honours an x-papertrading: true (or 1) request
header.

This one was a real gap rather than a missing feature. create_http_client
already forwarded the header with the rest of extra_headers, but Config
forwards none of them — so the SDK contexts, trade above all, quietly ran
against real money for a caller who had asked for paper trading.

Trusting a client header is safe in the one direction that matters: the flag
only ever narrows what a token may do, and upstream rejects a paper-trading
request made with a real-money token. A spurious header fails the call rather
than routing it somewhere unexpected. LONGBRIDGE_PAPERTRADING=true (read by
the SDK) still covers a whole deployment; the header covers one request.

Documented in the README's authentication section and covered by a unit test.

Locales

locales/zh-CN and locales/zh-HK are updated for all six affected tools,
including the two new parameters. Worth noting for future changes:
locales_match_live_tool_schema only asserts that locale keys exist in the
live schema, not the reverse — a missing translation would not have failed
the build.

Verification

  • cargo clippy --all-features --all-targets — clean
  • cargo test --all-features — 312 passed, 3 ignored
  • cargo +nightly fmt

Not run: the three #[ignore]d tests, and no live call against the new
option-chain endpoint from this machine.

🤖 Generated with Claude Code

Pick up the SDK surface that landed in openapi between 5.0 and 5.1 but
was never wired through here. The dependency moves from a pinned git rev
back to crates.io: `1df0f560` predated the option-chain rewrite, and the
branch note it carried (the symbol-based request contract) is now in a
release.

BREAKING CHANGE: `option_chain_info_by_date` now returns one entry per
contract instead of strikes paired by price. The endpoint moved to
`GET /v1/gemini/option/option_chain_list`, so `strikePrices[]{strike_price,
call{...}, put{...}}` is replaced by a flat list of `{symbol, expiry_date,
strike_price, direction, option_type, standard_attr, days_to_expiry}`.
Callers that read `call.symbol`/`put.symbol` must filter on `direction`
instead, and the response no longer carries prices or Greeks — those come
from `option_quote`. The tool also gains `standard_only`, which drops the
legacy contracts left over from a corporate action.

Also:

- `submit_multileg_order` documents `CalendarCallSpread` /
  `CalendarPutSpread`. The value is parsed via `FromStr`, so only the
  prose gated them.
- `submit_order` and `submit_multileg_order` gain `client_request_id`,
  the exchange-side idempotency key, so a retry after a timeout cannot
  double-fill. It is deliberately left out of `dry_run::Scope`: it does
  not change the order the user approved, and a caller that regenerates
  one between preview and execute must not be told its code is wrong. It
  is echoed in the preview.
- `OPTION_PRE_MARKET` is documented on the three outside-RTH fields. The
  SDK already parsed it; being absent from the schema made it
  unreachable.
- `create_config` honours an `x-papertrading` request header.
  `create_http_client` already forwarded it with the rest of
  `extra_headers`, but `Config` forwards none of them, so the SDK
  contexts — trade above all — quietly ran against real money for a
  caller who asked for paper trading. Trusting the header is safe in the
  one direction that matters: it only narrows what a token may do, and
  upstream rejects a paper-trading request made with a real-money token.

The zh-CN and zh-HK tool locales are updated to match, including the two
new parameters. `locales_match_live_tool_schema` only checks that locale
keys exist in the live schema, not the reverse, so a missing translation
would not have failed the build.
@sunli829
sunli829 marked this pull request as draft September 21, 2026 04:47
@sunli829
sunli829 marked this pull request as ready for review September 22, 2026 01:42
@sunli829
sunli829 merged commit dfcdc8c into main Sep 22, 2026
1 check passed
@sunli829
sunli829 deleted the feat/sync-sdk-5.1 branch September 22, 2026 01:42
@hogan-yuan hogan-yuan mentioned this pull request Oct 8, 2026
hogan-yuan added a commit that referenced this pull request Oct 8, 2026
Cut **v0.13.0**. Bumps `0.12.0` → `0.13.0` and pins the openapi
dependency to the published crates.io release.

## Included since v0.12.0
- **Fund channel tools** (#161): 28 mutual-fund tools (25 read +
`fund_validate_order` + 2 gated writes) — catalog & market data, user
positions, orders/trading. Funds are addressed by `counter_id`. Writes
(`fund_submit_order` / `fund_cancel_order`) are behind the two-step
dry-run confirmation; reads are in the v2 allowlist.
- **SDK 5.1 sync** (#157): ports the longbridge SDK 5.1 additions.

## Dependency
- `longbridge` switched from the temporary git rev (`e0df4c1e8`) to the
published crates.io release **`5.2.0`** (the fund channel shipped in
openapi v5.2.0). `cargo build` + `cargo clippy --all-targets` clean.
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