All articles
Hyperliquid·May 27, 2026·4 min read

Building an Iceberg Order Bot on Hyperliquid Perps

Tutorial on chunking large perp orders into iceberg slices to avoid signaling to HFT competitors, with WebSocket-driven order placement logic and dynamic clip sizing based on real-time order book depth.

If you are trading more than a few thousand dollars of notional on Hyperliquid perps, your order size is visible to every HFT firm and scraper watching the L2. The moment a 50k USDC limit order lands on the book, latency-sensitive participants front-run the residual. Iceberg execution is the practical countermeasure: you show only a small "tip" at a time, replenish it programmatically, and finish your position without telegraphing intent.

Why Hyperliquid Specifically

Hyperliquid's on-chain order book means every resting order is public and permanent in the ledger — there is no concept of hidden quantity like some centralized venues offer. That changes the implementation. You cannot instruct the exchange to hide your size; you have to manage it yourself by sending a sequence of smaller orders in rapid succession, each sized to clear or partially fill before the next one is queued. The WebSocket API makes this tractable. The l2Book and trades subscriptions give you sub-100 ms latency on book updates, which is fast enough to react to fills and replenish before a competing algorithm can statistically infer your full intent.

The Core Loop

The bot subscribes to two channels simultaneously: l2Book for the target instrument and userFills for your own account. Pseudocode for the control flow:

on_fill(fill):
    remaining -= fill.sz
    if remaining > 0 and not cooldown_active:
        send_next_clip()

on_book_update(book):
    recalculate_clip_size(book)
    if clip_slot_empty and remaining > 0:
        send_next_clip()

The key invariant is that at most one clip order is resting on the book at any time per side. Multiple simultaneous clips increase the statistical fingerprint of your activity; a sophisticated observer can sum adjacent resting orders and reconstruct your approximate position target. One clip, one slot.

Dynamic Clip Sizing

Static clip sizes are a crutch. A 500 USDC clip in a thin market moves price; the same clip in a deep book is invisible. The right sizing input is the available quantity within your price tolerance on the opposite side of the book.

A practical formula:

available_depth = sum(qty for price, qty in asks if price <= limit + tolerance)
clip_size = clamp(available_depth * participation_rate, min_clip, max_clip)

participation_rate is the fraction of available depth you want to consume per clip — 0.05 to 0.15 is a typical starting range. min_clip prevents dust orders that eat gas budget unnecessarily; max_clip is your hard ceiling regardless of depth. For most liquid Hyperliquid pairs (BTC-PERP, ETH-PERP, SOL-PERP) you can set max_clip at 2–5k USDC notional and remain under the noise floor of most HFT detection heuristics.

Timing and Cooldowns

Do not replenish immediately on fill. A fill followed within milliseconds by another order of the same size at the same price is a textbook iceberg signature. Insert a jittered cooldown between 200 ms and 800 ms. The jitter matters — a fixed 500 ms interval is as detectable as no cooldown at all because it creates a visible metronomic pattern in trade timestamps.

Also handle partial fills carefully. If your 500 USDC clip partially fills to 300 USDC and the residual is cancelled, you still have 200 USDC of that clip unexecuted. Track this separately and fold it into the next clip's sizing rather than re-sending a standalone 200 USDC order, which would narrow the apparent clip size and compress your timing signature in the wrong direction.

State Machine and Error Handling

The bot needs explicit states: IDLE, CLIP_RESTING, COOLDOWN, DONE, and ERROR. Transitions should be driven purely by WebSocket events, not polling. If the WebSocket connection drops mid-execution, the bot must reconcile state on reconnect by querying open orders and fills before resuming. Resuming blind on a stale state will double-count remaining size and either over-execute or leave a dangling order resting at a stale price.

On Hyperliquid, cancel-on-disconnect is not available in the same way as on some CEXs. Persist your clip order ID to a local store (Redis or even a plain file) so you can cancel it programmatically on restart. An orphaned order at a stale price while you are trying to rebuild state is a common source of slippage in live deployments.

Measuring Execution Quality

The only metric that matters is VWAP slippage versus your arrival mid-price. Log the mid-price at strategy start, then compute:

slippage_bps = (execution_vwap / arrival_mid - 1) * 10000  # for a buy

Run this across sessions and segment by clip_size / avg_depth to understand where your participation rate starts hurting you. In practice, staying below 8–10% participation rate per clip on liquid pairs keeps slippage under 2 bps for order sizes up to 200k USDC, which is competitive with professional execution desks.

The TierZero bots service covers production implementations of strategies like this — iceberg, TWAP, and adaptive-spread market making — deployed and monitored end to end.


If you are running size on Hyperliquid and want execution infrastructure that handles all of this in production, reach out via the contact page and we can scope what a bespoke implementation looks like for your strategy.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Hyperliquid#trading-bots#order-execution#perps#iceberg-orders#WebSocket#HFT