The Heat score, term by term
Heat is a bounded score from 0 to 100 that ranks a meme coin by how much is happening in it right now, measured against its own size rather than against the rest of the market. It is computed on the server by a single function, and this page documents every term in it.
The question Heat answers
A market cap column ranks the largest coins. A 24 hour volume column ranks the largest coins again, because volume scales with size: the biggest pool on the board will out-trade a small one on a quiet day without anything happening in it at all.
Heat asks a different question. Where is money moving relative to the size of the thing it is moving in, is it moving harder in the last hour than it was earlier, are buyers or sellers doing the moving, and is the pool deep enough for any of it to be real.
Every term is bounded. That is the design constraint the whole score is built around: no single input can run away with the ranking. A coin up four thousand percent cannot bury a coin up sixty percent on price alone, and a very large pool cannot buy rank with volume it barely turns over.
Shape of the score
Five weighted components produce an activity score between 0 and 1. That score is then multiplied by a direction gate and by any penalties that apply, clamped, and reported on a 0 to 100 scale with one decimal.
activity = SUM( weight[i] * part[i] ) for the five parts below
score = activity * direction * PRODUCT(penalties)
reported = round( clamp(score, 0, 1) * 100, 1 )
The weights sum to exactly one, so the activity term is itself bounded to the 0 to 1 range before anything is applied to it.
| Component | Weight | What it answers |
|---|---|---|
| Turnover | 0.30 | Volume relative to the coin's own size |
| Momentum | 0.22 | Where the price has actually gone, damped |
| Acceleration | 0.20 | Is the last hour hotter than the last six |
| Buy pressure | 0.14 | Which side is doing the trading |
| Freshness | 0.14 | How young the pool is |
The two bounding functions
Both functions exist to turn an unbounded quantity into a bounded one without a hard cutoff. Each takes a knee parameter, the value at which the output reaches one half. Below the knee the function is close to linear; above it, it saturates.
soft(v, mid) = v / (v + mid) for v > 0, else 0
signed(pct, mid) = sign(pct) * soft(|pct|, mid)
The choice of knee is where the judgement lives, and it is the only place a value is asserted rather than measured. Each one is stated below with the reasoning.
Turnover, weight 0.30
The core signal. Volume in the last 24 hours divided by the size of the coin, so a small pool trading its whole float scores above a large pool trading a sliver of it.
size = max( 1, min( marketCap, liquidity * 40 ) )
turnover = soft( volume24h / size, 0.35 )
The denominator takes the smaller of the reported market cap and forty times the pool liquidity. That guard matters: a token can report almost any market cap it likes by minting supply nobody holds, and dividing by that inflated number would make a busy coin look calm. Capping the denominator at forty times the real pool stops a fictional market cap from hiding activity, and stops a thin pool from looking busier than it is.
A knee of 0.35 means a coin turning over thirty five percent of its size in a day scores half marks on this term. Market cap falls back to fully diluted valuation when it is missing.
Acceleration, weight 0.20
This is what separates a coin that is moving now from a coin that moved this morning. It compares the last hour against the six hour run rate, and adds a short term term for the last five minutes.
accel = max(0, h1 - h6/6) + max(0, m5 * 3)
acceleration = soft( accel, 12 )
Both terms are floored at zero, so a cooling coin simply scores nothing here rather than going negative and fighting the other components. Dividing the six hour change by six converts it to an hourly rate so the comparison is like for like. The knee of 12 means a coin running roughly twelve percentage points per hour above its own recent pace scores half marks.
Momentum, weight 0.22
Where the price has actually gone, over two horizons, damped hard so an old parabola fades instead of holding the top of the board for a day.
raw = 0.65 * signed(change24h, 45) + 0.35 * signed(change6h, 20)
momentum = clamp(raw, -1, 1) * 0.5 + 0.5
The knees say a 45 percent day and a 20 percent six hours are each worth half marks on their horizon. The final line remaps the signed result onto 0 to 1, so a flat coin sits at 0.5 rather than at zero, and a falling coin scores below the midpoint instead of being excluded.
Buy pressure, weight 0.14
Which side is doing the trading, weighted by how much evidence there is. A nine to one buy ratio across eleven trades means very little; the same ratio across two thousand trades means a great deal.
ratio = buys / (buys + sells) 0.5 when there are no trades
confidence = soft( buys + sells, 150 )
buyPressure = 0.5 + (ratio - 0.5) * confidence * 2
The confidence factor is the important part. With few trades the term collapses toward a neutral 0.5 no matter how lopsided the ratio looks, so a handful of trades cannot manufacture a signal. At 150 trades the ratio is credited at half its strength, and it approaches full strength from there.
Freshness, weight 0.14
Exponential decay on the age of the pool, with a time constant of 96 hours.
freshness = exp( -ageHours / 96 ) 0.25 when the age is unknown
That gives close to full marks on the first day, about 0.47 at three days, about 0.13 at a week, and about 0.03 after two weeks. This is the most opinionated term in the score and it is included for one reason: meme moves overwhelmingly start in young pools. A token whose age we cannot establish is given a flat 0.25 rather than a zero or a full score, so a missing timestamp neither rewards nor destroys it.
The direction gate
Activity alone is not heat, and this is the correction that matters most in practice. A coin collapsing seventy percent prints enormous volume, accelerates hard and shows a huge trade count while everybody leaves. On activity terms alone it tops the board. That is a ranking nobody wants to read.
direction = clamp( 0.55 + 0.45 * signed(change24h, 45)
+ 0.25 * max(0, signed(change1h, 8)),
0.12, 1.15 )
The activity score is multiplied by this gate. A coin down 70 percent over the day, with no recovery in the last hour, retains about 28 percent of its activity score. A coin that fell but is bouncing in the last hour keeps meaningfully more, because a bounce off a flush is genuinely interesting. A riser is left alone or lifted by at most fifteen percent.
The floor of 0.12 rather than zero is deliberate. A violent collapse should be pushed down the board, not erased from it: it is still information, and hiding it would make the ranking less honest, not safer.
Penalties
The gate handles direction. Penalties handle a different class of problem: conditions that make a high score meaningless rather than merely too high. Each is a multiplier, so they compound.
| Condition | Multiplier | Why |
|---|---|---|
| liquidity < $15,000 | liquidity / 15,000, floored at 0.15 | Below this depth the inputs above are mostly noise |
| liquidity = 0 | 0.15 | Nothing to trade against |
| marketCap / liquidity > 5,000 | 0.35 | A valuation far beyond the pool backing it |
| trades < 10 | 0.4 | Almost nobody is trading it, whatever the chart says |
| price is stale | 0.5 | A price we no longer trust should not lead a live ranking |
What the distribution actually looks like
The figures below are a frozen capture, not a live query, so they stay checkable against the same file this page was written from. Download it and recompute them.
/data/heat-snapshot.json captured 2026-09-09
| Measure | Value |
|---|---|
| Tokens scored | 336 |
| Highest score | 59.7 |
| 90th percentile | 23.1 |
| Median | 11.4 |
| 10th percentile | 7.6 |
| Lowest score | 0.2 |
| At or above the hot mark of 45 | 5 |
The shape is the point. The median sits near 11 and only a handful of coins clear 45 on any given capture. A score in the forties is genuinely unusual, and the interface marks a coin hot at 45 for that reason. A score of 90 is not something the function is built to produce: every term would have to be near its ceiling at once, with a rising price and no penalty.
A worked decomposition
The same capture, top of the board, with each term shown as it entered the weighted sum. These are produced by the scoring function itself rather than a reimplementation, so this table cannot drift from the code it documents.
| Token | Heat | Turn | Accel | Mom | Buy | Fresh | Dir |
|---|---|---|---|---|---|---|---|
| DUO | 59.7 | 0.95 | 0.11 | 0.88 | 0.45 | 0.57 | 0.93 |
| USEFUL | 58.8 | 0.74 | 0.76 | 0.73 | 0.57 | 0.35 | 0.89 |
| PURR | 57.2 | 0.63 | 0.76 | 0.87 | 0.66 | 0.01 | 0.91 |
| Stonks | 46.8 | 0.84 | 0.41 | 0.61 | 0.59 | 0.26 | 0.8 |
| PURPS | 45.6 | 0.93 | 0 | 0.64 | 0.56 | 0.01 | 0.91 |
| BTC | 44.7 | 0.56 | 0 | 0.92 | 0.69 | 0.09 | 0.93 |
Read across a row and the ranking explains itself. A coin can lead on turnover while scoring nothing on acceleration, which says the money is there but the move is not speeding up. Another can carry the board on freshness and buy pressure with modest turnover, which is a different kind of interesting.
What Heat is not
Heat measures activity. It is not a safety rating. A coin can be extremely hot and be a trap, and the score deliberately does not pretend otherwise: the penalties reduce scores that are meaningless, not scores that are dangerous.
It is not a prediction. Nothing in the function looks forward, and no term is fitted to future returns. It is a summary of the recent past, bounded so that no single input dominates.
It is not investment advice. Meme coins are high risk and most lose value. Use the safety checks and the token page, not a single number, before you act.
Reproducing it
There is one definition and it runs on the server, so the same score appears in the table, the sort order and the API. The client never recomputes it.
| Where | What |
|---|---|
scripts/token-heat.mjs | The scoring function and the weights |
test/token-heat.test.mjs | Behaviour tests pinning these numbers |
GET /api/tokens | Returns heat and heatRank on every row |
/data/heat-snapshot.json | The frozen capture this page cites |
One caveat worth stating plainly. The hub pages that list tokens by chain use a simpler build time ordering, 24 hour volume weighted by 24 hour trend, described on those pages in exactly those words. That ordering is not the Heat column and does not share its bounds.
Common questions
- Is a high Heat score a signal to buy?
- No. Heat measures how much activity a coin has relative to its size, over the recent past. It contains no forward looking term and is not fitted to future returns. A collapsing coin can still show real activity, which is why the direction gate exists and why the score is not a safety rating.
- Why is the score capped at 100 when volume is not?
- Every component passes through a bounding function that saturates, so no input can run away with the ranking. Without that, one coin up several thousand percent, or one very large pool, would dominate the board on a single term and the other four would stop mattering.
- Why does a young pool score higher than an old one?
- Freshness carries a weight of 0.14 and decays exponentially with a 96 hour time constant, because meme moves overwhelmingly start in young pools. It is the most opinionated term in the score. It cannot carry a coin on its own: at full marks it contributes 14 points before the direction gate and any penalties.
- What happens to a coin with almost no liquidity?
- Below 15,000 dollars of liquidity the score is multiplied by liquidity divided by 15,000, floored at 0.15. With no liquidity at all the multiplier is 0.15 flat. The inputs are still computed, they are simply not trusted to lead a ranking.
- Does the Heat column match the order on the chain hub pages?
- No. The chain hubs use a simpler build time ordering, 24 hour volume weighted by 24 hour trend, and say so on the page. The Heat column is the bounded 0 to 100 score documented here.
Keep reading
Nothing here is financial advice. Meme coins are high risk and most lose value. Read the full risk disclosure before trading.