Streams referenceQuickNode-compatible

TWAP algos

Native TWAP order status and execution progress, as it fills.

Status events for Hyperliquid's native TWAP orders: who is running them, total and executed size, executed notional (giving average fill price), duration, and lifecycle status. Useful for large-order detection and flow analysis.

Method
hyperliquid.Streaming/StreamData (stream_type: TWAP)
Endpoint
stream.hyperliquidrpc.com:443 · gRPC over TLS (HTTP/2)
Auth
API key in x-api-key metadata
Volume
Low volume relative to fills, since only institutional TWAPs appear here. Cheap to subscribe to platform-wide.

When to use it

Native TWAPs are how size moves quietly on Hyperliquid. This stream announces them: who started a TWAP, in which market, how big, over how many minutes, and, as progress events arrive, how much has executed at what notional. Use it for large-order detection, flow-aware execution (trade around a TWAP, not into it), and studying how algorithmic sell/buy programs move markets.

Volume is low (institutional TWAPs only), so a platform-wide, unfiltered subscription is cheap. The individual child fills are not here; they arrive on the trades stream tagged with the same twap_id.

Method

// stream.hyperliquidrpc.com:443 — gRPC over TLS (HTTP/2)// auth: API key in x-api-key metadata · server reflection enabledpackage hyperliquid; service Streaming {  // Bidirectional: send one subscription, then read updates.  // Subscribe with stream_type: TWAP.  rpc StreamData (stream SubscribeRequest) returns (stream SubscribeUpdate);}

QuickNode-compatible StreamData with stream_type: TWAP. Each update carries the block number and the TWAP event payload as JSON.

Subscribe

# StreamData is bidirectional; grpcurl sends the subscription for you.grpcurl -H 'x-api-key: YOUR_KEY' \  -d '{"subscribe":{"stream_type":"TWAP"}}' \  stream.hyperliquidrpc.com:443 \  hyperliquid.Streaming/StreamData

The example subscribes platform-wide. Add coin or user filters to narrow to one market or one wallet's algos.

Message fields

FieldTypeDescription
twap_iduint64TWAP identifier; joins to twap_id on fills.
coinstringMarket symbol.
userstringWallet running the TWAP.
sidestringB (buy) or A (sell).
szstringTotal TWAP size.Byte-exact decimal string.
executed_szstringSize executed so far.Byte-exact decimal string.
executed_ntlstringNotional executed so far; divide by executed_sz for average fill price.Byte-exact decimal string.
minutesuint32Configured duration.
statusstringactivated / finished / canceled / terminated.

Fields typed string that carry numbers are byte-exact decimal strings, verbatim from the node. Compare and store them as strings or arbitrary-precision decimals. Never parseFloat a price you intend to reconcile.

Server-side filters

  • coins[]
  • wallets[]
  • replay from a block height

Filters are applied on the server, so filtered-out messages never leave our edge. You only pay for what you subscribe to. Request shapes for every stream family are on Filtering; backfill semantics on Replay & backfill.

Semantics & gotchas

Event stream: one message per TWAP status change or progress update, in block order.

  • One TWAP, many messages. You receive a message per status change and progress update. Key your state on twap_id and treat each message as the latest view of that parent order.
  • Average fill price is a division away. executed_ntl / executed_sz gives the running average fill price. Both are byte-exact decimal strings; divide as decimals, not floats.
  • Lifecycle has four terminal-ish states. activated starts the clock; finished, canceled, and terminated end it. A canceled TWAP keeps whatever it executed.
  • Child fills live on the trades stream. Fills belonging to a TWAP carry its twap_id on the trades/swaps feed. Join the two streams for slice-by-slice execution detail.

Sample message

{  "block_height": 612408201,  "twap_id": 48112,  "coin": "HYPE",  "user": "0xa4f17bd09e26c3158c0b7341fa882ce05d97b264",  "side": "B",  "sz": "25000.00",  "executed_sz": "9412.36",  "executed_ntl": "116214.872340",  "minutes": 60,  "randomize": true,  "status": "activated"}

Low volume relative to fills, since only institutional TWAPs appear here. Cheap to subscribe to platform-wide.

Recipes

Alert on large TWAPs as they start

Watch activated events and flag programs whose total size matters in their market. A 60-minute sell program announced at activation is actionable information for the entire window.

from decimal import Decimal for update in stub.StreamData(iter([subscribe]), metadata=meta):    ev = json.loads(update.data.data)    if ev["status"] == "activated" and Decimal(ev["sz"]) > Decimal("10000"):        alert(ev["coin"], ev["user"], ev["sz"], ev["minutes"])

Track execution progress and slippage

On each progress update, compute the running average fill price and compare it to the mark at activation. This measures what the program is paying for its patience.

from decimal import Decimal ev = json.loads(update.data.data)if Decimal(ev["executed_sz"]) > 0:    avg_px = Decimal(ev["executed_ntl"]) / Decimal(ev["executed_sz"])    done = Decimal(ev["executed_sz"]) / Decimal(ev["sz"])  # fraction complete

Join child fills by twap_id

Subscribe to trades for the same market and group fills by twap_id. You get each slice's exact price, size, and timing: the full execution trace of someone else's algo.

Related