Hyperliquid data is currently in beta and the schemas are subject to change. DEX Trades:

Data is backfilled, but as of March 2025, the Hyperliquid API has a limitation so only the last 10k trades per address are available. This means that we’re unable to get 100% coverage of trades for ~1% of traders (~4,000 traders). Once this is accessible, any gaps will be backfilled.

Hyperliquid is an L1 built to support an ecosystem of permisionless financial applications. The flagship native application is the Hyperliquid DEX, a fully onchain order book exchange.

Tables

Using hyperliquid.dex.trades is recommended as it enriches the raw.trades table with relevant trade & token metadata

Table NameDescription
hyperliquid.raw.tradesRaw Hyperliquid spot & perpetual trades data This is available as a real-time Kafka stream without the extra_fields column.
hyperliquid.dex.tradesEnriched Hyperliquid spot & perpetual trades data.
hyperliquid.raw.tokensList of tokens that are traded on Hyperliquid DEX, with token metadata such as token name and symbol. Currently only includes spot tokens.
hyperliquid.assets.transfersToken transfers on Hyperliquid L1. Currently only includes deposits & withdrawals for Arbitrum. (Coming Soon) Bitcoin, Ethereum, Solana
hyperliquid.raw.ordersShows order status changes. So when an order goes from open, to filled, cancelled or any other possible status. Currently the order ‘open’ status is not showed, as this is a limitation in the information provided by the node. Subsequent status changes will be reflected.

Coming Soon

Widthdrawals and deposits into Hyperliquid across Arbritrum, Bitcoin, Ethereum and Solana. See how value is flowing across chains.

L1 blocks with transactions.

  • Track user interactions across HyperEVM and HyperCore L1.
  • Track builder fees (what fees are applications charging)

Sample Queries

Get total monthly DEX volume on Hyperliquid over time

SELECT
    DATE_TRUNC('MONTH', timestamp) AS month,
    token_a_symbol,
    SUM(usd_amount) AS volume_usd
FROM hyperliquid.dex.trades
GROUP BY ALL

Get all available trades for a given user

select
    *
from hyperliquid.dex.trades
where 1=1
    and (buyer_address = <address_to_search> or seller_address = <address_to_search>)

Get all trades of BTC in the last 24 hours

select
    *
from hyperliquid.dex.trades
where 1=1
    and token_a_symbol = 'BTC'
    and timestamp >= current_timestamp - interval '24 hours'

Get a list of tokens traded in the last 24 hours, with a breakdown of spot vs perpertuals volume, ordered by total USD volume traded

select
    token_a_symbol,
    sum(case when market_type = 'spot' then usd_amount else 0 end) as total_spot_usd_amount,
    sum(case when market_type = 'perpetuals' then usd_amount else 0 end) as total_perpetuals_usd_amount,
    sum(usd_amount) as total_usd_amount,
from hyperliquid.dex.trades
where 1=1
    and timestamp >= current_timestamp - interval '24 hours'
group by all
order by total_usd_amount desc

Get daily activity metrics, aggregated by token, for the last 7 days

select
    date(timestamp) as day,
    token_a_symbol,
    count(distinct buyer_address) as num_buyers,
    count(distinct seller_address) as num_sellers,
    sum(usd_amount) as total_usd_amount,
from hyperliquid.dex.trades
where 1=1
    and timestamp >= current_timestamp - interval '7 days'
group by all
order by 1 asc

We can use some simple queries to view market resistance levels for the last 24 hours. (For more sophisticated clustering consider exporting the data and usind statiscal tools to identify clusters.)

Please be advised that this data is currently incomplete as open orders are still missing. We are working to complete this data set. However this will give you some sense of the levels.

  • Limit losses levels
    • The query below give you levels where traders are more likely to sell to limit their losses.
-- Dynamic binning for Stop orders based on each coin's price range
WITH coin_price_ranges AS (
    SELECT 
        COIN,
        MIN(TRIGGER_PRICE) as min_price,
        MAX(TRIGGER_PRICE) as max_price,
        (MAX(TRIGGER_PRICE) - MIN(TRIGGER_PRICE))/20 as bin_size -- Create 20 bins across the range
    FROM hyperliquid.raw.orders
    WHERE IS_TAKE_PROFIT_OR_STOP_LOSS = TRUE
    AND TYPE IN ('Stop Market', 'Stop Limit')
    AND STATUS_CHANGE_TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
    GROUP BY COIN
)

