Skip to content

add time-condition order support - #1289

Merged
hogan-yuan merged 3 commits into
longbridge:mainfrom
shinexia:feature-add-timed-order
Oct 14, 2026
Merged

hogan-yuan merged 3 commits into
longbridge:mainfrom
shinexia:feature-add-timed-order

Conversation

@shinexia

Copy link
Copy Markdown
Contributor

No description provided.

Xia Guanghui and others added 2 commits October 13, 2026 17:45
Documents the new time-conditional order monitoring state across all three locales.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sync with order-gateway a0730f74, which exposes delayed_until on the
OpenAPI submit, multileg submit and replace requests and returns it on
order queries.

- submit / submit_multileg: add delayed_until param; add a
  Time-Condition Orders section listing supported markets and order types
- replace: 0 keeps the time condition, 1 clears it, other values set a new time
- today_orders / history_orders / order_detail: add delayed_until field
- openapi.yaml: replace request, Order schema and examples
- changelog: 2026-10-13 entry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hogan-yuan added a commit to longbridge/openapi-go that referenced this pull request Oct 13, 2026
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.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hogan-yuan added a commit to longbridge/openapi that referenced this pull request Oct 13, 2026
Documented in longbridge/developers#1289. A time-condition order is held
in DelayedNotReported status and sent automatically at a set time (later
than now, at most 90 days ahead).

- Rust: SubmitOrderOptions / SubmitMultiLegOrderOptions gain
  delayed_until(OffsetDateTime); ReplaceOrderOptions gains
  delayed_until(OffsetDateTime) and clear_delayed_until() (sends 1).
  Order / OrderDetail gain delayed_until: Option<OffsetDateTime>,
  defaulting to None when the field is absent or "0".
- C: delayed_until pointers (and clear_delayed_until on replace)
  appended to the option structs; delayed_until on lb_order_t /
  lb_order_detail_t. Header regenerated by cbindgen.
- C++, Java, Node.js (index.d.ts regenerated), Python (+ openapi.pyi)
  mirror the Rust API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hogan-yuan added a commit that referenced this pull request Oct 13, 2026
#1286 (Cloudflare Pages) was merged while **Check text autocorrect** was
failing, so every PR opened since then fails the same 11 errors in files
it doesn't touch — e.g. #1263 and #1289.

This adds the CJK/ASCII spacing autocorrect asks for, in exactly the 11
places the CI job reports:

- `astro.config.ts` (1)
- `src/integrations/prebuild-skills.ts` (4) — log message strings only,
no behavior change
- `docs/superpowers/plans/2026-09-16-openapi-nginx-decommission.md` (6)

Once this is merged, re-running the autocorrect check on #1263 / #1289
should pass, since PR checks run against the merge with `main`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
hogan-yuan added a commit to longbridge/openapi that referenced this pull request Oct 13, 2026
Documented in longbridge/developers#1289. A time-condition order is held
in DelayedNotReported status and sent automatically at a set time (later
than now, at most 90 days ahead).

- Rust: SubmitOrderOptions / SubmitMultiLegOrderOptions gain
  delayed_until(OffsetDateTime); ReplaceOrderOptions gains
  delayed_until(OffsetDateTime) and clear_delayed_until() (sends 1).
  Order / OrderDetail gain delayed_until: Option<OffsetDateTime>,
  defaulting to None when the field is absent or "0".
- C: delayed_until pointers (and clear_delayed_until on replace)
  appended to the option structs; delayed_until on lb_order_t /
  lb_order_detail_t. Header regenerated by cbindgen.
- C++, Java, Node.js (index.d.ts regenerated), Python (+ openapi.pyi)
  mirror the Rust API.
hogan-yuan added a commit to longbridge/openapi-go that referenced this pull request Oct 13, 2026
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.
hogan-yuan added a commit to longbridge/openapi that referenced this pull request Oct 14, 2026
hogan-yuan added a commit to longbridge/openapi-go that referenced this pull request Oct 14, 2026
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>
hogan-yuan added a commit to longbridge/openapi-go that referenced this pull request Oct 14, 2026
…(DelayedUntil) (#123)

Ports longbridge/openapi#595: the `DelayedNotReported` order status
([longbridge/developers#1263](longbridge/developers#1263))
and time-condition orders
([longbridge/developers#1289](longbridge/developers#1289)).

## Changes

- **`trade.OrderDelayedNotReported`:** a new `OrderStatus` constant for
the wire value `"DelayedNotReported"`, meaning a time-condition order
that is held and not yet 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 literal.
- **`DelayedUntil int64`** (Unix seconds; `0` is not sent) on
`SubmitOrder`, `SubmitMultiLegOrder` and `ReplaceOrder`.
- On submit, the order is held in `OrderDelayedNotReported` and
submitted at that time (later than now, at most 90 days ahead; multi-leg
supports only `LO` / `MO`).
- On replace, `0` keeps the current time condition, the new
`ClearDelayedUntil` constant (`1`) clears it, and any other value sets a
new time.
- **`DelayedUntil string`** on `Order` / `OrderDetail`: the raw
Unix-seconds string from `TodayOrders` / `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 existing
`TriggerAt string`. The wire field also accepts a JSON number (or
`null`), so a server-side type change in this new field cannot fail the
whole response.

Raw `int64` seconds follow the SDK's existing request conventions
(`ExpireTime`, `GetCashFlow.StartAt`). The mapping to the wire types
goes through `util.Copy`, the same as the neighbouring fields.

## Verification

- `go build ./...`, `go vet ./trade/...` and `go test ./trade/...` pass.
- `trade/delayed_until_test.go` exercises the real `util.Copy` +
`encoding/json` path:
- the wire values for submit / multi-leg / replace, including
`ClearDelayedUntil` and a new time
  - the field is omitted at zero for all three request types
- responses with `"0"`, a timestamp, a JSON number, `null`, and no field

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@hogan-yuan
hogan-yuan merged commit 0826f0f into longbridge:main Oct 14, 2026
2 checks passed
hogan-yuan added a commit that referenced this pull request Oct 15, 2026
Conflicts:
- src/pages/llms.txt.ts, src/pages/llms-full.txt.ts: keep this branch's
  `/docs/api` filter and main's `.md` URL suffix (nginx decommission).
- openapi.yaml: this branch relocated the old /v1/trade/*, grid, content
  and asset paths, so main's side of the conflict was the stale copy of
  them; taking both duplicated 21 path keys and 9 operationIds (YAML keeps
  the last one silently). Resolved to this branch's version and ported
  main's only changes since the merge base:
  - #1289: delayed_until on submit_order,
    replace_order and submit_multileg, and on today_orders /
    history_orders response properties + examples (trilingual text taken
    from the merged docs);
  - #1263: DelayedNotReported in the order status
    enumerations (12 places).
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.

2 participants