Skip to main content

Hyperliquid HIP-3 Stocks API

HIP-3 lets anyone deploy a perpetual market on Hyperliquid. In practice that has produced a full off-chain asset complex trading on-chain: S&P 500, Nasdaq-100, individual US equities, country ETFs, gold, oil, natural gas and FX — all as perps settled in USDC on HyperCore.

Bitquery indexes every HIP-3 market alongside the native perps, in the same Hyperliquid cube. This page covers how to address those markets, and the queries that matter for pricing, market making and basis trading against the underlying.

The video ranks the HIP-3 stock, index and commodity perps by volume and by number of traders over one week.

API Key Required

To query or stream data outside the Bitquery IDE, you need an API access token.

Follow the steps here: How to generate Bitquery API token ➤

How HIP-3 markets are addressed​

Every market carries a Market object. Three fields identify a HIP-3 market:

FieldNative perpHIP-3 market
Kindperphip3
Protocolhypercorethe deployer, e.g. xyz, io, para, mkts, hyna
CoinRawBTCxyz:SP500 — deployer:symbol
SymbolBTCSP500 — the bare symbol

Two consequences worth knowing before you write a filter:

  • Symbol is not unique across deployers. SNDK trades under both xyz: and io:, AVGO under both xyz: and para:, UNITREE under xyz: and para:. Filter on CoinRaw when you mean one specific market, and on Symbol only when you deliberately want every deployer's version of the same underlying.
  • Filter the whole asset class with Kind, not with a Protocol allowlist. New deployers appear without notice; Kind: {is: "hip3"} keeps working.

List every HIP-3 market​

Ranks all HIP-3 markets by USD volume over the last 24 hours, with trade and distinct trader counts. Every match has a maker row and a taker row, so volume and trades count the taker side only. This is the discovery query — run it first to see what exists right now.

Run it in the IDE: Hyperliquid HIP-3 Markets ➤

query {
Hyperliquid {
Trades(
limit: {count: 300}
orderBy: {descendingByField: "volumeUsd"}
where: {
Trade: {Market: {Kind: {is: "hip3"}}}
Block: {Time: {since_relative: {hours_ago: 24}}}
}
) {
Trade {
Market { Symbol CoinRaw Protocol }
}
volumeUsd: sum(of: Trade_Execution_NotionalUSD, if: {Trade: {Execution: {IsAggressor: true}}})
trades: count(if: {Trade: {Execution: {IsAggressor: true}}})
traders: count(distinct: Trade_Trader_Address)
}
}
}

Swap Kind for Protocol: {is: "xyz"} to scope to a single deployer.

Trades on a stock market​

Every fill on xyz:SP500, both sides of each match. IsAggressor marks the taker, and a negative Fee is a maker rebate. Execution.Index is the fill's place in its block (all fills of a block share Block.Time), and Position.Size the account's position after the fill.

Run it in the IDE: Hyperliquid SP500 Perp Trades ➤

query {
Hyperliquid {
Trades(
limit: {count: 50}
orderBy: {descending: [Block_Time, Trade_Execution_Index]}
where: {Trade: {Market: {CoinRaw: {is: "xyz:SP500"}}}}
) {
Block { Time }
Trade {
Market { Symbol CoinRaw Kind Protocol }
Execution { Price Size Side Direction IsAggressor Index Oid Tid }
Fees { Fee FeeToken BuilderFee }
Position { Leverage IsCross SizeBefore Size RealizedPnl }
Trader { Address }
}
}
}
}

Change CoinRaw to any market from the discovery query — xyz:NVDA, xyz:TSLA, xyz:GOLD, mkts:USTECH, io:GPRO.

Mark prices across all HIP-3 markets​

MarkPrices is a latest-state cube: one row per market holding its current mark, not a time series. Use it for a pricing snapshot; use Candles or Trades for history.

Run it in the IDE: Hyperliquid HIP-3 Mark Prices ➤