SELECT 
    o.COIN,
    'Stop Orders' as order_category,
    FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) * r.bin_size as price_bin_start,
    (FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) + 1) * r.bin_size as price_bin_end,
    COUNT(*) as order_count
FROM hyperliquid.raw.orders o
JOIN coin_price_ranges r ON o.COIN = r.COIN
WHERE o.IS_TAKE_PROFIT_OR_STOP_LOSS = TRUE
AND o.TYPE IN ('Stop Market', 'Stop Limit')
AND o.STATUS_CHANGE_TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
GROUP BY o.COIN, order_category, FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) * r.bin_size, (FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) + 1) * r.bin_size
ORDER BY o.COIN, price_bin_start;
  • Take Profit Levels
    • This will give you the levels where traders are more likely to take profits.
-- Dynamic binning for Take Profit orders based on each coin's price range
WITH coin_price_ranges AS (
    SELECT 
        COIN,
        MIN(TRIGGER_PRICE) as min_price,
        MAX(TRIGGER_PRICE) as max_price,
        (MAX(TRIGGER_PRICE) - MIN(TRIGGER_PRICE))/20 as bin_size -- Create 20 bins across the range
    FROM hyperliquid.raw.orders
    WHERE IS_TAKE_PROFIT_OR_STOP_LOSS = TRUE
    AND TYPE IN ('Take Profit Market', 'Take Profit Limit')
    AND STATUS_CHANGE_TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
    GROUP BY COIN
)

SELECT 
    o.COIN,
    'Take Profit Orders' as order_category,
    FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) * r.bin_size as price_bin_start,
    (FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) + 1) * r.bin_size as price_bin_end,
    COUNT(*) as order_count
FROM hyperliquid.raw.orders o
JOIN coin_price_ranges r ON o.COIN = r.COIN
WHERE o.IS_TAKE_PROFIT_OR_STOP_LOSS = TRUE
AND o.TYPE IN ('Take Profit Market', 'Take Profit Limit')
AND o.STATUS_CHANGE_TIMESTAMP >= DATEADD(hour, -24, CURRENT_TIMESTAMP())
GROUP BY o.COIN, order_category, FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) * r.bin_size, (FLOOR(o.TRIGGER_PRICE / NULLIF(r.bin_size, 0)) + 1) * r.bin_size
ORDER BY o.COIN, price_bin_start;
  • Circular Trading - two addresses trading back and forth
WITH trading_pairs AS (
    SELECT 
        BUYER_ADDRESS,
        SELLER_ADDRESS,
        COIN,
        COUNT(*) as trade_count,
        SUM(USD_AMOUNT) as total_volume
    FROM hyperliquid.dex.trades
    WHERE TIMESTAMP >= DATEADD(day, -30, CURRENT_TIMESTAMP()) -- Last 30 days
    GROUP BY BUYER_ADDRESS, SELLER_ADDRESS, COIN
    HAVING COUNT(*) >= 10 -- At least 10 trades between the same pair
),
reverse_pairs AS (
    SELECT 
        a.BUYER_ADDRESS,
        a.SELLER_ADDRESS,
        a.COIN,
        a.trade_count as forward_count,
        b.trade_count as reverse_count,
        a.total_volume as forward_volume,
        b.total_volume as reverse_volume
    FROM trading_pairs a
    JOIN trading_pairs b ON a.BUYER_ADDRESS = b.SELLER_ADDRESS 
                         AND a.SELLER_ADDRESS = b.BUYER_ADDRESS
                         AND a.COIN = b.COIN
    WHERE a.BUYER_ADDRESS < a.SELLER_ADDRESS -- To avoid duplicate pairs
)

SELECT 
    BUYER_ADDRESS,
    SELLER_ADDRESS,
    COIN,
    forward_count,
    reverse_count,
    forward_count + reverse_count as total_trades,
    forward_volume,
    reverse_volume,
    forward_volume + reverse_volume as total_volume,
    ABS(forward_count - reverse_count) / (forward_count + reverse_count) as trade_count_imbalance,
    ABS(forward_volume - reverse_volume) / (forward_volume + reverse_volume) as volume_imbalance
