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

# rwa_multichain.perp_trades

> Taker-leg fills on RWA perpetual futures markets, currently covering Hyperliquid HIP-3 builder-deployed perps.

export const PremiumDatasetAccessCard = ({href = "https://dune.com/enterprise#contact-form"}) => <Card title="Premium dataset access" icon="info" href={href}>
    This dataset is part of a premium offering and requires additional access. Contact the Dune enterprise team to request access.
  </Card>;

`rwa_multichain.perp_trades` is the cross-venue fill table for RWA perpetual futures — synthetic exposure to a real-world asset with no tokenized share involved. Grain: one taker-leg fill per row, keyed on `(blockchain, block_month, block_date, unique_key)`. Today it carries Hyperliquid HIP-3 markets; the schema is venue-agnostic so other perp venues can be unioned in without a breaking change.

<PremiumDatasetAccessCard />

## Taker leg only

Every trade has a buyer and a seller, and the source data emits a fill for each. This table keeps only the taker leg, where `crossed = true`.

That is a deliberate choice: it means `SUM(notional_usd)` matches the volume Hyperliquid itself reports for a market, rather than double-counting both sides. If you sum an exchange feed that includes both legs, you get twice the real number.

The trade-off is that **maker-side analysis is not possible from this table**. You cannot measure market-maker fill rates or maker inventory. `closed_pnl` is also deliberately absent, since it is only meaningful per-account with the full position history.

## Table schema

| Column                        | Type        | Description                                                             |
| ----------------------------- | ----------- | ----------------------------------------------------------------------- |
| `blockchain`                  | `VARCHAR`   | Venue chain. `hyperliquid` today                                        |
| `block_month`                 | `DATE`      | Partition column                                                        |
| `block_date`                  | `DATE`      | Fill date                                                               |
| `block_time`                  | `TIMESTAMP` | Fill timestamp                                                          |
| `block_number`                | `BIGINT`    | Block height                                                            |
| `perp_dex`                    | `VARCHAR`   | Builder DEX short code                                                  |
| `coin`                        | `VARCHAR`   | Full market id in `dex:SYMBOL` form, e.g. `xyz:TSLA`                    |
| `market_symbol`               | `VARCHAR`   | Market ticker within the builder DEX                                    |
| `asset_id`                    | `VARCHAR`   | HIP-3 asset id. **Join key to `rwa_hyperliquid.markets.token_address`** |
| `side`                        | `VARCHAR`   | `buy` or `sell`, from the taker's perspective                           |
| `price`                       | `DOUBLE`    | Fill price                                                              |
| `size`                        | `DOUBLE`    | Fill size in contract units                                             |
| `notional_usd`                | `DOUBLE`    | USD notional of the fill                                                |
| `fill_type`                   | `VARCHAR`   | `order`, `twap`, `liquidation`, or `adl` (auto-deleveraging)            |
| `builder_name`                | `VARCHAR`   | Builder DEX full name                                                   |
| `trader`                      | `VARCHAR`   | Taker address                                                           |
| `dir`                         | `VARCHAR`   | Raw direction string from the source, e.g. Open Long, Close Short       |
| `fee`                         | `DOUBLE`    | Protocol fee paid                                                       |
| `builder_fee`                 | `DOUBLE`    | Fee routed to the builder                                               |
| `deployer_fee`                | `DOUBLE`    | Fee routed to the market deployer                                       |
| `twap_id`                     | `BIGINT`    | TWAP order identifier, for `fill_type = 'twap'`                         |
| `liquidation_method`          | `VARCHAR`   | Liquidation mechanism, for `fill_type = 'liquidation'`                  |
| `liquidation_liquidated_user` | `VARCHAR`   | Account that was liquidated                                             |
| `liquidation_mark_px`         | `DOUBLE`    | Mark price at liquidation                                               |
| `oid`                         | `BIGINT`    | Order identifier                                                        |
| `tid`                         | `BIGINT`    | Trade identifier                                                        |
| `unique_key`                  | `VARCHAR`   | Row identifier                                                          |
| `_updated_at`                 | `TIMESTAMP` | When this row was last written by the pipeline                          |

<Warning>
  `asset_id` is `VARCHAR` here and joins to `rwa_hyperliquid.markets.token_address`, also `VARCHAR`. Do **not** join it to `markets.asset_id`, which is the same value typed as `INTEGER`.

  A perp has no `token_id` and never joins to `rwa_multichain.tokens` — there is no token behind it.
</Warning>

## fill\_type matters for volume

Liquidations and auto-deleveraging are forced fills, not discretionary trading. In a typical week `order` fills dominate (\~13.8M), followed by `twap` (\~1.2M), `liquidation` (\~42K), and `adl` (\~500). Exclude the forced types when measuring genuine trading demand:

```sql theme={null}
WHERE fill_type IN ('order', 'twap')
```

TWAP fills are one order sliced into many small fills, so they inflate trade counts far more than volume. Count distinct `twap_id` rather than rows if you want order-level counts.

## Getting asset class

This table has no `asset_class`. Join [`rwa_hyperliquid.markets`](/data-catalog/curated/rwa/registry/hyperliquid-markets) for classification, issuer, and leverage:

```sql theme={null}
SELECT
  m.asset_class,
  m.underlying_ticker,
  p.builder_name,
  COUNT(*) AS fills,
  SUM(p.notional_usd) AS volume_usd
FROM rwa_multichain.perp_trades p
JOIN rwa_hyperliquid.markets m
  ON m.blockchain = p.blockchain
  AND m.token_address = p.asset_id
WHERE p.block_date >= current_date - INTERVAL '7' day
  AND p.fill_type IN ('order', 'twap')
GROUP BY 1, 2, 3
ORDER BY 5 DESC
LIMIT 25
```

## Example query

```sql theme={null}
-- Daily volume and taker activity per market
SELECT
  block_date,
  market_symbol,
  builder_name,
  COUNT(*) AS fills,
  COUNT(DISTINCT trader) AS unique_takers,
  SUM(notional_usd) AS volume_usd,
  SUM(fee + builder_fee + deployer_fee) AS total_fees_usd
FROM rwa_multichain.perp_trades
WHERE block_date >= current_date - INTERVAL '7' day
  AND block_date < current_date
GROUP BY 1, 2, 3
ORDER BY 1 DESC, 6 DESC
```

**Liquidation activity:**

```sql theme={null}
SELECT
  block_date,
  market_symbol,
  COUNT(*) AS liquidations,
  COUNT(DISTINCT liquidation_liquidated_user) AS accounts_liquidated,
  SUM(notional_usd) AS liquidated_notional_usd
FROM rwa_multichain.perp_trades
WHERE block_date >= current_date - INTERVAL '30' day
  AND fill_type IN ('liquidation', 'adl')
GROUP BY 1, 2
ORDER BY 5 DESC
LIMIT 50
```

<Note>
  For pre-aggregated volume, open interest, and funding rather than raw fills, use [`perp_metrics_hourly`](/data-catalog/curated/rwa/activity/perp-metrics-hourly) or [`perp_metrics_daily`](/data-catalog/curated/rwa/activity/perp-metrics-daily).
</Note>
