Funding & Positioning
How the funding rate percentile, streak counter, and term-structure widgets are computed: sources, formulas, edge cases, limits.
See the live widgets at /perpetuals/funding.
Data sources
MarketTrace funding analytics combine three inputs: Binance's public funding-rate history, the per-asset snapshot service, and the tracked-asset roster.
- Historical funding rates. Binance USDT-margined perpetuals, public funding-rate endpoint. Pulled per asset on an 8-hour cycle, paginated 1000 rows at a time. Local ingest keeps ~2 years of rolling history per asset (≈ 2,190 cycles per asset × 6 assets ≈ 13k rows total).
- Current funding rate. Read from the per-asset snapshot, refreshed every ~5 minutes. The widget surfaces the value as percent (the raw API field is a fraction; we multiply by 100 at the boundary).
- Hyperliquid perpetuals. Public funding endpoint, hourly settlement (24 cycles/day, against the 8-hour cycles on the CEX feeds). Local ingest holds the same 2-year rolling window at 3× density: around 17,500 rows per asset.
- Tracked assets.BTC, ETH, SOL, BNB, XRP, DOGE, read across Binance, Bybit, OKX and Hyperliquid. Each venue's percentile is ranked against that venue's own history, so cross-exchange basis stress shows up directly in the table.
Percentile rank: how it's computed
A funding rate percentile of N means N% of 8-hour cycles in the last two years printed at or below the current rate. We split ties evenly so identical observations rank between strict-less-than and less-or-equal counts.
Concretely, given a sorted list of historical percent values S:
left = count of elements in S strictly less than current right = count of elements in S less than or equal to current rank = (left + right) / 2 percentile = (rank / |S|) × 100
The result is bounded [0, 100]. A 0th percentile means the current rate is the most negative reading in the window; 100th means it is the most positive.
Percentile rank: edge cases
- Insufficient history. When the on-disk window spans fewer than
90 days, the API returnspartial: trueand a null percentile. The FE renders an “insufficient history” cell rather than a misleading number from a thin sample. - Missing current rate.When the snapshot has no funding-rate field (cold start, daemon down), the percentile is null and the FE shows —.
- Sample size disclosure. The actual number of contributing cycles is shown alongside every percentile so the reader can judge how robust the rank is.
Streak: how it's computed
A funding streak is the run of consecutive 8-hour cycles that share the same sign as the latest cycle. Streak length, in days, is the elapsed time between the first cycle in the run and the latest cycle. A neutral cycle (rate exactly 0) ends any streak.
direction = sign(latest.rate) // "neg" | "pos" | "neutral" walk back through history while sign matches streak.days = (latest.ts - first_in_streak.ts) / 86_400_000
Direction labels: "neg" (shorts pay longs), "pos" (longs pay shorts), "neutral" (latest cycle is zero or no history).
Streak: rarity flag
The rare flag fires when the current streak length is in the top 10% of historical same-direction streak lengths for that asset. We also require at least 10 prior completed streaks before publishing a rarity claim. Without that floor the threshold can come from a tiny sample and overfire.
Term structure
Funding term structure is a table that shows the current funding rate, 2-year percentile, and active streak length for all six tracked perpetual pairs at once. The endpoint returns one row per asset; embeds can override the asset list via ?assets=btc&assets=eth.
Distribution histogram
The funding rate distribution histogram is a 30-bucket frequency chart of every 8-hour cycle in the asset’s 2-year history. Bin width is dynamic per asset across the observed [min, max] range; a fixed [-0.1 %, +0.1 %] would clip DOGE/SOL outlier tails and waste resolution on the BTC body. Each bin reports the timestamp of the most recent cycle that fell in it, so the tooltip can show “last seen YYYY-MM-DD”.
Caching
- Percentile. 1-hour cache. The 2-year rank shifts negligibly within an hour.
- Streak. 1-minute cache. Streak length ticks every 8 h cycle but the FE may want a tighter heartbeat for nearby flips.
- Term structure. 1-minute cache, matching the streak component (its freshest dependency).
- Distribution. 24-hour cache. One new cycle per day adds ~1 row to a 2k-row histogram; shape barely shifts.
Limitations
- Per-venue history depth varies.Binance and Bybit go back ~2 years; OKX's public funding endpoint exposes only ~3 months, so its percentile reads
partialuntil enough cron-driven history accumulates locally. - 8-hour granularity. Funding settles at 00:00 / 08:00 / 16:00 UTC. Intra-cycle direction shifts (rare) are invisible to this widget.
- Account composition is opaque. Funding rate is a market-clearing price between long and short open interest; it does not decompose into who is positioned where.
- History depth is rolling 2 years. Comparisons to older regimes (e.g. 2020 spikes) are not represented in the percentile.
Versioning
Methodology version v1.2.0 · updated 2026-05-21. Material changes (new sources, formula tweaks, threshold changes) bump the version and update dateModified in the structured data above.
v1.2.0 (2026-05-21): added Hyperliquid to the data-sources list (hourly settlement, 24 cycles/day) and removed the L/S ratio section. The L/S widget runs live on /perpetuals/positioning, so its methodology now sits on the market-positioning page instead.