Placing Orders
Every order is an execution graph — a market buy is a 1-node graph. The SDK's buy() / sell() helpers marshal urgency, policy, max_slippage_bps, horizon_ms, and tif into the full graph payload behind the scenes. Same execution path, simpler ergonomics.
For multi-leg orders (brackets, hedges, TWAP), see Execution Graphs. For pre-trade cost estimates without submitting, see the preview() section in Market Data.
Market & Limit Orders
use sequence_sdk::{Side, Urgency, TimeInForce};
// Market buy — SOR routes across every connected venue
seq.buy("ETH-USD", 50.0)
.urgency(Urgency::High)
.max_slippage_bps(10)
.submit().await?;
// Limit sell pinned to one venue
seq.sell("BTC-USD", 0.5)
.venue("coinbase")
.limit_price(75_000.0)
.time_in_force(TimeInForce::Gtc)
.submit().await?;
// Perp (Hyperliquid)
seq.buy("ETH-USD-PERP", 5.0)
.perp()
.venue("hyperliquid")
.submit().await?;
// Paper fill against live book — works on a seq_live_* key too
seq.buy("SOL-USD", 100.0).sandbox().submit().await?;OrderBuilder methods: .venue(v), .limit_price(px), .policy(p), .urgency(u), .max_slippage_bps(bps), .horizon_ms(ms), .time_in_force(t), .perp(), .sandbox(), .submit().
Both helpers return a graph response — the order ID can be derived as graph:<graph_id>:<node_id>:<seq>. The seq.cancel(...) helper accepts either form.
The prediction-market round-trip is fully on the same /v1/orders graph path. A real Kalshi submit takes ~75 ms end-to-end (edge → /trade-api/v2/portfolio/orders → 201). Polymarket takes ~260 ms on the first order per session (one extra roundtrip for L2-cred derivation), then ~130 ms thereafter.
Inspect a single order
let o = seq.order("graph:graph_…:spot:1").await?;
println!("status={} filled={:.4}/{} ({:.1}%)",
o.status, o.filled_qty(), o.qty(), o.fill_pct());
if o.is_terminal() {
println!("done — failure_reason={:?}", o.failure_reason);
}OrderResponse exposes raw + human accessors: qty(), filled_qty(), fill_pct(), is_terminal(). Status values: NEW, PENDING, ACCEPTED, PARTIAL, FILLED, COMPLETED, CANCELLED, REJECTED, FAILED (UPPERCASE).
List orders + fills
let page = seq.orders().symbol("ETH-USD").limit(100).offset(0)
.fetch().await?;
// OrdersResponse { orders, total, limit, offset, has_more }
let fills = seq.fills().limit(50).fetch().await?;
for f in fills.fills {
println!("{} {:.4} @ {:.2}", f.symbol, f.qty(), f.price());
}Each fill row: {fill_id, node_order_id, symbol, side, qty_1e8, price_1e9, venue, fee_1e9, timestamp_ns}.
Cancel
cancel() accepts a graph ID or a node-order ID — it strips the suffix before calling DELETE /v1/execution_graphs/{graph_id}. Cancels every active node in the graph. Already-filled quantities are NOT reversed — this is stop-now, not rollback.
seq.cancel("graph_f679e9c25e9e4ecbaacceb71d62bd9a9").await?;Amend (price / qty)
Change price, qty, or both on a resting order. At least one of new_price/new_qty must be provided.
use sequence_sdk::AmendMode;
let r = seq.amend("graph:graph_…:n:1",
Some(0.55), // new_price
Some(10.0)).await?; // new_qty
match r.mode {
AmendMode::CancelReplace => track_queue_loss(&r.order_id),
AmendMode::NativeAtomic => {} // queue preserved (future — Kalshi only)
}mode | Meaning |
|---|---|
cancel_replace | Today's behavior on every venue. Queue position is lost. |
native_atomic | Future — Kalshi only, once CC↔edge wiring for /portfolio/orders/{id}/amend lands. Queue preserved. |
Decrease (shrink without re-pricing)
Shrink a resting order without touching price. Two round-trips today (read current size, issue amend).
let r = seq.decrease("graph:graph_…:n:1", 5.0).await?;Errors if reduce_by would take remaining qty to ≤ 0 — cancel instead.
Batch (per-venue)
Open a batch of submits + cancels targeted at one venue.
use sequence_sdk::BatchMode;
let r = seq.batch("kalshi")
.buy_limit("KXBTCZ-26DEC31-T99000", 10.0, 0.55)
.buy_limit("KXBTCZ-26DEC31-T100000", 10.0, 0.50)
.cancel("stale_order_id")
.end().await?;
assert_eq!(r.mode, BatchMode::Serial);batch() currently submits one graph root per op and returns mode="serial" for both Kalshi and Polymarket. Kalshi's transport supports native /portfolio/orders/batched (20-op atomic), and Polymarket's transport supports CLOB POST /orders batch (15 orders, per-order results), but the SDK graph path does not preserve a native venue batch window end-to-end yet.
Redeem (prediction markets)
Claim winnings from a resolved prediction market. Uniform across venues — the mode field announces what actually happened.
use sequence_sdk::RedeemMode;
let r = seq.redeem("fed-decision-…", "polymarket").await?;
match r.mode {
RedeemMode::AutoSettled => {} // Kalshi — already paid
RedeemMode::RelayerSubmitted => {} // Polymarket — async credit in mins
RedeemMode::Noop => {} // nothing to redeem
}mode | Meaning |
|---|---|
auto_settled | Kalshi settles on the venue side. Balance already reflects payout — no action taken. |
relayer_submitted | Polymarket. L2-HMAC-signed POST fired to the CLOB relayer. USDC credit asynchronously in minutes. |
noop | Nothing to redeem for this identity on this market. |
Risk ops
Halt new submission for the caller's identity. Existing open orders are NOT cancelled — pair with cancel_all_on_venue for stop-everything.
seq.kill_switch_engage(Some("hedge breach")).await?;
seq.cancel_all_on_venue("hyperliquid").await?;
// kill_switch_clear() is admin-only