---
title: "Closed Trades"
method: GET
path: "/gateway/v1/hyperliquid/trades"
tags: ["Hyperliquid"]
---

# Closed Trades

`GET /gateway/v1/hyperliquid/trades`

Returns a wallet's closed round-trip trades — one row per open→close position lifecycle, with realized per-trade P&L (gross, net = gross − fees, fees, and `funding_pnl` as a **separate** field that net EXCLUDES), entry/exit price, size, and hold time. Newest close first. This is the journal / calendar / attribution source; for fill-level executions use `/hyperliquid/fills` instead.

Returns EVERY closed trade in the window — it does NOT filter by symbol or direction (a `symbol`/`direction` query param is ignored, not applied); for per-symbol / per-direction rollups use `/hyperliquid/trades/aggregate`, or `/hyperliquid/fills` for symbol-scoped fills. `funding_pnl` is 0 for warehouse rows and populated only on the live tail, so a funding-inclusive total is incomplete before the watermark.

Cursor-paged over the full history (warehouse + a live gap-fill for the most recent days): follow `meta.next_cursor` to page back. The cursor is a complete continuation token (it encodes the window + position), so pass it with only `address` and `limit` — combining it with `from`/`to` is rejected. `from`/`to` (Unix seconds or a date) bound the window on the first page. A wallet with an extremely large live (post-warehouse) trade history may require a `from`/`to` window.

## Query parameters

- `address` string, required — Wallet address: a 0x EVM address or an ENS name (e.g. vitalik.eth). Solana addresses are not supported.
- `symbol` string — NOT SUPPORTED on /trades — returns 400 if set. Per-symbol slicing lives on /trades/aggregate (group_by=symbol) or client-side.
- `direction` 'long' | 'short' — NOT SUPPORTED on /trades — returns 400 if set. Per-direction slicing lives on /trades/aggregate (group_by=direction) or client-side.
- `dex` string — NOT SUPPORTED on /trades — returns 400 if set. Market scoping lives on /trades/aggregate (dex=...).
- `from` string — Window start: Unix seconds, an ISO datetime (2026-03-01T12:00:00Z), or a bare date (= midnight UTC). Omit for the full history.
- `to` string — Window end, inclusive: 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.
- `cursor` string — Opaque continuation token from a previous response's meta.next_cursor. It encodes the window, position, and address, so pass it with only address + limit — and only with the address it was issued for. Tokens are single-use opaque values: identical requests mint different tokens that decode to the same position.
- `limit` integer — Page size (1-100).

## Response `200`

OK

- CursorDataResponseHyperliquidEpisode
  - `$schema` string, uri — A URL to the JSON Schema for this object.
  - `data` HyperliquidEpisode[], nullable, required
    - `close_time` integer, required — When the position fully closed (Unix seconds)
    - `direction` string, required — long or short (side of the opening leg)
    - `entry_px` number, double, required — Size-weighted average entry price, USD
    - `episode_id` string — Stable per-wallet episode id (the opening fill's trade id). Present on warehouse rows; OMITTED on live-tail rows (assigned when the episode lands in the warehouse) — dedup live rows by (symbol, open_time, close_time) until then.
    - `exit_px` number, double, required — Size-weighted average exit price, USD
    - `fees` number, double, required — Fees paid over the episode, USD
    - `funding_pnl` number, double, required — Funding paid/received over the episode, USD (positive = received). A separate field — net_pnl EXCLUDES funding. Check funding_status before displaying this compatibility value.
    - `funding_status` 'complete' | 'partial' | 'unavailable', required — Whether funding_pnl is usable. complete distinguishes a real zero from unavailable historical data; partial is reserved for incomplete attribution.
    - `gross_pnl` number, double, required — Realized PnL before fees, USD
    - `hold_seconds` integer, required — Duration the position was held, seconds
    - `is_win` boolean, required — net_pnl > 0
    - `leverage` integer — Opening leverage multiplier. Omitted unless the source contract proves opening-time semantics.
    - `leverage_semantics` 'completed_trade_reported' — Explicit meaning of reported_leverage; omitted when unavailable.
    - `leverage_type` 'cross' | 'isolated' — Opening margin mode. Omitted unless opening-time semantics are proven.
    - `net_pnl` number, double, required — Realized PnL after fees, USD (funding excluded — gross_pnl − fees)
    - `notional_usd` number, double, required — Opened notional, USD (opened_sz × entry_px) — the size figure /trades/aggregate's volume_usd sums
    - `open_time` integer, required — When the position opened (Unix seconds)
    - `opened_sz` number, double, required — Total size opened over the episode (token units)
    - `reported_leverage` integer — Leverage associated with the completed-trade record; not asserted to be the opening value.
    - `reported_leverage_type` 'cross' | 'isolated' — Margin mode associated with reported_leverage.
    - `source` string, required — warehouse (from the ClickHouse build) or live (Hydromancer gap-fill past the warehouse watermark)
    - `symbol` string, required — Market id the trade was in (BTC, kPEPE, xyz:GOLD)
  - `meta` CursorMeta, required
    - `cached` boolean, required — Whether this response was served from cache
    - `credits_used` integer, required — Credits deducted for this request
    - `empty_reason` string — Hint explaining why the data array is empty, when applicable
    - `has_more` boolean, required — Whether more items exist beyond the current page.
    - `limit` integer, required — Maximum number of items returned in this response
    - `next_cursor` string — Opaque cursor token for fetching the next page. Empty when no more pages exist.
    - `watermark` integer — Warehouse watermark (Unix seconds) this response was computed at, on warehouse-backed endpoints (e.g. Hyperliquid /trades) — rows up to this time come from the warehouse, newer rows from the live tail. Omitted elsewhere.

## Other responses

- `default` — Error

---

[API](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api.md) · [All operations](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/asksurf/asksurf-public-rest-api/revisions/4153a9cb5145/schema)
