Repository navigation
feat(trade): add DelayedNotReported status and time-condition orders (DelayedUntil) - #123
Merged
Merged
Conversation
Port longbridge/openapi #595. Add the OrderDelayedNotReported constant for the "DelayedNotReported" wire value: monitoring, the state a time-condition order sits in before it is reported to the exchange. OrderStatus is a plain string, so the value was already passed through; the constant lets callers compare against it instead of a string literal.
hogan-yuan
added a commit
that referenced
this pull request
Sep 28, 2026
Cut **v0.28.0** — closes out the `[Unreleased]` CHANGELOG section as `[v0.28.0] - 2026-09-28`. ## Included since v0.27.0 - **Grid trading** (`grid.GridContext`); `SubmitStrategyQuestionnaire` endpoint removed - **Removed all symbol↔counter_id conversions** (port longbridge/openapi #562) — endpoints send/receive the user symbol directly; `counter` package removed - **Multi-leg option orders** — `TradeContext.SubmitMultiLeg` + `MultiLegInfo` on orders/push (#575, #589, #590) - **Option chain onto the HTTP endpoint** (#588, **breaking**) — `StrikePriceInfo` → `OptionChainContract`; see gateway note below - **FinanceCalendar pagination** (#597, **breaking**) — `count`/`offset`/`next` + `CalendarPageDirection` - **HistoryExecutions pages through all `has_more`** (#591) - **SignalContext** — `Signals` / `Signal` / `SecurityFacts` (#577, #578) - **Type refinements** — `Execution.Side`, typed `AlertValueMap`, typed `RankCategories`, `CorpActionLive.Status` string, `IndustryPeersResponse.Top` optional, `WarrantStatusUnknown`, Greek doc refresh (#586) - Ratings temporarily disabled; `TopMovers.NextParams` string; portfolio flows timestamp ##⚠️ Gateway dependency (#588) `QuoteContext.OptionChainInfoByDate` now calls `GET /v1/gemini/option/option_chain_list`. That endpoint must be deployed on the target gateway. Verified live for this release: **available on staging, not yet on production** (returns `404 api not found` there until deployed). Called out prominently at the top of the v0.28.0 CHANGELOG entry. ## Verification Read-only endpoints exercised live against staging + production (report with per-endpoint request/response params): every change verified on at least one environment — see internal report. `go build ./...` and package tests pass. ## Not included `#123` (DelayedNotReported) and `#124` (fund) remain open for a later release. ## After merge Tag `v0.28.0` on the merge commit and push (Go modules resolve by tag).
…ayed-not-reported # Conflicts: # CHANGELOG.md
…ayed-not-reported # Conflicts: # CHANGELOG.md
hogan-yuan
marked this pull request as ready for review
October 13, 2026 10:28
Port longbridge/openapi #595 (longbridge/developers#1289). - SubmitOrder, SubmitMultiLegOrder and ReplaceOrder gain DelayedUntil (unix seconds, omitted when 0). On replace, ClearDelayedUntil (1) clears the time condition. - Order and OrderDetail gain DelayedUntil, read from the delayed_until field of the order query responses.
- CHANGELOG: move both entries from Fixed to Added and drop the incorrect claim that DelayedNotReported used to map to an unknown status (Go OrderStatus is a plain string passthrough). - Document that Order/OrderDetail DelayedUntil can be empty as well as "0", and warn against a literal 1 / zero on ReplaceOrder. - Replace the Chinese godoc text with English. - Tests: zero omitted on submit and multi-leg too, a non-sentinel replace time, and a response without delayed_until.
hogan-yuan
force-pushed
the
feat/order-status-delayed-not-reported
branch
from
October 13, 2026 14:42
f84b074 to
fd0f764
Compare
The spec (longbridge/developers#1289) marks the response field nullable.
Mirrors the Rust core: the wire field is a FlexString that also takes a number (or null), so a type change in this newly added field cannot fail TodayOrders / HistoryOrders / OrderDetail.
hogan-yuan
added a commit
to longbridge/openapi
that referenced
this pull request
Oct 14, 2026
…rders (#595) Follows [longbridge/developers#1263](longbridge/developers#1263) (the new `DelayedNotReported` order status) and [longbridge/developers#1289](longbridge/developers#1289) (time-condition orders). ## 1. `OrderStatus::DelayedNotReported` **Monitoring (time-condition order)**: the state a time-condition order sits in before it is reported to the exchange. No SDK enum variant matched that wire value. `OrderStatus` deserializes through `impl_serde_for_enum_string!`, which falls back to `unwrap_or_default()` → `OrderStatus::Unknown`, so nothing failed loudly. Monitored time-condition orders simply became indistinguishable from a genuinely unrecognized status in `today_orders` / `history_orders` / `order_detail` and the order-changed push. The variant is **appended after `PartialWithdrawal`** rather than grouped with the other `*NotReported` values. The C/C++ and Node.js enums use implicit discriminants: - `lb_order_status_t` has no explicit values, so inserting mid-list would shift every following value. That is an ABI break for anything linked against a prebuilt C/C++ library. - `nodejs/index.d.ts` emits a `const enum`, which TypeScript inlines at the consumer's compile time. Renumbering would silently change already-compiled code. Appending keeps every existing discriminant stable (`DelayedNotReported = 18`). ## 2. Time-condition orders (`delayed_until`) | Endpoint | SDK | |---|---| | Submit order / submit multi-leg order | `delayed_until`: hold the order in `DelayedNotReported` and submit it at that time (later than now, at most 90 days ahead; multi-leg supports only `LO` / `MO`) | | Replace order | `delayed_until` moves the time; `clear_delayed_until` turns it back into a regular order (wire `1`); leaving both unset keeps the current time condition | | `today_orders` / `history_orders` / `order_detail` | `Order.delayed_until` / `OrderDetail.delayed_until`, unset when the server returns `"0"` or omits it | Per layer: - **Rust:** `delayed_until(OffsetDateTime)` builders and `ReplaceOrderOptions::clear_delayed_until()` (last call wins); `Option<OffsetDateTime>` response fields. - **C:** `const int64_t *delayed_until` (Unix seconds) on the three option structs, plus `bool clear_delayed_until` on replace. Also on `lb_order_t` / `lb_order_detail_t`. **Every new field is appended at the end of its struct**, so existing field offsets are unchanged. - **C++:** `std::optional<int64_t> delayed_until`, plus `bool clear_delayed_until = false`. - **Java:** `setDelayedUntil(OffsetDateTime)`, `ReplaceOrderOptions.clearDelayedUntil()`, `getDelayedUntil()`. - **Node.js:** `delayedUntil?: Date`, `clearDelayedUntil?: boolean`, `get delayedUntil(): Date | null`. - **Python:** `delayed_until: Optional[datetime]` / `clear_delayed_until: bool = False` keyword arguments (appended, so positional callers are unaffected), and `Order.delayed_until` / `OrderDetail.delayed_until`. In the bindings, clear takes precedence over a time when both are set. ### Edge cases handled - **Wire sentinels:** a time at or before `1970-01-01T00:00:01Z` would map to `0` (no condition) or `1` (clear), so it is sent as `2` instead. The server then rejects it as a past time rather than silently placing a regular order or clearing the condition. - **Out-of-range timestamps:** - C reports the error through the callback instead of panicking across the FFI boundary. - Node.js returns an `InvalidArg` error instead of aborting the process. - **Lenient response parsing:** the response field also accepts a JSON integer. A malformed, negative or out-of-range value reads as unset instead of failing the whole `today_orders` / `history_orders` / `order_detail` call, so users who upgrade are not exposed to a field the server never sent before. - **Python time zones:** `delayed_until` uses a dedicated converter. - A timezone-aware `datetime` (one whose `utcoffset()` is not `None`) converts by its real offset; a naive one is read as UTC. - Other `datetime` parameters keep their existing wall-clock semantics. For example, `history_candlesticks_by_offset(time=...)` relies on that. ## Second commit: regenerated `nodejs/index.js` `npm run build:debug` regenerates `index.js` alongside `index.d.ts`. The committed copy predated the `@napi-rs/cli@3.8.6` that the release workflow pins, so it was regenerated separately (`38184a7`); it is loader churn unrelated to the API changes. ## Verification - `cargo clippy --all --all-features`: no new warnings. `cargo +nightly fmt --all` applied. - `cargo test -p longbridge --lib`: 70 passed. New tests cover: - request serialization for submit / multi-leg / replace - the sentinel clamp, and last-call-wins on replace - `"0"` / absent / `null` / integer / malformed responses - the new status - `cargo build -p longbridge-c` (header regenerated); `clang++ -fsyntax-only` on `cpp/src/trade_context.cpp`. - `cargo build -p longbridge-java` and `mvn compile` for the Java classes. - `npm run build:debug`: `index.d.ts` regenerated. Checked with a script that an out-of-range `delayedUntil` returns `InvalidArg` and the process stays alive. - Python: built the wheel and called `submit_order` / `replace_order` against a local fake HTTP server. - Aware `+08:00`, aware UTC and naive inputs all send `1767225600`. - The epoch is sent as `2`. - Clear sends `1` and wins over a time. - The field is omitted when unset. - Not verified: an end-to-end order against a real account. Go SDK counterpart: longbridge/openapi-go#123. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: 袁章洪 <zhanghong.yuan@longbridge-inc.com>
Merged
hogan-yuan
added a commit
that referenced
this pull request
Oct 14, 2026
Cut **v0.29.1** — closes out the `[Unreleased]` CHANGELOG section as `[v0.29.1] - 2026-10-14`. ## Included since v0.29.0 - **Added — time-condition orders** (#123): `DelayedUntil` on `SubmitOrder` / `SubmitMultiLegOrder` / `ReplaceOrder` (`ClearDelayedUntil` clears it on replace), `DelayedUntil` on `Order` / `OrderDetail`, and the `OrderDelayedNotReported` status constant. Ports longbridge/openapi#595. - **Added — quote transport** (#130): `quote.Transport` to serve quote pull APIs over HTTP, plus the related `Changed` / `Fixed` items (`LONGBRIDGE_ENABLE_OVERNIGHT`, idempotent `QuoteContext.Close`, `Subscribe` error propagation, WebSocket leak fixes). Only `CHANGELOG.md` changes. The `v0.29.1` tag is created after merge. 🤖 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.
Ports longbridge/openapi#595: the
DelayedNotReportedorder status (longbridge/developers#1263) and time-condition orders (longbridge/developers#1289).Changes
trade.OrderDelayedNotReported: a newOrderStatusconstant for the wire value"DelayedNotReported", meaning a time-condition order that is held and not yet reported to the exchange.OrderStatusis a plain string, so the value was already passed through; the constant lets callers compare against it instead of a literal.DelayedUntil int64(Unix seconds;0is not sent) onSubmitOrder,SubmitMultiLegOrderandReplaceOrder.OrderDelayedNotReportedand submitted at that time (later than now, at most 90 days ahead; multi-leg supports onlyLO/MO).0keeps the current time condition, the newClearDelayedUntilconstant (1) clears it, and any other value sets a new time.DelayedUntil stringonOrder/OrderDetail: the raw Unix-seconds string fromTodayOrders/HistoryOrders/OrderDetail. It is"0", or empty if the server omits the field, when the order is not a time-condition order. This mirrors the existingTriggerAt string. The wire field also accepts a JSON number (ornull), so a server-side type change in this new field cannot fail the whole response.Raw
int64seconds follow the SDK's existing request conventions (ExpireTime,GetCashFlow.StartAt). The mapping to the wire types goes throughutil.Copy, the same as the neighbouring fields.Verification
go build ./...,go vet ./trade/...andgo test ./trade/...pass.trade/delayed_until_test.goexercises the realutil.Copy+encoding/jsonpath:ClearDelayedUntiland a new time"0", a timestamp, a JSON number,null, and no field🤖 Generated with Claude Code