Closed Trades Aggregate

GET/gateway/v1/hyperliquid/trades/aggregate

Returns a wallet's closed trades rolled up server-side into one row per group — so the P&L calendar, per-symbol / direction / size attribution, and the realized equity curve are one call each instead of paging the whole trade history.

`group_by`: `day` (UTC calendar day — the calendar and equity-curve source), `symbol` (per market), `direction` (long vs short), `size_bucket` (notional-USD tiers: `<1k`, `1k-10k`, `10k-100k`, `100k-1m`, `1m+`), or `hold_bucket` (holding-time tiers: `<5m`, `5m-1h`, `1h-1d`, `1d-1w`, `1w+`). Tiers with no trades are omitted — render the full ladder client-side and zero-fill. One dimension per call.

Per group: trade_count, gross_pnl, net_pnl (funding-excluded — gross − fees, matching `/trades` and `/performance`), fees, funding_pnl (live tail only), win_rate, volume_usd (notional), avg_win, avg_loss.

`from`/`to` (Unix seconds or a date) bound close_time; omit for full history. Totals reconcile to `/trades` and `/performance` — all three read the same `episodes` universe (warehouse ≤ watermark plus the live gap-fill past it) through one shared watermark; only the live gap-fill contributes trades past the watermark, and `funding_pnl` is populated on that tail alone. `dex` scopes to one market (omit to aggregate across markets). For `group_by=day`, `fill_gaps=true` emits zero rows for no-trade days (a dense calendar; requires `from`). Not paginated — every group in the window is returned in one response.

Query Parameters

addressstringrequired

Wallet address: a 0x EVM address or an ENS name (e.g. vitalik.eth). Solana addresses are not supported.

group_byenum<string>

Dimension to roll up by. day = UTC calendar day (the P&L calendar / equity-curve source); symbol = per market; direction = long vs short; size_bucket = notional-USD tiers; hold_bucket = holding-time tiers.

Available options:daysymboldirectionsize_buckethold_bucket
fromstring

Window start, bounds close_time: Unix seconds, an ISO datetime (2026-03-01T12:00:00Z), or a bare date (= midnight UTC). Omit for full history.

Example: 2026-03-01
tostring

Window end, inclusive, bounds close_time: Unix seconds, an ISO datetime, or a bare date — a bare date means the END of that UTC day, so from=X&to=X covers the whole day X. Defaults to now.

Example: 2026-03-31
dexenum<string>

Market scope: main_dex for the native market only, omit to aggregate across ALL markets, or a builder market — one of: xyz, flx, vntl, hyna, km, abcd, cash, para, mkts. NOTE: the omit default differs from /leaderboard, where omitting dex means the native market only.

Available options:main_dexxyzflxvntlhynakmabcdcashparamkts
fill_gapsboolean

group_by=day only: emit a zero row for every no-trade UTC day in the window so the calendar is dense. Requires from (a bounded window); ignored for other group_by values.

Closed Trades Aggregate
const options = {method: 'GET'};

fetch('https://api.asksurf.ai/gateway/v1/hyperliquid/trades/aggregate?from=2026-03-01&to=2026-03-31', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
OK
{
  "$schema": "https://example.com/schemas/DataResponseHyperliquidTradeGroup.json",
  "data": [
    {
      "avg_loss": 123,
      "avg_win": 123,
      "fees": 123,
      "funding_pnl": 123,
      "gross_pnl": 123,
      "key": "<string>",
      "net_pnl": 123,
      "trade_count": 123,
      "volume_usd": 123,
      "win_rate": 123
    }
  ],
  "meta": {
    "cached": true,
    "credits_used": 123,
    "empty_reason": "<string>",
    "has_more": true,
    "limit": 123,
    "offset": 123,
    "total": 123,
    "watermark": 123
  }
}