METHODOLOGY
Momentum Score
A single number, 0–100, that ranks how hard a symbol moved today and on how much volume. It is a description of today. It is not a forecast, and it is not alpha.
What has never been measured
This score has never been tested against forward returns. There is no out-of-sample study of it in this product — no backtest, no hit rate, no holding period, no benchmark comparison. Nothing on this page should be read as evidence that a high score precedes a gain, because no such evidence has been gathered.
That is also why it stopped being called “Alpha Score”. Alpha is return in excess of a benchmark, adjusted for risk. The formula below contains no benchmark, no risk adjustment and no forward return — so the old name described a measurement that was never taken.
What would have to change for a forecast claim: the score fixed in advance, run over held-out history it was never tuned on, with fees and adverse fills, and reported with the trial count that produced it — the same bar our Strategy Lab holds a backtest to. Until that exists, this is a sort order.
Inputs — exactly two
Nothing else enters the number. Not earnings, not fundamentals, not news, not the benchmark, not any longer-dated trend.
- dayChangePct — the symbol’s percent change on the day, from the same live quote the Price column shows.
- volumeVs10dAvgPct — today’s volume against its own trailing 10-day average, as a percentage above or below. Computed from our stored daily bars, not a vendor field.
Method — the whole of it
A fixed linear transform with a hard clamp. There is no model, no fitting, and no parameter that has ever been optimised against an outcome:
score = clamp(50 + dayChangePct × 2 + volumeVs10dAvgPct ÷ 10, 0, 100)In words: start at 50; every +1% on the day adds 2 points; every +10% of volume over the 10-day average adds one point; the result is rounded and clamped to 0–100. Price change therefore dominates, and volume can only nudge.
| Day | Change | Volume vs 10d | Score |
|---|---|---|---|
| Flat day, average volume | 0% | 0% | 50 |
| Up 3%, volume 50% above its 10-day average | +3% | +50% | 61 |
| Down 2%, volume 20% below its 10-day average | -2% | -20% | 44 |
| Up 12%, volume triple its 10-day average | +12% | +200% | 94 |
| Up 30%, volume double its 10-day average | +30% | +100% | 100 |
Those scores are computed by this page calling the scan’s own function, not copied from a spreadsheet. The last row is where the clamp bites: 50 + 30 × 2 + 100 ÷ 10 computes past 100 and is capped there. So the score saturates — above roughly +25% on the day it can no longer separate a strong move from an extreme one, and two very different tapes both read 100.
Cadence
Recomputed on every scan, over the universe the screener names above its own results — the default scan covers mega-caps and the crypto majors our feed streams, and the tiers differ in how many symbols a vendor answers for. A cached scan is served straight from Redis for 60s; past that a refresh runs off the request path while the previous scan is still served, stamped with its real age. A scan is kept at most 24h, so during a feed outage you see stale-but-real numbers with the age shown — never a fresh-looking guess.
It is not intraday-continuous, and it is not end-of-day settled. It is a snapshot of whenever the scan last ran, which the screener prints next to the results.
What it is not for
- · Not a ranking of quality, value, or business health — no fundamental enters it.
- · Not comparable across days; a 62 today and a 62 last week describe different tapes.
- · Not a position size, an entry, or a recommendation. See the screener for the boundary its filters actually enforce.
The formula, bounds, cache windows and universe size on this page are imported from the code that runs the scan. If one of them changes, this page changes with it.