query {
Hyperliquid {
MarkPrices(
limit: {count: 200}
orderBy: {descending: LastTime}
where: {Market: {Kind: {is: "hip3"}}}
) {
LastTime
LastBlock
Mark
Market { Symbol CoinRaw Protocol }
}
}
}

Note the field names differ from the other cubes: LastTime / LastBlock rather than Block { Time }, and the price is Mark.

Basis: on-chain mark vs off-chain reference​

This is the query behind the HIP-3 arbitrage trade. PriceUpdates carries the oracle feed the market is priced against, and Kind separates the components:

KindMeaning
spotInputthe off-chain reference price for the underlying
markInputthe input to the on-chain mark
markthe published mark price
oraclethe published oracle price
extPerpInputexternal perp reference, where used
extPerpthe published external perp price

Because spotInput is indexed alongside the mark, the basis is computable from Bitquery alone — you do not need to bring your own equities feed just to measure the spread.

Run it in the IDE: Hyperliquid HIP-3 Basis Spread ➤

query {
Hyperliquid {
PriceUpdates(
limit: {count: 100}
orderBy: {descending: Block_Time}
where: {PriceUpdate: {Market: {CoinRaw: {is: "xyz:NVDA"}}}}
) {
Block { Time }
PriceUpdate {
Market { Symbol CoinRaw }
Kind
Price
DailyPx
UpdateClass
UpdateTime
}
}
}
}

Pair the spotInput series with Trades on the same market to see where fills landed relative to the reference, which is what decides whether a basis trade was actually capturable rather than just visible.

OHLCV candles for a stock perp​

Candles are pre-aggregated. Interval.Time.Duration is in seconds — 60 for 1m, 300 for 5m, 900 for 15m, 3600 for 1h.

Run it in the IDE: Hyperliquid Stock Perp Candles ➤

query {
Hyperliquid {
Candles(
limit: {count: 60}
orderBy: {descending: Interval_Time_Start}
where: {
Market: {CoinRaw: {is: "xyz:NVDA"}}
Interval: {Time: {Duration: {eq: 60}}}
}
) {
Interval { Time { Start Duration } }
Market { Symbol CoinRaw }
Ohlc { Open High Low Close Volume }
}
}
}

If you need an interval the Candles cube does not carry, aggregate Trades directly. Keep the taker side only, as Candles does, or every match counts twice in volume. open and close come from the first and last block of the interval; the fills of one block share Block_Time, so they can differ from the Candles values, which order fills by Execution.Index.

Run it in the IDE: Hyperliquid HIP-3 OHLC From Trades ➤

query {
Hyperliquid {
Trades(
limit: {count: 100}
orderBy: {descendingByField: "interval_Time"}
where: {
Trade: {Market: {CoinRaw: {is: "xyz:SP500"}}, Execution: {IsAggressor: true}}
Block: {Time: {since_relative: {hours_ago: 24}}}
}
) {
interval: Block { Time(interval: {in: minutes, count: 30}) }
open: Trade { Execution { Price(minimum: Block_Time) } }
high: Trade { Execution { Price(maximum: Trade_Execution_Price) } }
low: Trade { Execution { Price(minimum: Trade_Execution_Price) } }
close: Trade { Execution { Price(maximum: Block_Time) } }
volume: sum(of: Trade_Execution_Size)
trades: count
}
}
}

L4 order book for a stock perp​

BookUpdates are per-order deltas, not aggregated price levels. Each row names the order id and the wallet behind it, so you can reconstruct the book at any instant and measure queue position, order lifetime and maker behaviour.

Run it in the IDE: Hyperliquid Stock Book Updates ➤

subscription {
Hyperliquid {
BookUpdates(
where: {BookUpdate: {Market: {CoinRaw: {is: "xyz:NVDA"}}}}
) {
Block { Time }
BookUpdate {
Market { Symbol CoinRaw }
Kind
Side
Px
Size
SizeBefore
Oid
Trader { Address }
}
}
}
}

