Overview
The TWAP stream contains Time-Weighted Average Price (TWAP) order status updates from the Hyperliquid exchange. TWAP orders are algorithmic orders that execute gradually over a specified time period to minimize market impact.
Stream Type: TWAP
API Availability: gRPC Streaming API + JSON-RPC/WebSocket APIs
Volume: Low - Most blocks are empty; only updates when TWAP orders change status
Data Structure
Most blocks are empty because TWAP status updates only occur when an order changes state. Each event represents one status change, including waiting for a trigger, activation, completion, cancellation, a stop-price exit, or an error.
The current structure adds two nullable fields to state:
triggercontrols when a TWAP starts.stopPxlimits the price at which an active TWAP continues executing.
{
"local_time": "2026-09-09T12:49:13.941834396",
"block_time": "2026-09-09T12:49:13.781306253",
"block_number": 1141302834,
"events": [
{
"time": "2026-09-09T12:49:13.781306253",
"twap_id": 2200278,
"state": {
"coin": "VVV",
"user": "0x2306ce07ddca3829cdb1a2a14653dbefc211a9f1",
"side": "A",
"sz": "500.0",
"executedSz": "98.36",
"executedNtl": "2731.82602",
"minutes": 30,
"reduceOnly": true,
"randomize": false,
"timestamp": 1788957799491,
"trigger": null,
"stopPx": "27.5"
},
"status": "stopped"
}
]
}
Event Fields
| Field | Type | Description |
|---|---|---|
| time | string | Event timestamp (ISO 8601 format) |
| twap_id | integer | Unique identifier for the TWAP order |
| state | object | Current state of the TWAP order |
| status | string or object | TWAP order status. Normal statuses are strings; errors are objects with an error string (see Status Types below) |
State Object Fields
| Field | Type | Description |
|---|---|---|
| coin | string | Trading pair identifier (e.g., "HYPE", "xyz:NVDA", "@107") |
| user | string | User address who created the TWAP order |
| side | string | Order side: "B" (Buy) or "A" (Ask/Sell) |
| sz | string | Total target size for the TWAP order |
| executedSz | string | Amount executed so far |
| executedNtl | string | Notional value executed (price × size) |
| minutes | integer | Duration of TWAP order in minutes |
| reduceOnly | boolean | Whether order can only reduce position (cannot increase) |
| randomize | boolean | Whether execution timing is randomized to avoid detection |
| timestamp | integer | TWAP order creation timestamp (Unix milliseconds) |
| trigger | object or null | Activation condition. Null means the TWAP does not wait for a trigger |
| stopPx | string or null | Maximum execution price for a buy TWAP or minimum execution price for a sell TWAP. Null means no stop price is configured |
Trigger Object Fields
When trigger is not null, parse it as the following object:
| Field | Type | Description |
|---|---|---|
| px | string | Mark-price threshold that activates the TWAP. Keep it as a decimal string when exact precision matters |
| above | boolean | When true, the TWAP activates when the mark price reaches or crosses px from below. When false, it activates when the mark price reaches or crosses px from above |
trigger and stopPx are independent. A TWAP can use either field, both fields, or neither field. For example, a TWAP can wait for trigger.px before activating and then stop later if the mark price crosses stopPx.
Status Types
TWAP orders progress through different status states during their lifecycle. A triggered TWAP normally moves from waitingForTrigger to activated, then reaches a terminal status.
| Status | Description |
|---|---|
| activated | TWAP order has been created and is actively executing |
| waitingForTrigger | TWAP order has been accepted but will not start until its trigger condition is met |
| finished | TWAP execution window ended. Compare executedSz with sz because the full target size is not guaranteed to fill |
| stopped | Active TWAP stopped because the mark price crossed its configured stopPx boundary; partial execution is possible |
| terminated | TWAP order was cancelled or otherwise terminated before its execution window ended; partial execution is possible |
| { error: string } | TWAP could not proceed. The error field describes the failure |
Parsing Example
The following TypeScript types model the current QuickNode TWAP dataset. Decimal values are strings and should remain strings, or be parsed with a decimal library, when exact precision matters.
type TwapTrigger = {
px: string;
above: boolean;
};
type TwapStatus =
| 'waitingForTrigger'
| 'activated'
| 'finished'
| 'stopped'
| 'terminated'
| { error: string };
interface TwapEvent {
time: string;
twap_id: number;
state: {
coin: string;
user: string;
side: 'B' | 'A';
sz: string;
executedSz: string;
executedNtl: string;
minutes: number;
reduceOnly: boolean;
randomize: boolean;
timestamp: number;
trigger: TwapTrigger | null;
stopPx: string | null;
};
status: TwapStatus;
}
twapHistoryIn this dataset, normal status values are strings, while errors use an object such as "status": { "error": "Insufficient margin to place order." }. The identifier is twap_id. Hyperliquid's Foundation twapHistory response uses a nested status object for normal statuses, such as "status": { "status": "stopped" }, uses twapId, and returns its top-level time as Unix seconds. Do not apply the Foundation response type directly to a QuickNode dataset event.
Example Records
Triggered TWAP Awaiting Activation
This representative record shows how to parse non-null trigger and stopPx fields. The buy TWAP waits for the mark price to reach 120.0, then stops if the mark price crosses its maximum of 130.0.
{
"time": "2026-09-09T12:50:00.000000000",
"twap_id": 2200307,
"state": {
"coin": "XYZ",
"user": "0x1111111111111111111111111111111111111111",
"side": "B",
"sz": "10.0",
"executedSz": "0.0",
"executedNtl": "0.0",
"minutes": 60,
"reduceOnly": false,
"randomize": true,
"timestamp": 1788958200000,
"trigger": {
"px": "120.0",
"above": true
},
"stopPx": "130.0"
},
"status": "waitingForTrigger"
}
Activated TWAP Order
{
"time": "2025-12-04T17:00:22.417074898",
"twap_id": 1430699,
"state": {
"coin": "HYPE",
"user": "0x9d6a5ab97a8eed617bde9968d9ab6fcf72fde1b8",
"side": "A",
"sz": "108.36",
"executedSz": "0.0",
"executedNtl": "0.0",
"minutes": 10,
"reduceOnly": false,
"randomize": false,
"timestamp": 1764867622417,
"trigger": null,
"stopPx": null
},
"status": "activated"
}
Finished TWAP Order
{
"time": "2025-12-04T17:00:39.012600357",
"twap_id": 1430683,
"state": {
"coin": "xyz:NVDA",
"user": "0x130506ec2875c51eaf6fa2632ee952205a3dd793",
"side": "A",
"sz": "1.0",
"executedSz": "1.0",
"executedNtl": "183.83588",
"minutes": 5,
"reduceOnly": false,
"randomize": false,
"timestamp": 1764867337234,
"trigger": null,
"stopPx": null
},
"status": "finished"
}
Terminated TWAP Order (Partially Executed)
{
"time": "2025-12-04T17:05:55.357168702",
"twap_id": 1430645,
"state": {
"coin": "HYPE",
"user": "0xdce7148dd9418e01129192095954a5ad3d75b0cc",
"side": "B",
"sz": "100.59",
"executedSz": "25.94",
"executedNtl": "897.98844",
"minutes": 120,
"reduceOnly": false,
"randomize": true,
"timestamp": 1764866098571,
"trigger": null,
"stopPx": null
},
"status": "terminated"
}
Long Duration TWAP (210 minutes)
{
"time": "2025-12-04T17:03:28.969809817",
"twap_id": 1430703,
"state": {
"coin": "xyz:NVDA",
"user": "0xa993ad31ef46873c0193448dbb2f04c0d3854731",
"side": "B",
"sz": "27.11",
"executedSz": "0.0",
"executedNtl": "0.0",
"minutes": 210,
"reduceOnly": false,
"randomize": false,
"timestamp": 1764867808969,
"trigger": null,
"stopPx": null
},
"status": "activated"
}
Outcome Market TWAP (HIP-4)
Outcome assets (HIP-4) appear as #N-prefixed coins in TWAP records. The structure is identical to standard TWAPs.
{
"time": "2026-05-02T10:55:26.396453316",
"twap_id": 1783904,
"state": {
"coin": "#0",
"user": "0x81a39aa0b0d6fa8513aa79929e7c01dfaa232fce",
"side": "B",
"sz": "10000.0",
"executedSz": "0.0",
"executedNtl": "0.0",
"minutes": 5,
"reduceOnly": false,
"randomize": false,
"timestamp": 1777719326396,
"trigger": null,
"stopPx": null
},
"status": "activated"
}
API Usage
gRPC Streaming
// Subscribe to TWAP updates
const request = {
subscribe: {
stream_type: 'TWAP',
filters: {
user: { values: ['0x123...'] },
coin: { values: ['BTC', 'ETH'] },
status: { values: ['activated', 'finished'] }
}
}
};
JSON-RPC
# Get latest TWAP blocks
curl -X POST https://your-endpoint.hype-mainnet.quiknode.pro/your-token/hypercore \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "hl_getLatestBlocks",
"params": {
"stream": "twap",
"count": 10
},
"id": 1
}'
WebSocket
// Subscribe to TWAP updates
ws.send(JSON.stringify({
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streamType": "twap"
},
"id": 1
}));
Important Notes
- Sparse Data: Most blocks have empty event arrays because TWAP events are emitted only when an order changes state
- TWAP ID Linking: The
twap_idfield can be used to correlate with individual fills in the Trades dataset (wheretwapIdfield references thistwap_id) - Execution Progress: Compare
executedSztoszto determine completion percentage - Triggered Start: When
triggeris notnull, the order remains inwaitingForTriggeruntil the mark price crossestrigger.pxin the direction indicated bytrigger.above - Stop Price:
stopPxis a maximum price for buys and a minimum price for sells; crossing it moves the order tostopped - Randomization: When
randomizeistrue, order execution timing is randomized to avoid predictable patterns - Reduce-Only Orders: When
reduceOnlyistrue, the TWAP order can only reduce existing positions - Duration Range: TWAP orders can run from 5 minutes to 7 days (10,080 minutes)
- Suborder Timing: Suborder intervals are calculated dynamically from the total size and duration, with a minimum interval of 30 seconds
- Order Minimums: The minimum TWAP notional is $100, while each suborder must still meet a $10 minimum notional
- Partial Execution: Terminated orders may have partial execution (non-zero
executedSzless thansz)