Exchange is a Decentralized Perpetuals Trading Platform Evaluated for Partial-Fill Orders
Exchange is an operational checklist for submitting Hyperliquid perpetual orders, recognizing partial execution and accounting for unmatched size in the final order state. Read the per-order output, compare totalSz with the signed quantity and treat every IOC remainder as canceled before sending another order.
What's inside
The short version: It is an operational checklist for Hyperliquid perp traders, mapping signed order submission, partial-fill states, output checks, and IOC cancellation of unfilled size.
IOC versus GTC when unfilled size must disappear
When an unfilled remainder must vanish immediately, Hyperliquid IOC is the correct choice; GTC instead leaves any unmatched size resting on the HyperCore book.
HyperCore assigns an order book to each asset and matches orders in price-time priority. A trader selects the exact perpetual market, side, size, limit price, reduce-only flag and time-in-force. Native perp execution has no AMM pool or multi-hop route; venue selection means choosing the correct HyperCore or builder-deployed perp DEX and its asset identifier. IOC crosses only liquidity priced at the limit or better, then cancels the residual. GTC retains the residual at its limit. Hyperliquid exposes 3 limit time-in-force choices: IOC, GTC and ALO; ALO rejects an order that would match immediately.
Many interfaces describe an aggressive IOC as a market order, yet the payload still carries a limit price. Hyperliquid's Python SDK follows this pattern, while CCXT maps the venue into a standard exchange interface. The price cap remains operational: liquidity beyond it is untouched, even when the trader wants immediate execution. The selected book and limit therefore define the fill boundary.
What should be checked before wallet confirmation?
Before a wallet or approved API agent signs a Hyperliquid order, confirm the account, perpetual asset, side, size, limit price, reduce-only setting and IOC time-in-force.
Precision is part of that approval because the validator rejects malformed price and size inputs before execution.
Perpetual prices accept up to 5 significant figures and no more than 6 minus the asset's
szDecimals
decimal places.
Size follows the asset's
szDecimals
value returned by the
meta
request, while integer prices remain valid. The intended notional must also clear the 10 USDC minimum for a perp order. These are payload properties, not cosmetic formatting in an interface. A rounded display can conceal a request carrying too many decimals, so compare the final signed strings with the market metadata before confirmation.
This is set out in practice.
HyperCore order placement is a signed L1 action, separate from an Arbitrum USDC deposit. MetaMask and Rabby render software prompts, while Ledger and Trezor add hardware confirmation.
API wallets, also called agent wallets, require their own nonce discipline. Hyperliquid stores the 100 highest nonces per signer; each new value must be unused, exceed the smallest stored nonce and fall between 2 days before and 1 day after block time. One API wallet shared across multiple processes or subaccounts shares one nonce set, so separate signing processes should use distinct agents. The connected topic is covered under HyperCore Order Books.
Exchange response states after signed submission
A submitted Hyperliquid order resolves into one of three immediate per-order response shapes: filled, resting or error, and each shape demands a different next action.
A filled object reports
totalSz,
avgPx
and
oid.
totalSz
is executed quantity; a smaller value than signed size identifies a partial IOC fill and residual cancellation. A resting object returns an
oid
for a live order, fitting GTC or ALO rather than an IOC remainder. An error records rejection such as invalid tick precision, insufficient margin or inability to match. The outer
status
value
ok
confirms endpoint processing, not full execution. Normally, statuses mirror the count and order of submitted requests. Pre-validation is the exception: one error can represent the entire batch. HyperCore records order, cancel and trade actions with one-block finality under HyperBFT.
How do you reconcile partial fills without double-counting?
Partial-fill reconciliation on Hyperliquid starts with executed size, not requested size: sum fills by order identifier and compare the total with the signed quantity.
The WebSocket API separates
orderUpdates
from
userFills: the first tracks order-state changes and the second carries executions. Streaming fill messages include coin, price, size, side, time, starting position, closed PnL, transaction hash and order identifier. A reconnect begins with a snapshot flag, after which live updates set it false.
The
userFillsByTime
response returns at most 2000 fills and exposes only the 10,000 most recent fills.
With
aggregateByTime
enabled, crossing-order partials are combined; fills of a resting order combine only when they share one block.
Reconciliation should use the traded account's 42-character address, never the agent wallet used only to sign. If the stream is uncertain, query
orderStatus
by the 64-bit
oid
or optional 16-byte
cloid. Then join every fill sharing that order identifier, sum its size once and compare the total with the original request. Snapshot entries already stored must be deduplicated before subsequent live events are applied.
Partial-fill arithmetic from signed size to canceled residual
A partial-fill calculation is complete only when executed size, canceled residual, average price and resulting position change all reconcile to the original signed order.
Every changing input in this worked example is hypothetical: requested size, limit price, visible ask sizes and prices, executed size and average execution price. A trader signs an IOC buy for 2.40 ETH with a 2500 USDC limit. The selected HyperCore book shows 0.90 ETH at 2496, another 0.70 ETH at 2499 and the next 1.20 ETH at 2504. Only the first two levels satisfy the price cap. HyperBFT matching executes 1.60 ETH and cancels the remaining 0.80 ETH instead of placing it as a resting bid.
The weighted average is
(0.90 × 2496 + 0.70 × 2499) ÷ 1.60 = 2497.3125. The response should show
totalSz
of 1.60 and
avgPx
of 2497.3125 alongside the
oid. Executed notional before fees is 3995.70 USDC. Completion equals 1.60 divided by 2.40, or 66.67%; the canceled residual equals 2.40 minus 1.60, or 0.80 ETH. The position changes by 1.60 ETH, not the original 2.40 ETH. Size, average price, residual and position delta must agree before a recovery order is built.
Recovery starts with a fresh book and current position. Submit 0.80 ETH only if that exact residual remains required, using a new nonce and, when useful, a new cloid. If the original action used
expiresAfter, do not recycle it: expiry cancellation consumes 5 times the usual address-based rate limit. A reduce-only close also needs the reloaded position size before signing.
Who benefits from an IOC-first execution policy?
An IOC-first policy suits traders whose strategy values bounded residual exposure and immediate state clarity more than queue position on a resting order.
Automation is the clearest fit because it can persist signed size, parse
totalSz
and issue only the calculated residual. Hyperliquid recommends a separate API wallet per trading process and describes batching orders and cancels every 0.1 seconds; the documented structure handles out-of-order transactions within 2 seconds. A manual trader closing a position also benefits when an abandoned remainder would leave exposure unclear. ALO preserves post-only behavior; GTC preserves an unmatched residual. The complete IOC policy is to quote the chosen book, sign one bounded order, inspect its per-order status, reconcile fills and refresh both position and depth before repricing the remainder.
Everyday questions about Exchange
What happens if an IOC order finds no matching liquidity?
The order receives no fill and its full size is canceled during the IOC matching attempt. API output identifies the condition as an error such as IocCancel rather than a resting order identifier. Refresh the relevant HyperCore book, confirm the limit still reaches available prices and create a new signed request only if the trade remains required.
Can a partially filled reduce-only order reverse a position?
No, a reduce-only order is constrained to decrease the existing position rather than increase or reverse it. If an IOC close fills only part, Hyperliquid cancels the residual and leaves the smaller position open. Reload current position size before another close because a stale requested quantity can produce a reduce-only rejection or cancellation.
Does a client order ID prevent duplicate IOC submissions?
No, a client order ID provides correlation and cancellation addressing rather than automatic idempotency. Hyperliquid accepts an optional 128-bit cloid, while transaction replay control uses the signer's nonce. Store both values, reject a repeated strategy event locally and query order status before retrying when the first response is ambiguous.
When should the unfilled size be submitted again?
Resubmit only after the first IOC's executed size and canceled residual reconcile against the current position. Refresh the order book because the original depth and price boundary have already been consumed or changed. Build the next order for the exact remaining size, then assign a fresh nonce and, when used, a new cloid.
Why can one IOC order produce several fill records?
One IOC order can match several resting orders across eligible price levels, creating multiple execution records under the same oid. Sum their sizes once and calculate the size-weighted average price. The userFills aggregateByTime option combines crossing-order partials, while fills against a resting order combine only when they occur in the same block.
Are partial fills represented identically in CCXT and the Hyperliquid Python SDK?
The underlying Hyperliquid response is the common reference, but adapters can map its fields into different order models. Native filled output includes totalSz, avgPx and oid. Preserve the raw response, then confirm the library's filled and remaining fields are populated from totalSz before recovery logic decides what quantity to send next.
Who signs an IOC order for a Hyperliquid subaccount?
The master account or an approved API wallet signs actions on behalf of a Hyperliquid subaccount, while vaultAddress identifies the target subaccount. The subaccount itself has no private key. Account queries must use the actual master or subaccount address rather than the agent address, otherwise position and fill results will describe the wrong account context.