Kind is new, update or remove. Size is empty on a remove — the order is gone, so there is no resting size to report; use Px, Side and Oid to find the level it left. Change subscription to query and add limit / orderBy for history: without a Block: {Time: ...} filter the query covers the last 30 minutes, and about 7 days are kept.

Funding on HIP-3 markets​

Funding is per trader, per market, and settles hourly. Rate is the funding rate applied and Amount the USDC paid or received.

Run it in the IDE: Hyperliquid HIP-3 Funding ➤

query {
Hyperliquid {
PerpFundings(
limit: {count: 50}
orderBy: {descending: Block_Time}
where: {Funding: {Market: {Kind: {is: "hip3"}}}, Block: {Time: {since_relative: {hours_ago: 2}}}}
) {
Block { Time }
Funding {
Market { Symbol CoinRaw Protocol }
Trader { Address }
Rate
Amount
Size
}
}
}
}

Equity perps have no natural funding anchor overnight or at weekends, when the underlying market is closed. Funding is where that dislocation shows up, so this series is worth watching if you carry HIP-3 positions across a session boundary.

Liquidations on HIP-3 markets​

Run it in the IDE: Hyperliquid HIP-3 Liquidations ➤

query {
Hyperliquid {
PerpLiquidations(
limit: {count: 50}
orderBy: {descending: [Block_Time, Liquidation_Execution_Index]}
where: {Liquidation: {Market: {Kind: {is: "hip3"}}}}
) {
Block { Time }
Liquidation {
Market { Symbol CoinRaw Protocol }
LiquidatedUser
Liquidator
MarkPx
Method
Trader { Address }
Execution { Price Size Side Index }
Position { Leverage SizeBefore Size RealizedPnl }
}
}
}
}

Method distinguishes a market liquidation from a backstop one. Both sides of a forced fill are listed with the same LiquidatedUser: the row whose Trader.Address equals it is the liquidated account's own fill, the others are the accounts that took the other side. Sign a fill by Execution.Side (Buy adds, Sell subtracts).

Top traders on a stock market​

Ranks wallets by traded size on one market, with realized PnL. Useful for copy-trading, market-maker identification and flow analysis.

Run it in the IDE: Hyperliquid HIP-3 Top Traders ➤

query {
Hyperliquid {
Trades(
limit: {count: 50}
orderBy: {descendingByField: "volume"}
where: {
Trade: {Market: {CoinRaw: {is: "xyz:SP500"}}}
Block: {Time: {since_relative: {hours_ago: 24}}}
}
) {
Trade { Trader { Address } }
volume: sum(of: Trade_Execution_Size)
trades: count
pnl: sum(of: Trade_Position_RealizedPnl)
}
}
}

Field notes​

  • Prices and sizes are decimal strings, not floats, in every cube except Candles (whose Ohlc fields are floats). Parse with Decimal where precision matters.
  • A match produces two Trades rows, one per counterparty. Key a trade on (Block.Number, Market.CoinRaw, Execution.Tid) — not on Hash, which spans many matches and is all zeroes on both sides of a TWAP fill. Tid is a hash, not a sequence: to order the fills of a block, use Execution.Index (orderBy: {descending: [Block_Time, Trade_Execution_Index]}).
  • Position.SizeBefore and Position.Size are signed position sizes before and after the fill, negative for short. They are not money; realized PnL is Position.RealizedPnl.
  • Direction takes values like Open Long, Close Short and Short > Long — a flip through flat is one fill, not two.
  • Retention. These cubes are served from realtime with roughly a 30-day window (about 7 days for Orders, BookUpdates and SignedActions). For longer ranges, see Data Coverage & Retention. For older data, ask about a Data Store export.
Build with Bitquery

Ready to run this in production?

Get an API key and run these queries in minutes, or talk to us about plans and enterprise delivery.