> ## Documentation Index
> Fetch the complete documentation index at: https://docs.allium.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Guide

> Understanding the hyperliquid DEX and data characteristics

This section is a collection of extra documentation on the workings of Hyperliquid L1.
It is not exhaustive, rather it complements the [Hyperliquid Docs](https://hyperliquid.gitbook.io/hyperliquid-docs).

For each section under Sources where the Parent is

* Datastreams then entity is the Kafka Topic name
* Snowflake then the entity is the table name

# Assets

<Warning>
  In a lot of the data sources, especially datastreams and tables in the raw schema you will find assets listed as a number.

  This is how Hyperliquid refers to them. They are normally a trading Pair.
</Warning>

<Tip>
  Where the asset is simply an index.

  Perpetuals - index in the universe field returned by the `meta` response.

  Spot - 10000 + index in the universe field returned by the `spotMeta` response.

  For example, when submitting an order for PURR/USDC, theset that should be used is 10000 because its asset index in the spot metadata is 0.
</Tip>

## Spot

<Tip>
  Spot Pairs are prefixed by an @
</Tip>

<Info>
  The Spot Pair PURR/USDC is the only one not referred to by an @index and instead you will see it referred by PURR/USDC
</Info>

[You can fetch the Hyperliquid Spot metadata here.](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-metadata)

Samples

```json theme={null}
{
  "tokens": [
...
    {
      "name": "HYPE",
      "szDecimals": 2,
      "weiDecimals": 8,
      "index": 150,
      "tokenId": "0x0d01dc56dcaaca66ad901c959b4011ec",
      "isCanonical": false,
      "evmContract": null,
      "fullName": "Hyperliquid",
      "deployerTradingFeeShare": "0.0"
    }
...
  ],
  "universe": [
...
    {
      "tokens": [
        150,
        0
      ],
      "name": "@107",
      "index": 107,
      "isCanonical": false
    }
...
  ]
}
```

Looking at the universe section we can see a index `107` with name `@107`

`@107` is what you will see in the hyperliquid data, and this refer to the trading pair `HYPE/USDC`

```
0 = USDC
150 = Hyper
```

## Perpetuals

[You can fetch the Hyperliquid Perpetual metadata here.](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-metadata-universe-and-margin-tables)

<Info>
  Perpetuals are easier than Spot, as the name is the Token which trades against USDC.
</Info>

For example

* HYPE will be HYPE/USDC.
* BTC will be BTC/USDC

# Funding Rates and Fees

## Historical Rates

Historical Funding Rates are available in `hyperliquid.raw.perpetual_market_asset_contexts`

**Example Data**

| TIMESTAMP               | COIN  | DAY\_BASE\_VOLUME   | DAY\_NATURAL\_VOLUME | OPEN\_INTEREST      | FUNDING      | PREMIUM       | IMPACT\_PRICES            | MARK\_PRICE  | MID\_PRICE   | ORACLE\_PRICE | PREVIOUS\_DAY\_PRICE | MAX\_LEVERAGE | \_CREATED\_AT           | \_UPDATED\_AT           |
| ----------------------- | ----- | ------------------- | -------------------- | ------------------- | ------------ | ------------- | ------------------------- | ------------ | ------------ | ------------- | -------------------- | ------------- | ----------------------- | ----------------------- |
| 2025-09-12 00:15:00.000 | SYRUP | 4762555.0000000000  | 2159913.4026699993   | 11635584.0000000000 | 0.0000862455 | 0.0011820433  | \["0.464999", "0.465207"] | 0.4650300000 | 0.4651100000 | 0.4644500000  | 0.4431300000         | 3             | 2025-09-12 00:16:10.342 | 2025-09-12 00:16:10.342 |
| 2025-09-12 00:15:00.000 | MAV   | 6811783.0000000000  | 471417.9629660000    | 4238730.0000000000  | 0.0000125000 | -0.0001864601 | \["0.069577", "0.069707"] | 0.0696310000 | 0.0696570000 | 0.0697200000  | 0.0635690000         | 3             | 2025-09-12 00:16:10.342 | 2025-09-12 00:16:10.342 |
| 2025-09-12 00:15:00.000 | PYTH  | 29175950.0000000000 | 5101855.4974899963   | 27527772.0000000000 | 0.0000098288 | -0.0006291059 | \["0.179335", "0.179507"] | 0.1795000000 | 0.1794650000 | 0.1796200000  | 0.1697300000         | 5             | 2025-09-12 00:16:10.342 | 2025-09-12 00:16:10.342 |

## Fees

Fees are available in streams and as historical data.

### Historical

Historical Funding Fees are available in `hyperliquid.raw.misc_events`

**Example Data**

Query: `select * from hyperliquid.raw.misc_events where event:Funding is not null limit 3;`

| HASH                                                               | TIME                    | EVENT                                                                                                                                                                   | \_CREATED\_AT           | \_UPDATED\_AT           |
| ------------------------------------------------------------------ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ----------------------- |
| 0x0000000000000000000000000000000000000000000000000000000000000000 | 2025-08-04 09:00:00.057 | `{"Funding": {"coin": "PENGU", "funding_amount": "0.000029", "funding_rate": "-0.0000076137", "szi": "109.0", "user": "0xffff407e5770f000ec93bc008d81b59acb505672"}}`   | 2025-08-04 09:17:23.414 | 2025-08-04 10:47:28.542 |
| 0x0000000000000000000000000000000000000000000000000000000000000000 | 2025-08-21 09:00:00.023 | `{"Funding": {"coin": "HYPE", "funding_amount": "14.595776", "funding_rate": "0.0000271144", "szi": "-13000.0", "user": "0xfffafff1445fb2d469b7f2d87fb3eadb8b1aa87e"}}` | 2025-08-21 09:06:09.769 | 2025-08-21 10:48:14.265 |
| 0x0000000000000000000000000000000000000000000000000000000000000000 | 2025-08-31 13:00:00.000 | `{"Funding": {"coin": "kPEPE", "funding_amount": "-0.005145", "funding_rate": "0.0000125", "szi": "41658.0", "user": "0xffff407e5770f000ec93bc008d81b59acb505672"}}`    | 2025-08-31 13:17:38.764 | 2025-08-31 15:17:37.427 |

### Streams

Funding Fees are streamed in `hyperliquid.misc_events`

Example Payload

```
{
  "payload": {
    "hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "inner": {
      "Funding": {
        "coin": "BTC",
        "funding_amount": "0.049819",
        "funding_rate": "0.0000125",
        "szi": "-0.0355",
        "user": "0xee963ef70d2e0468bf63630071c6968ae5e3074e"
      }
    },
    "time": "2025-09-10T11:00:00.127249976"
  },
  "source": "source"
}
```

# Orders

[For order types and options see the hyperliquid docs](https://hyperliquid.gitbook.io/hyperliquid-docs/trading/order-types#order-types)

## Market order fills

* Sources
  * **Datastreams**
    * hyperliquid.orders
    * hyperliquid.fills
  * **Snowflake**
    * hyperliquid.raw\.orders
* Filter by:
  * `status = 'filled'`
  * `type = 'market'`

## Limit order fills

* Sources
  * **Datasteam**
    * hyperliquid.orders
    * hyperliquid.fills
  * **Snowflake**
    * hyperliquid.raw\.orders
* Filter by
  * `status = 'filled'`
  * `type = 'limit'`

## **What are TWAP Orders?**

**It is an order which is divided into multiple suborders over a period of time set by user.**

**A suborder is sent every 30 seconds during the course of the TWAP.**

<Tip>
  TWAP stands for Time-Weighted Average Price.
</Tip>

<Warning>
  In hyperliquid TWAPs are executed automatically by the validators and as such they do not have a transaction hash, only the order to place a twap has a transaction hash. As such you will very often see trades and fills with `0x0000000000000000000000000000000000000000000000000000000000000000` as the transaction hash.

  For trades this means one side of the trade is a TWAP.

  For fill this means it is a TWAP fill.
</Warning>

## Twap fills

* Sources
  * **Datastreams**
    * hyperliquid.trades
    * hyperliquid.fills
  * **Snowflake**
    * hyperliquid.raw\.transactions
* Filter by
  * `hash = '0x0000000000000000000000000000000000000000000000000000000000000000'`

## Twap Open

* Sources
  * **Datastreams**
    * hyperliquid.transactions
  * **Snowflake**
    * hyperliquid.raw\.transactions
* Filter by
  * `action:type = 'twapOrder'`

## Twap Cancel

* Sources
  * **Datastreams**
    * hyperliquid.transactions
  * **Snowflake**
    * hyperliquid.raw\.transactions
* Filter by
  * `action:type = 'twapCancel'`

## Staking Activity

* Sources
  * **Datastream**
    * hyperliquid.misc\_events
  * **Snowflake**
    * hyperliquid.raw\.misc\_events
* Filter by
  * `inner: { CDeposit` for deposits
  * `inner: { CWithdrawal` for withdrawals

# Liquidations

**There are two types of liquidations in hyperliquid.**

<Tip>
  **Market Liquidations**

  This is when Hyperliquid places an order to sell (for longs) and buy (for shorts) a user's position on the market.
</Tip>

<Tip>
  **HLP Vault Liquidations**

  This is a last effort, when the above Market Liquidations fails, ie due to lack of liquidity. In this case the HLP Vault acquires the position, and takes the loss (if any).
</Tip>

## Market Liquidations

* Datastreams
  * hyperliquid.fills
* Snowflake
  * hyperliquid.raw\.fills

### Market Liquidation Example

```
{
...
  "liquidation": {
    "liquidatedUser": "0x444591887598c8ce607e8315daa61ead3dc0e912",
    "markPx": "2.3725",
    "method": "market"
  },
...
}
```

This will be wrapped in a payload key

```
{
  "payload": [
    "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05",
    {
      "closedPnl": "-9.94483",
      "coin": "ETH",
      "crossed": false,
      "dir": "Liquidated Isolated Long",
      "fee": "0.0",
      "feeToken": "USDC",
      "hash": "0x13286c0383f6dbbf94db0425f954ba0205a300395397739c419f7da34f95f99d",
      "liquidation": {
        "liquidatedUser": "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05",
        "markPx": "2323.3",
        "method": "backstop"
      },
      "oid": 104754754832,
      "px": "2316.0",
      "side": "A",
      "startPosition": "0.1037",
      "sz": "0.1037",
      "tid": 361622066638684,
      "time": 1750541100096
    }
  ],
  "source": "source"
}
```

## HLP Vault Liquidations

* Sources
  * **Datastreams**
    * hyperliquid.misc\_events
    * hyperliquid.fills
  * **Snowflake**
    * hyperliquid.raw\.misc\_events
    * hyperliquid.raw\.fills

The HLP Vault Liquidation shows up in both the misc events and the fills.

In the `fills` it will show up with both sides, and one side being the HLP Vault.

### Fills

**Liquidated User Fill**

```
{
  "payload": [
    "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05",
    {
      "closedPnl": "-9.94483",
      "coin": "ETH",
      "crossed": false,
      "dir": "Liquidated Isolated Long",
      "fee": "0.0",
      "feeToken": "USDC",
      "hash": "0x13286c0383f6dbbf94db0425f954ba0205a300395397739c419f7da34f95f99d",
      "liquidation": {
        "liquidatedUser": "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05",
        "markPx": "2323.3",
        "method": "backstop"
      },
      "oid": 104754754832,
      "px": "2316.0",
      "side": "A",
      "startPosition": "0.1037",
      "sz": "0.1037",
      "tid": 361622066638684,
      "time": 1750541100096
    }
  ],
  "source": "source"
}
```

**HLP Vault Fill**

```
{
  "payload": [
    "0xb0a55f13d22f66e6d495ac98113841b2326e9540",
    {
      "closedPnl": "0.0",
      "coin": "ETH",
      "crossed": true,
      "dir": "Liquidated Isolated Long",
      "fee": "0.0",
      "feeToken": "USDC",
      "hash": "0x13286c0383f6dbbf94db0425f954ba0205a300395397739c419f7da34f95f99d",
      "liquidation": {
        "liquidatedUser": "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05",
        "markPx": "2323.3",
        "method": "backstop"
      },
      "oid": 104754754832,
      "px": "2316.0",
      "side": "B",
      "startPosition": "7177.3205",
      "sz": "0.1037",
      "tid": 361622066638684,
      "time": 1750541100096
    }
  ],
  "source": "source"
}
```

### Misc Events

```
{
  "payload": {
    "hash": "0x13286c0383f6dbbf94db0425f954ba0205a300395397739c419f7da34f95f99d",
    "inner": {
      "LedgerUpdate": {
        "delta": {
          "accountValue": "0.756264",
          "leverageType": "Isolated",
          "liquidatedNtlPos": "240.92621",
          "liquidatedPositions": [
            {
              "coin": "ETH",
              "szi": "0.1037"
            }
          ],
          "type": "liquidation"
        },
        "users": [
          "0x4e8ffa69c78d7a067e1795fbe16a5c80c90b6c05"
        ]
      }
    },
    "time": "2025-06-21T21:25:00.096291909"
  },
  "source": "source"
}
```

# Order Book

The easiest way to keep an updated order book is to read from the Datastream `orders` and applying it to a snapshot of the L2 Orderbook or the L4 Orderbook snapshot.

[L2 Orderbook snapshot](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#l2-book-snapshot)

[L4 Orderbook snapshot](/api/developer/hyperliquid/orderbook-snapshot)

Once you have the snapshot, you can use the `orders` datastream to update the snapshot.

[All the possible order statuses can be found in the Hyperliquid Docs](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#query-order-status-by-oid-or-cloid)

# Trade Ids

<Info>
  Trade ids are not guaranteed to be unique.
</Info>

Trade ids are a 50bit hash of the buyer and seller order ids.

For a unique id use `coin`, `timestamp` and `trade id` for trades and additionally `user` for fills.

# Orders explained

The trading engine does not emit the orders in the same way that it does for fills, nor are they bound to trading engine timestamps.

They are not 1-1. For every order with the status filled you may not find a counter order with the status filled.

We'll pick the only order with this timestamp that has the status filled.

At a first glace we'd expect to see another order with the status filled as well. (buyer and seller)

But this is not the case let's see why.

```
select *
from hyperliquid.raw.orders 
where date_trunc('millisecond', status_change_timestamp) = '2025-09-03 05:46:43.881'::timestamp_ntz and status = 'filled';
```

It's a filled order. If you across the timestamp, you will find it is the only filled order.

So let's take the order id and find the corresponding fill.

```
select * from hyperliquid.raw.fills where order_id = '151749521496';
```

From there we get the trade id (See trade ids section for caveats info on trade ids)

```
select * from hyperliquid.raw.fills where trade_id = '879183392645577';
```

Now we should see two fills, so get the order id from the other fill, the counter order

```
select * from hyperliquid.raw.orders where order_id = '151749449008';
```

We found the counter order.

But we don't have a filled status; you can see it was opened then cancelled.

This is because the time in force is Alo

* It went into the order book
* Got a partial fill (you can see the size is less on the cancelled than the open)
* It was cancelled, so as to not remove liquidity from the order book.

# Time in Force Explained

## Alo

The **ALO (Add Liquidity Only)** time-in-force option works similarly to “Post Only” on other exchanges.

**How ALO Works**

* When you place an order with **ALO**, the system ensures that your order will **only add liquidity to the order book**.
* If your order would **immediately match with an existing order** (thus taking liquidity), Hyperliquid will automatically **cancel it** instead of executing.
* This prevents you from accidentally paying **taker fees**, guaranteeing that you only act as a **maker**.

## GTC

**GTC (Good ’Til Canceled)**

* A **GTC order** will remain active on the order book until it is either **filled or manually canceled** by you.
* It does **not expire automatically**, regardless of how much time passes.
* This is the **default time-in-force** on most exchanges, including Hyperliquid.
* Useful if you want your order to stay in the market and wait for execution, even if it takes hours or days.

## IOC

**IOC (Immediate or Cancel)**

* An **IOC order** must be **filled immediately** (fully or partially) when it reaches the order book.
* Any portion of the order that **cannot be instantly matched** will be **canceled right away**.
* This makes IOC useful when you want to **execute as much as possible instantly**, but don’t want leftover orders sitting on the book.
* Traders often use IOC for **quick entries/exits** or to avoid resting exposure on the book.
