Every number on this site comes from one of two calculations, and both are written out below. There are no proprietary models, no machine learning, and no human judgement applied per token. Given the same public CoinGecko data you can reproduce every figure exactly.
To compare a pair over a window, the site computes the cross-rate on each day and then averages those daily rates:
average = mean( price_A(day i) / price_B(day i) )
It does not divide the average of A by the average of B:
average ≠ mean(price_A) / mean(price_B)
Those two give different answers. Division is a convex function, so by Jensen's inequality the ratio-of-averages is systematically biased relative to the average-of-ratios, and the size of the bias grows with volatility — which is exactly the condition DePIN tokens live in. The dashed average line on the chart uses the same computation as the number in the text, so the two always agree.
The percentile answers one question: on what share of the last 90 days was this cross-rate lower than it is right now?
percentile = round( 100 × count(rate_i < rate_now) / n )
The comparison is strictly less-than, so days exactly equal to today's rate are not counted. The result is an integer from 0 to 100.
This makes no assumption about the shape of the distribution. There is no mean, no standard deviation, and no bell curve involved, because DePIN cross-rates are not normally distributed and treating them as if they were would produce confident, wrong numbers.
If a pair has fewer than 30 aligned daily observations in the window, the site publishes no percentile, no median, and no quartiles for it. It prints the observation count instead.
This is a deliberate refusal rather than a gap. A percentile computed on nine days of history is arithmetically valid and practically meaningless, and a reader has no way to tell the difference from the number alone. Newly listed tokens and recently added pairs hit this case.
The median and the 25th and 75th percentiles are computed from the sorted series of daily cross-rates:
idx = q × (n − 1)
if idx is a whole number: value = sorted[idx]
otherwise: value = sorted[floor(idx)]
+ (sorted[ceil(idx)] − sorted[floor(idx)])
× (idx − floor(idx))
with q of 0.25, 0.50 and 0.75. This is the same definition as NumPy's default linear method and Excel's PERCENTILE.INC, so the figures can be reproduced in either without adjustment.
Each token gets one sentence, in this exact form:
{FROM}/{TO} sits in the {N}th percentile of the last {days} days — {band}.
The band is chosen from the percentile by fixed cutoffs. These are the complete rules — there are no others:
| Percentile | Band |
|---|---|
| 0 – 10 | near recent lows |
| 11 – 25 | below the typical range |
| 26 – 74 | in the middle of its recent range |
| 75 – 89 | above the typical range |
| 90 – 100 | near recent highs |
The narrative is produced by a fixed string template in the codebase. No language model is involved, no text is generated per token, and no sentence is edited by hand. The same percentile always produces the same sentence, and the sentence is always past-tense and descriptive — it states where the rate sits, never what to do about it.
usd-coin) for the DePIN snapshot.
Every DePIN page carries the snapshot time in a machine-readable <time> element. That timestamp is authoritative — if it is old, the numbers are old.
The calculation is descriptive and backward-looking. It states where today's rate sits relative to a recent window, and that is the entire claim.
It does not forecast. A rate near the bottom of its 90-day range can go lower, and a rate near the top can go higher; the percentile carries no information about which. It is not a recommendation to act, and nothing on this site tells you to convert, hold, or wait. Should I Swap does not execute trades, custody assets, or take a position in any token it displays.
Published under the publishers' exemption to the Investment Advisers Act of 1940 (15 U.S.C. §80b-2(a)(11)(D)).
The current snapshot is available as JSON and is explicitly allowed in robots.txt:
current_rate, percentile_90d, median_90d, p25_90d, p75_90d, sample_size, narrative. Top level: vs, vs_symbol, generated_at, ready, stale.
Where a figure is unavailable, the field is null rather than a substituted value.
DePIN token hub · Furthest from their 90-day median · Editorial policy · The average-of-ratios problem, explained at length · FAQ