Ranking Builder
Build your own composite ranking from the metric catalog.
The Builder (polyrank.app/rankings/builder, paid plans) lets you weight any combination of catalog metrics into a custom composite and rank the full wallet universe against it.

Drag a weight slider and the live preview re-ranks the 2.9M-wallet universe — the top-20 column updates as you compose.
Via API
curl -s -X POST https://api.polyrank.app/v1/rankings/custom \
-H "Authorization: Bearer pk_live_…" \
-H "Content-Type: application/json" \
-d '{
"weights": { "brier_score": 0.4, "alpha_vs_mid": 0.3, "sharpe": 0.3 },
"filters": { "min_trades": 100, "min_volume_usdc": 10000 },
"limit": 50
}'- Weights apply to percentile-normalized metric values; direction (higher/lower-is-better) is handled per the catalog.
- Filters cut the universe before ranking — sample-size floors keep
small-N noise out. Beyond the fixed gates,
metric_filtersputs an absolute min/max on ANY displayable metric's raw lifetime value ({"metric_filters": [{"metric": "copier_realized_return", "min": 0}]}, max 12; wallets where the metric isn't measured are excluded), andskill_gatesis the relative version (top-X% by percentile, max 8). - Sorting:
sort_byacceptscomposite(default), a raw stat (realized_pnl,roi_pct,win_rate_pct,lifetime_volume_usdc,trade_count,copier_realized_return), or any displayable metric viametric:<id>(raw lifetime value) /pctile:<id>(lifetime percentile, direction-corrected sodescis always best-first). Unmeasured values always sort last. na_policycontrols wallets missing a weighted metric:exclude(default — only fully-measured wallets qualify) orneutral_50(missing metrics score a neutral 50th percentile instead).- Full config schema: API Reference → Rankings.
Reading the breakdown (the measured marker)
Set include_breakdown: true and each ranking row carries a breakdown object —
the per-metric percentile that fed the composite. Two response fields work
together:
| Field | Meaning |
|---|---|
breakdown | { metricId → percentile }. A cell is null when the metric was not measured for that wallet (below the metric's minimum sample size, or no activity in the requested window). |
breakdown_measured | { metricId → boolean }. false mirrors a null cell — the metric is unmeasured. Present only when include_breakdown is set. |
A null cell is not a zero
A windowed percentile join-miss (a wallet with no row in the 30-day table)
serializes to null over the wire — not a real 0 or P50. Reading it as a
measured 0 silently corrupts a re-derived composite. Always branch on
breakdown_measured[id]:
false→ render—(unmeasured). Underna_policy: neutral_50the composite scored it as a neutral P50; underexcludethe wallet was dropped if this metric was weighted.true→ the percentile inbreakdown[id]is a real measured value (even if it happens to be0).
Recipes to start from
| Goal | Weights sketch |
|---|---|
| Pure forecaster | brier 0.5 · calibration ECE 0.3 · IC 0.2 |
| Copyable sharp | alpha-vs-mid 0.4 · brier 0.3 · late-entry return 0.3 |
| Steady compounder | Sharpe 0.4 · max drawdown 0.3 · profit factor 0.3 |