FROM reverse_pairs
ORDER BY total_trades DESC;

Table Columns

Column NameDescription
market_typeThe type of market for the trade, e.g. spot, perpetuals
coinA unique identifier for the asset being traded: • The coin for perpetuals is the standard token symbol, e.g. HYPE • The coin for spot tokens is an ID representing a pair of tokens based on Hyperliquid’s metadata, e.g. @4 (coin) represents token 5/token 0, which corresponds to JEFF/USDC The metadata is available from the info endpoint of Hyperliquid’s API
token_a_symbolThe symbol of the first token in the trading pair
token_b_symbolThe symbol of the second token in the trading pair. At the moment, this is always USDC
amountThe quantity of token_a being traded (normalized)
priceThe execution price of token_a for the trade, in terms of token_b (usually USDC)
usd_amountThe quantity of token_a being traded, in USD terms
buyer_addressThe address of the buyer in the trade
seller_addressThe address of the seller in the trade
timestampThe UTC timestamp of when the trade was executed
transaction_hashThe transaction hash for the trade. There can be multiple trades (i.e. multiple records with different trade_id) for the same transaction_hash. *See notes for Null Transaction hash.
trade_idAn identifier for the trade. Some historical trades share a tid of 0
unique_idA unique identifier for each trade
extra_fieldsAdditional information for each trade. See notes for more details.

Notes

The extra_fields column contains additional information for each trade including fees and liquidation details. Some caveats to be aware of:

  • New trades are first fetched from Hyperliquid Websocket API, so the extra_fields are initially unavailable. We attempt to refetch all new trades via the Info endpoint, to source the extra_fields. Given the 10k transaction limit on the API, it’s possible that some trades cannot be refetched.
  • Because of the above, trades may have:
    • extra_fields not populated with buyer or seller details: this means the trade could not be backfilled with additional information. These can be identified by extra_fields:source = 'api.hyperliquid.xyz/ws'
    • extra_fields populated with one of the buyer or seller details: we were able to backfill details for one side of the trade (i.e. the buy side or sell side)
    • extra_fields populated with both buyer and seller details: we were able to backfill details for both sides of the trade

**Sample on **

{
  "buyer": {
    "builder_fee": null,
    "closed_pnl": "0.0",
    "crossed": true,
    "dir": "Open Long",
    "fee": "0.0",
    "fee_token": "USDC",
    "liquidation": null,
    "order_id": 80667495079,
    "start_position": "99492.0"
  },
  "seller": {
    "builder_fee": null,
    "closed_pnl": "0.0",
    "crossed": false,
    "dir": "Open Short",
    "fee": "0.0",
    "fee_token": "USDC",
    "liquidation": null,
    "order_id": 80667490005,
    "start_position": "-361760.0"
  },
  "source": "api.hyperliquid.xyz/info"
}

FAQs

Is it possible to fetch all historical trades of <address>?

The Hyperliquid API currently has a limitation, so only the last 10k trades for each address is available. If an address has made less than 10k trades as of the time of backfill (~March 2025), then all their historical trades will be available. However, fetching all historical trades is not currently possible for addresses that have done more than 10k trades. Once historical data becomes accessible, any gaps will be backfilled.

**How are liquidations treated in the **dex.tradestable?

To find liquidations, look for any dex.trades where the HLP Liquidator (0x2e3d94f0562703b25c83308a05046ddaf9a8dd14) is either the buyer or seller address.

Hyperliquidity Provider (HLP) is a protocol vault that does market making and liquidations. The HLP Liquidator is a component strategy that’s part of the HLP. As per Hyperliquid, “this strategy liquidates positions on all coins as soon as they become liquidatable. Once it acquires these positions, it exits the positions using a market making algorithm.”

**Why is the buyer or seller (sometimes both) in **extra_fieldsin the trades table sometimes null?

This is due to two current limitations. (We are working on improving these.)

  1. Hyperliquid’s endpoint not returning more than the 10000 latest fills.
  2. Hyperliquid’s api rate limiting, which causes us to not be able to fetch the data for all the trades fast enough.

Issue 1 coupled with 2 can cause us to not be able to fetch the fills before the the end up outside the 10000 limit, for users with very high trading volume.