HL Cohorts
Cohort positioning for Hyperliquid perps - the cohort vocabulary, how each cohort is positioned now, and the hourly cohort matrix behind a positioning backtest.
2 tools for the cohort side of Hyperliquid: which cohorts of wallets exist and where each one is
positioned right now and hour by hour across all symbols (hl_segments), and one symbol's hourly positioning by
cohort over time (hl_cohort_metrics). They are the /v1/hl-cohorts REST routes shaped for an agent: each call reads one view, which is one
route, runs the same query function that route runs, and costs what that route costs. hl_segments takes a view;
hl_cohort_metrics has one view and no view parameter.
The behaviour every Hyperliquid tool shares (a call checked against its route before any query runs, symbol as the
instrument parameter, the new field names only, keyset cursors, and the units table, where bias and pct_wallets_in_profit
are both fractions) is stated once, under How these tools behave. The ladders
are explained on Cohorts and axes and when a label was computed on
Point-in-time vs current labels. For the current positioning of one symbol, hl_market on the
Hyperliquid page is the shorter read; hl_cohort_metrics is the one for research.
hl_cohort_metrics
1 credit. The hourly cohort matrix of one symbol: for every hour, how much long and short notional each bucket of one ladder holds. It answers "are whales or smart money long or short BTC", the history of that answer, and is the source for a positioning backtest.
| Parameter | Type | Default | Notes |
|---|---|---|---|
symbol | string | required | Instrument ticker, e.g. BTC; a HIP-3 market is dex:TICKER. An all-symbol matrix is refused |
axis | enum | size | size, pnl, pnl_abs, tier or pnl_unrealized; the ladders are described below |
start | string | — | ISO-8601 UTC lower bound |
end | string | — | ISO-8601 UTC upper bound |
opened_within | enum | all | 24h, 7d, 30d or all: positions opened in that window before each hour, rolling rather than relative to now. Anything but all is refused where the matrix is a stored aggregate (see below) |
hours | integer | 168 | Hourly buckets, newest first, max 8760. Pass 1 to 24 for a current read |
cursor | string | — | nextCursor from the previous page; it pages by whole hours |
label_basis | enum | — | current or point_in_time. Use point_in_time for any backtest |
grading | enum | — | realized (the default on pnl), realized-pit or unrealized; only on the pnl and pnl_unrealized axes |
include | string | — | Comma list of volume, median_pnl; default none. Adds to the NEWEST hour's rows volume_24h_usd (USD the cohort's wallets filled in this symbol in the last 24 hours; on size only wallets holding it now count; null if they filled nothing or the cohort is empty) and median_realized_pnl_usd (USD, median cumulative realized PnL over the DISTINCT wallets holding the symbol now; null if none does). The median is a sampled quantile: exact up to 8,192 wallets in a cohort, an estimate above it; the asset page's pnl-axis "Med Lifetime" counts positions rather than wallets, so it can differ slightly. Both are current figures, not that hour's, and null on unknown. Only axis=size or axis=pnl with the default grading; refused with opened_within, cursor or a past end. |
Returns {axis, label_basis, grading, metrics, hours, nextCursor}, plus label_computed on every
graded ladder (pnl, pnl_unrealized, pnl_abs) and freshness on a window that reaches the present.
Each metrics row is one hour for one cohort: ts, cohort, total_position_value and
total_position_value_long in USD, bias, and, except under label_basis=point_in_time, position_count,
position_count_long, total_unrealized_pnl, total_position_size and total_position_size_long. The
response holds about hours times the number of buckets on the ladder, so ask for hours=1 to 24 for a
current read and page older data with cursor; paging is by whole hours, so an hour never arrives with
some of its cohorts missing.
Three ladders are per wallet (size, pnl, pnl_abs); tier buckets each position by its own notional;
pnl_unrealized ranks wallets by the unrealized PnL of their open positions as a share of account value,
from the last snapshot before that hour. pnl_abs is always today's dollar bands, so it is look-ahead and
never for a backtest. The hour in progress is never returned, so a series that is differenced or z-scored
has no partial bar at its right edge. For the current value use hl_market view symbol_metrics.
opened_within is applied or refused, never dropped. It filters live positions, so it works on size,
tier, pnl_abs and on pnl with the default label basis. The stored sources (axis=pnl_unrealized,
grading=unrealized or realized-pit, and label_basis=point_in_time) have position age summed away, and the
REST route answers the all-ages matrix for any value there, including a value that is not an age. The tool
refuses anything but all in those combinations, naming the combination, and refuses a value that is not an age
everywhere.
For a backtest, pass label_basis=point_in_time. Without it the pnl ladder is today's grading
applied to past hours, which lets a wallet that is "smart" now label a period when it was not.
label_computed states which source labelled the window and names the point where the label's resolution
changes (daily before 2026-08-06, hourly after), which a turnover count will read as a regime change that is
an artefact. grading=realized-pit is a frozen control for a study that crosses it: it stops growing, so a
recent window comes back short, and freshness.behind_hours says by how much.
For a live read, check freshness. On a window that reaches the present the envelope carries
{newest_ts, behind_hours, settled_lag_ceiling_hours, stale}; stale is the verdict, so a caller does not
re-derive the rollup's cadence. A window that ends in the past has no freshness.
Are whales net long or short BTC right now, and how has that moved over the last 24 hours?
Compare smart-money and rekt positioning on ETH over the last month, with the cohort labels as they were at the time.
hl_segments
1 credit. The cohort vocabulary and its positioning at the latest snapshot. Read cohorts or segments
first to learn the exact labels, then summary for one cohort, heatmap for the whole board or history for
one cohort over time.
| Parameter | Type | Default | Notes |
|---|---|---|---|
view | enum | segments | segments, cohorts, summary, heatmap or history |
cohort | string | — | One label on axis, e.g. whale or 3x smart, spelled as cohorts lists it. Required by summary and history |
axis | enum | size | size, pnl or pnl_abs (summary, heatmap); history takes size or pnl only and requires it |
opened_within | enum | all | 24h, 7d, 30d or all (summary, heatmap); positions with no known open time are left out of every bounded window |
start | string | — | ISO-8601 UTC lower bound, e.g. 2026-10-01T00:00:00Z. history only; hours before 2026-04-07 are never returned. Used by view: history. |
end | string | — | ISO-8601 UTC upper bound, e.g. 2026-10-02T00:00:00Z. history only: with no start, the window is the hours newest hours at or before it. Used by view: history. |
hours | integer | 168 | history only: window length in hours when start is omitted, ending at end or now. Max 8760. Used by view: history. |
limit | integer | 5000 | history only: max hourly rows, newest first; has_more says older ones exist, page back with end = the oldest ts minus 1 second. Max 5000. Used by view: history. |
include | string | — | history only: comma list, only leverage; default none (nothing extra is read). Adds to every hourly row perp_bias = (long - short) / equity, equity_exposure = (long + short) / equity and equity_covered_share = main-dex notional of the counted wallets / main-dex notional of the whole cohort: unbounded ratios (above 1 = more than 1x of equity), native perp account only (main-dex positions of wallets with a known positive native equity, each wallet once; builder-DEX positions are not included). An hour with no stored row, and any hour before leverage.data_from (2026-08-11), is null on all three (never 0). perp_bias and equity_exposure are also null when no counted wallet has a positive equity; equity_covered_share is null when the cohort holds no main-dex notional and a real 0 when it holds some but no wallet is counted. Hours rebuilt from fills rather than read from snapshots are null. An unknown token is refused. Used by view: history. |
cohortsreturns{size, pnl, tier}, each a list of labels in ladder order (pnlalso holdsunknown, wallets under 10 closed trades). Everycohortparameter on every tool accepts exactly these strings.segmentsreturns one row per bucket withaxis,cohort,slug,rank,basis,applies_to,groupable, the bounds (min_usd,max_usd,percentile_min,percentile_max) andmin_closed_trades. It is how a client learns that thepnlladder is a percentile rank of cumulative realized PnL, not dollars, and thatpnl_absis dollars over the same PnL.groupableisfalsefortrade_size, which buckets a position rather than a wallet.summaryreturns everything one cohort holds across all symbols:total_long_usd,total_short_usd,total_value,bias,n_positions,n_wallets,n_wallets_in_profit,pct_wallets_in_profit,total_margin_used,total_equity,exposure_ratio(notional over margin used, the cohort's realized leverage),total_unrealized_pnland aby_sideblock.total_equityis the cohort's whole-account value, not the part backing the positions counted.heatmapreturns{axis, opened_within, snapshot_ts, source, totals, heatmap}: one row per symbol, ordered by total notional, each carrying its totals,biasand asegmentslist of the cohorts that hold anything in it. Empty cells are omitted rather than sent as zeros. It covers every symbol with open interest, so it is a large response.historyreturns one cohort hour by hour, summed over all symbols, newest first, from 2026-04-07:{axis, cohort, label_basis, data_from, series, has_more}pluslabel_computed, andleverageunderinclude=leverage.cohortandaxisare both required, andaxisissizeorpnlonly. Aseriesrow carriests,long_usdandshort_usdin USD,bias= (long - short) / (long + short), a fraction from -1 to +1 that isnullwhen both are 0, andposition_count, the number of open positions, not wallets. Each hour carries the cohort label it had then (label_basisispoint_in_time;pnllabels are daily before 2026-08-06, andlabel_computedsays so).hourssizes the window,limitcaps the rows andhas_moresays older rows exist: page back withendset to the oldesttsminus one second.include=leverageadds to every rowperp_bias,equity_exposureandequity_covered_share, the threesummaryratios of that hour, native perp account only; they arenullbefore 2026-08-11 and for a missing hour. An unknown cohort for the axis is an error.
axis is size, pnl or pnl_abs on summary and heatmap, and size or pnl on history; the
per-position tier ladder is refused there and is available on hl_cohort_metrics.
Which Hyperliquid cohorts are the most net short right now?
Show how every cohort on the pnl ladder is positioned in SOL.
Hyperliquid
Wallets, leaderboards, liquidations, market structure, builder codes, trader rankings and share-card lookup for Hyperliquid perps, one tool per family of routes.
Polymarket
10 tools — trending prediction markets, per-market deep dives, smart-money flows, trader profiles and a wallet leaderboard, plus the recorded L2 feed - event tape, order book, tape stats, on-chain settlement and the bulk archive index.