Methodology
Sentiment Classification
Every piece of content is analyzed by our AI pipeline using large language models to extract directional sentiment and relevant assets.
The model evaluates context, considers hedging language, and distinguishes between strong conviction calls and nuanced observations. Each classification includes asset extraction (BTC, ETH, SOL, etc.) for granular analysis.
Consensus Index
The Consensus Index uses a one-analyst-one-vote system. Each analyst's vote is their current stance: the recency-weighted average of their directional posts on the asset over the last 30 days, weighted by their accuracy score. Analysts whose past calls proved right carry more influence.
Sell-side ratings on equities vote like posts: a Buy-type rating (Buy, Outperform, Overweight…) is a bullish call and a Sell-type rating (Sell, Underperform, Underweight…) a bearish call. Neutral ratings (Hold, Neutral, Market Perform, Equal-weight…) are not calls: they take no side on price, so they neither count toward an analyst's calls nor vote in the index. They only end the analyst's earlier call.
A price-target change with no rating word votes by the target's distance from the stock's last close (the last close on or before the event day, at most 7 days back): a target at least 10% above that close is a bullish call, at least 10% below it a bearish call, and anything inside that band is neutral. Without a close in that window, or when the target is more than 4× or less than ¼ of the close, the event casts no vote.
The strength of a rating is the call's conviction. A Strong Buy or Strong Sell, a Strong initiation, or an upgrade / downgrade of two or more notches (Sell → Buy, Hold → Strong Buy) weighs more than a plain Buy or Sell, up to twice a regular call. Posts and crypto calls carry no rating and keep weight 1, so this only sharpens the equity indexes.
The chart plots a moving average of the daily index. Its window is the selected period (7D = 7 days, 1M = 30, 3M = 90, 6M = 180, 1Y = 365; YTD and ALL use the days in that span); the API and the default reading use 30 days. Chart colors use a 90-day rolling Z-score of that average to highlight unusually bullish or bearish periods relative to recent history:
- Green = Above-average bullish sentiment
- Red = Above-average bearish sentiment
The site's views are DEFINED by the MA window: Weekly (7D) = 7-day MA, Monthly (1M, the default) = 30-day MA, Quarterly / Yearly = 90 / 365-day MA — always with the 90-day z window. The 30-day (consensus_index_30d_ma / z_score / bullish_percent) and the 7-day (consensus_index_7d_ma / z_score_7d / bullish_percent_7d) series are published per row; any other window follows from consensus_index with the same recipe (python_example takes the window as a parameter). The current UTC day is never in the API; the site may already show it.
Python example (standard library): the same code the API's method.python_example carries
# Reproduce the Analyst Consensus Index chart from GET /api/v1/consensus?asset=BTC&days=N
# (fetch N = your range + 120: the first 30 + 90 days are the MA / z context). Standard library only.
import json, math, urllib.request
from datetime import date
def r2(v):
return math.floor(v * 100 + 0.5) / 100 # JavaScript's Math.round(v * 100) / 100 (half rounds up, not to even)
SD_FLOOR = 0 # the published z has NO sigma floor: it divides by the population sd itself. (The site's /screener ranks its
# Relative sort by max(sd, 10) = 5 bullish-share points on the -100..100 scale — a ranking rule of that page, not the API's z.)
def reproduce(rows, ma_days=30, z_days=90, sd_floor=SD_FLOOR):
"""rows = payload["data"] (ascending). Returns {date: (ma, z, plotted)}; None where the chart has no reading."""
rows = sorted(rows, key=lambda r: r["date"])
day = [date.fromisoformat(r["date"]).toordinal() for r in rows]
ma = []
for i, r in enumerate(rows): # MA over the CALENDAR window (d - ma_days, d], valued days only
win = [rows[j] for j in range(i + 1) if day[j] > day[i] - ma_days]
vals = [x["consensus_index"] for x in win if x["consensus_index"] is not None]
calls = sum(x["total_analysts"] or 0 for x in win)
if vals and calls > 0:
s = 0.0 # add LEFT TO RIGHT like the chart's JavaScript: Python 3.12+'s
for v in vals: # sum() compensates float rounding and can land a .xx5 tie on the
s += v # other side of r2 (21.195 -> 21.19 instead of the chart's 21.2)
ma.append(s / len(vals))
else:
ma.append(None)
out = {}
for i, r in enumerate(rows):
if ma[i] is None:
out[r["date"]] = (None, None, None) # no_data: the chart draws a black stretch here
continue
win = [ma[j] for j in range(i + 1) if day[j] > day[i] - z_days and ma[j] is not None]
if len(win) < 2:
z = 0.0
else:
mean = 0.0
for v in win: # left to right again (no sum()), see the MA loop above
mean += v
mean /= len(win)
var = 0.0
for v in win:
var += (v - mean) ** 2
sd = math.sqrt(var / len(win)) # POPULATION sd (divide by n)
sd = max(sd, sd_floor) # sd_floor = 0 for the API's z (no floor)
z = (ma[i] - mean) / sd if sd > 0 else 0.0 # zero variance (and no floor) reads 0
ma2 = r2(ma[i])
plotted = max(0, min(100, math.floor((ma2 + 100) / 2 + 0.5)))
out[r["date"]] = (ma2, r2(z), plotted)
return out
if __name__ == "__main__":
req = urllib.request.Request("https://consensus.cryptoquant.com/api/v1/consensus?asset=BTC&days=485",
headers={"Authorization": "Bearer <your CryptoQuant API key>"})
payload = json.load(urllib.request.urlopen(req))
monthly = reproduce(payload["data"], ma_days=30) # == consensus_index_30d_ma, z_score, bullish_percent
weekly = reproduce(payload["data"], ma_days=7) # == consensus_index_7d_ma, z_score_7d, bullish_percent_7d
for r in payload["data"][-5:]:
print(r["date"], monthly[r["date"]], (r["consensus_index_30d_ma"], r["z_score"], r["bullish_percent"]))
Accuracy Score
We evaluate analysts with a phase-based scoring system. Each asset's price history is divided into bull and bear phases (section 04), and each analyst's daily stance on that asset is scored against those phases.
- At least 50 days of sentiment data
- Participation in at least 2 bull AND 2 bear phases
- Active posting history (not inactive for 6+ months)
- At least 1 year of history from first to last data
- Both long and short phase participation for Long/Short-term categories
- At least 10 directional calls on the asset to be ranked on it
Being right in the few periods an analyst covered is not enough. The score weighs every market phase by how much of it the analyst actually covered, and silence is never turned into agreement.
Show the formula
In force for every asset’s ranking since 2026-10-09; the sell-side rule since 2026-10-12. Scores below 50 move toward 50 the same way.
Note: History depth varies by analyst. X returns at most the 3,200 most recent posts per account, and deeper history is backfilled selectively, so an analyst's record may not cover their full posting history. Scores are computed on the days we hold.
Market Phases
Analyst accuracy is evaluated against market phases detected per asset from its daily price history with a swing-based rule, so the ground truth is objective and the same for every analyst on that asset.
The rule reads each asset's daily closes and dates its turning points:
- A regime flips when the close moves beyond a strong threshold from its running peak or trough; the threshold scales with the asset's own volatility within a floor and a cap, and the new regime is back-dated to that extreme
- Smaller counter-moves past a lower threshold are swings inside the regime: a dip in a bull market is a bear trap, a rally in a bear market a bull trap
- The open tail is provisional and re-judged every day; confirmed phases are frozen and snapshotted monthly
- An asset needs at least two bull and two bear phases, and a price history of at least a year, to be scored
Each swing is labelled by the regime it sits in and its own direction:
View Phase Details
| Start | End | Days | Label |
|---|---|---|---|
| 2019-02-07 | 2019-06-25 | 139 | BULL |
| 2019-06-26 | 2019-07-15 | 20 | BEAR |
| 2019-07-16 | 2019-08-07 | 23 | BULL TRAP |
| 2019-08-08 | 2019-10-23 | 77 | BEAR |
| 2019-10-24 | 2019-10-26 | 3 | BULL TRAP |
| 2019-10-27 | 2019-12-16 | 51 | BEAR |
| 2019-12-17 | 2020-02-13 | 59 | BULL |
| 2020-02-14 | 2020-03-11 | 27 | BEAR |
| 2020-03-12 | 2021-01-07 | 302 | BULL |
| 2021-01-08 | 2021-01-26 | 19 | BEAR TRAP |
| 2021-01-27 | 2021-02-20 | 25 | BULL |
| 2021-02-21 | 2021-02-27 | 7 | BEAR TRAP |
| 2021-02-28 | 2021-04-12 | 44 | BULL |
| 2021-04-13 | 2021-07-19 | 98 | BEAR |
| 2021-07-20 | 2021-09-05 | 48 | BULL |
| 2021-09-06 | 2021-09-20 | 15 | BEAR TRAP |
| 2021-09-21 | 2021-11-07 | 48 | BULL |
| 2021-11-08 | 2022-01-21 | 75 | BEAR |
| 2022-01-22 | 2022-03-28 | 66 | BULL TRAP |
| 2022-03-29 | 2022-06-17 | 81 | BEAR |
| 2022-06-18 | 2022-08-12 | 56 | BULL TRAP |
| 2022-08-13 | 2022-11-20 | 100 | BEAR |
| 2022-11-21 | 2023-07-12 | 234 | BULL |
| 2023-07-13 | 2023-09-10 | 60 | BEAR TRAP |
| 2023-09-11 | 2024-03-12 | 184 | BULL |
| 2024-03-13 | 2024-09-05 | 177 | BEAR TRAP |
| 2024-09-06 | 2025-01-20 | 137 | BULL |
| 2025-01-21 | 2025-04-07 | 77 | BEAR |
| 2025-04-08 | 2025-10-05 | 181 | BULL |
| 2025-10-06 | 2026-02-04 | 122 | BEAR |
| 2026-02-05 | 2026-05-09 | 94 | BULL TRAP |
| 2026-05-10 | 2026-06-29 | 51 | BEAR |
| 2026-06-30 | 2026-11-10 | 134 | BULL · provisional |
Analyst Bias
Current Bias is the analyst's current stance on the asset: the same 30-day recency-weighted average of their directional posts that feeds the index, shown on a 0 to 100 scale.
The bias score ranges from 0 (perma-bear) to 100 (perma-bull); 45 to 55 reads Neutral. Nuanced calls sit a quarter of the way from the midpoint. Analysts with no directional post on the asset in the last 30 days show no bias ('No clear view').
How analysts are selected
Only analysts who publish directional calls on a tracked asset in public enter the roster. Candidates are found on X, Seeking Alpha and Substack and judged against the same questions on every platform (reach, activity, coverage of a tracked asset, and whether the posts contain explicit calls), with screening thresholds set per platform. A reviewer reads every candidate before anything is loaded; a keyword or model screen only ranks the queue and never adds an analyst by itself. The grades order the acquisition of independent, asset-attributed directional signals for the index; they are not a verified measure of forecasting accuracy, which is scored separately in the track record below.
| Criterion | X | Seeking Alpha | Substack |
|---|---|---|---|
| Reach | Screening bar. S: ≥ 50,000 followers. A has no follower bar; the candidate pool starts at 300 followers. Reach alone does not make an S. | Screening bar. S: ≥ 20K Seeking Alpha followers. A: ≥ 5K followers (or ≥ 20K with a lower cadence). Not comparable with Substack subscribers; reach alone does not make an S. | Screening bar. S: ≥ 20K free subscribers. A: ≥ 5K subscribers (or ≥ 20K with ≥ 2 asset posts). Not comparable with Seeking Alpha followers; reach alone does not make an S. |
| Activity | A post within the last 180 days and ≥ 3 original (non-retweet) posts about the sector in the last 90 days. Protected accounts and accounts silent for 180 days are dropped. | Screening cadence. S: ≥ 4 analysis articles per 30 days. A: ≥ 2 per 30 days (≥ 1 per 30 days with ≥ 20K followers). Dormant for more than 90 days = C. The grade itself reads directional calls over 30 / 90 days, not article counts. | Screening cadence. S: ≥ 4 posts per 90 days. A: ≥ 3 per 90 days. Dormant for more than 90 days = C. The grade itself reads directional calls over 30 / 90 days, not post counts. |
| Coverage | Posts about a tracked sector. An asset is attached only on a direct cashtag or name mention of a registered asset. | Articles whose text makes a claim about a tracked asset (crypto symbols, registry US equities or commodity symbols). A miner, royalty or energy stock is not the commodity it produces. | Screening share. S: ≥ 40 % of the latest 20 posts name a tracked asset class. A: ≥ 25 %. Only posts whose text makes a claim about a tracked asset count as coverage. |
| Explicit calls | Original analysis posts in the sector; the direction of each post is labelled by the classifier after collection. Promotional or signal-selling profiles are dropped. | Only calls proven in the article's own title or summary count; a ratings site does not make every article a rating with a target. A reviewer confirms the calls. | Directional calls confirmed by reading the free body or the public title, subtitle and preview (buy / sell / target / long / short / bullish / bearish). A question-form title or a company revenue outlook is not a call. English only. |
| Verification | A reviewer reads the profile and posts, and only the review file authorises loading. Press check: dated citations at Bloomberg, CNBC, Reuters, WSJ, FT, Barron's, NYT or The Economist in the last 24 months. S needs at least 5 of them on top of the follower bar. A Grok cross-check per sector flags accounts that are not genuine analysts for the reviewer; it is never applied automatically. | Author feed (20 latest articles) for cadence and symbols, profile page for followers, titles read by hand. Firm, feed, news-desk, data-vendor and issuer accounts and sell-side employees are excluded from this roster by rule. | Public archive (latest 20 posts) and the About page for subscribers, titles read by hand. News digests, project / exchange / VC / issuer newsletters and duplicate hosts are excluded; a team newsletter is attributed per byline. |
- Reach is a secondary signal. Seeking Alpha followers and Substack subscribers are not the same scale, and reach alone never makes an S; a small account with clear calls on a thinly covered asset is assessed as an exception.
- Activity is counted in directional calls, not posts: one call = one author × one tracked asset × one publication date × one direction, counted over the last 30 and 90 days (D30 / D90). Neutral pieces, retrospectives, announcements and educational posts do not count.
- Coverage means a claim in the text about an asset we actually track. A bullish view on a gold miner is not a bullish call on gold; a sector word or a feed's symbol list is not coverage.
- A call needs, at minimum, the asset, the author's own direction and when it was made. A buy / sell wording, a price target, a horizon or an invalidation level add weight but are not required.
- Clarity and performance are kept apart. Self-reported returns, third-party reputation and follower counts are never read as forecasting skill; performance is verified only on calls stored in advance, out of sample, in the track record.
- Duplicates are resolved person first: canonical person → platform account → publication or byline → article and asset. The same person on another platform is a source linked to the existing analyst, not a new analyst.
- Paywalls: what counts is the share of posts whose direction can be read from the public title, subtitle or preview. A paid share is not penalised across the board, and a free label is not read as full-text access.
- Conflicts of interest: executives of an asset's issuer or of an exchange are excluded; fund managers and former executives are not excluded automatically. Views are attributed per byline, never to a team, a newsletter brand or a quoted news item.
- S (core roster): meets every A criterion plus the reach bar (and, on X, the press bar). A collection priority, not a performance rating.
- A (roster): loaded, collected and tracked.
- B (candidate): kept in the appendix, not loaded.
- C (excluded): already registered, dormant, no call signal, or ineligible by rule.
- Activity: an analyst counts as active only with an original post inside the last three calendar months; the others sort below active analysts in lists. An X account with no post in 180 days is not onboarded.
- One person, one analyst: a Seeking Alpha or Substack account is attached to an existing analyst only after a verified profile cross-link; an unverified match stays a candidate and is never collected.
- Duplicates: every candidate is checked against every stored handle, X id and alias, hidden rows included, person first: canonical person, then platform account, then publication or byline, then article. A firm account that duplicates a held person's personal account is not added.
- Ineligible accounts: news feeds, bots, relay and company accounts, and direct stakeholders (executives, founders, board members or foundation / treasury-strategy staff of a tracked asset's issuer, project, holding or treasury company, and exchange or issuer CEOs) carry an ineligibility flag. Fund managers and former executives are not flagged automatically. Flagged rows stay in the database but are excluded from every index, list, digest and badge. A stake in a single asset removes only that asset's votes, not the analyst.
- Index exclusion: hidden crypto-pool accounts carry an exclude-from-index flag and count in no aggregate; company research accounts and news aggregator handles are never listed.
The selection criteria are re-examined every quarter; the thresholds above are the ones in force as of October 2026, and the reading rules were last revised after the independent review of the October 2026 scout round.
Analyst track record — how a citation line is made
Each analyst page opens with one plain sentence — “CryptoQuant has tracked N directional calls by @handle on BTC since Jun 2021: ranked in the Top 5% of M scored analysts by accuracy (as of …)” — and a machine-readable copy of the same numbers (schema.org Person → subjectOf Dataset, and /api/v1/analysts/<handle>). This section says what each part means.
What counts as a call
A call is a public post by a tracked analyst that our classifier labels with a direction for an asset — BULLISH, BULLISH_NUANCE, BEARISH_NUANCE or BEARISH (NEUTRAL posts are collected but are not calls). “Directional calls” in the sentence is the count of bullish plus bearish posts; the API’s call_count is all-time count of the analyst's directional (bullish or bearish) posts on tracked assets.
How a call is judged and scored
We evaluate analysts with a phase-based scoring system. Each asset's price history is divided into bull and bear phases (section 04), and each analyst's daily stance on that asset is scored against those phases. Each day's sentiment score (0-100) is evaluated against the phase. Bull phase: score = sentiment. Bear phase: score = 100 - sentiment. Higher sentiment during bull = higher score.
accuracy_score: Overall accuracy, 0–100: the analyst's daily stance scored against the asset's bull and bear market phases (bull phase: the stance, bear phase: 100 − the stance), averaged over phases with recency weighting, reduced by a confidence factor when few phases or data days are held, and shrunk toward 50 when the record is sparse. Comparative — rank analysts on the same asset by it; it is NOT a win probability. accuracy_sample_size: Number of evaluated calls behind accuracy_score. Treat scores with a sample below ~10 as weak evidence.
- 🟢 Bull Specialist = Accuracy during bull market phases
- 🔴 Bear Specialist = Accuracy during bear market phases
- 📅 Long-term Expert = Accuracy in phases lasting 90+ days
- ⚡ Short-term Expert = Accuracy in phases under 60 days
balanced_score: Harmonic mean of bull_score and bear_score when both are positive (else the lower of the two) — rewards analysts who are right in both regimes.
Minimum requirements for a score
- At least 50 days of sentiment data
- Participation in at least 2 bull AND 2 bear phases
- Active posting history (not inactive for 6+ months)
- At least 1 year of history from first to last data
- Both long and short phase participation for Long/Short-term categories
An analyst without a score is shown as Tracked with no rank. A rank is also withheld while an analyst has fewer than 30 directional calls (“insufficient calls”).
Rank
overall_rank is the analyst’s position among every analyst that has an accuracy score (1 = best; ties share the higher count). The asset list’s rank is Position in the asset's list sorted by accuracy_score, counted among analysts active (an original post) in the last three calendar months; ties break by sample size, then handle. Ranks are published on the analyst page and in the API only.
Why percentile tiers, not scores
An accuracy score to one decimal place suggests a precision the data does not have: the gap between two analysts a few tenths apart moves with how many calls each has made and over which period, so it is not a statistically meaningful ordering, and the analyst list does not show it. The tracked pool is itself a selected group of leading analysts, so instead of a rank inside that pool the badge states an analyst’s position as a percentile — of that pool, or, where we have estimated it, of the world population of analysts publishing calls on the asset — Top 1%, Top 5%, Top 10% or Top 25% — on the basis set out below. We do not use letter grades. The precise score, its confidence interval where the score provides one, and the pool position are published on each analyst’s page and in the API / MCP response for anyone who needs them.
How the badge is assigned
Badges are computed per asset from the same accuracy score that drives the ranks: an analyst’s badge on ETH is their position among the analysts ranked on ETH, their badge on NVDA among those ranked on NVDA (an asset nobody is scored on yet reads —). The tracked pool of an asset is every analyst who meets all of:
- an accuracy score exists for the asset class;
- at least 30 directional calls (bullish or bearish posts on tracked assets; neutral posts do not count);
- not a company account, news feed or bot, and not removed from the consensus index;
- at least 10 eligible analysts in the class — with fewer, nobody in that class carries a badge.
Inside the pool, analysts are ordered by score; tied analysts share one (mid-rank) position and therefore one badge. The badge is the analyst’s actual percentile inside that pool — percentile = ⌈100 × position ÷ pool size⌉ — nothing is inflated (a position of 10 in a pool of 107 is the 10th percentile and reads Top 10%, not Top 1%):
- percentile ≤ 1 and the undisputed #1 of a pool of at least 100 → Top 1%
- percentile ≤ 5 → Top 5%
- percentile ≤ 10 → Top 10%
- percentile ≤ 25 → Top 25%
- inside the pool but past the 25th percentile → no badge; the page still shows the exact position (“#k of N analysts”) and the API carries
badge: "ranked" - below the baseline (fewer than 30 directional calls, not yet scored, or excluded) → no badge, shown as — in lists and Tracked in the API
A position exactly on a boundary (the 5th, 10th or 25th percentile) is inside the higher badge; a tie that straddles a boundary lands on the lower side for all of its members. In lists, analysts are ordered by badge and, within a badge, by their number of calls; the score itself is not shown there. The API carries the exact position (pool_rank, pool_size, percentile) and the score version for every badge, and every surface — the page, the lists, the API / MCP payloads and the share images — derives the badge from that position through one rule.
For an asset with a decided world population the same table is applied to the world instead of the pool: percentile = ⌈100 × position ÷ Nworld⌉, with no “undisputed #1” or pool-size clause (the population is far larger than 100). The API then says basis: "world" and carries world_size and world_percentile next to the unchanged pool position. An asset without a decided population carries no percentile badge on that asset at all — its row states the pool position alone (“#k of n analysts”, API badge: "ranked", basis: "pool"); the asset-class badges keep the pool percentile of the table above. Today:
- BTC — Nworld = 1,500 (capture–recapture estimate 1,607, 95% 1,364–1,851): pool rank ≤ 15 → Top 1% · pool rank ≤ 75 → Top 5% · pool rank ≤ 150 → Top 10% · pool rank ≤ 375 → Top 25%
- ETH — Nworld = 950 (capture–recapture estimate 974, 95% 650–1,298): pool rank ≤ 9 → Top 1% · pool rank ≤ 47 → Top 5% · pool rank ≤ 95 → Top 10% · pool rank ≤ 237 → Top 25%
- SOL — Nworld = 650 (capture–recapture estimate 628, 95% 214–1,042): pool rank ≤ 6 → Top 1% · pool rank ≤ 32 → Top 5% · pool rank ≤ 65 → Top 10% · pool rank ≤ 162 → Top 25%
- HYPE — Nworld = 250 (capture–recapture estimate 232, 95% 58–405): pool rank ≤ 2 → Top 1% · pool rank ≤ 12 → Top 5% · pool rank ≤ 25 → Top 10% · pool rank ≤ 62 → Top 25%
Badges on a world scale: the BTC population
For BTC the badge is no longer a percentile of the tracked pool but of the world population of analysts: everyone who publishes directional (bullish or bearish) BTC calls (on X, in newsletters, in research notes or when quoted by the press), not only the analysts tracked here.
That population cannot be counted directly, so we estimate it the way field biologists count a population they cannot see: capture–recapture. Two lists are built independently: the tracked BTC rank pool, and every person quoted with a directional BTC call in 180 days of news coverage, merged by name and screened down to analyst-type voices. The size of their overlap gives the size of the whole (Chapman’s estimator: N̂ = (n₁ + 1)(n₂ + 1) ÷ (m + 1) − 1, where n₁ and n₂ are the two list sizes and m the overlap).
For BTC the estimate is about 1,607 analysts (95% interval 1,364–1,851); we use N = 1,500 as the population size. Both lists over-represent prominent analysts, which makes the method under-estimate, so the true number is more likely above 1,500 than below it. A second, X-search-based list gave a higher but unstable figure and is kept for reference only.
The badge then reads world_top_pct = 100 × pool rank ÷ N: Top 1% for pool ranks 1–15, Top 5% to rank 75, Top 10% to rank 150, Top 25% to rank 375. This rests on one stated assumption: that the tracked pool is the top group of that population, so rank k inside the pool is rank k in the world. The pool is selected for reach, activity and track record (section 06), but the assumption itself is not tested here; the pool position (“#k of N analysts”) therefore stays visible next to every badge.
Badges on a world scale: the ETH population
For ETH the badge is no longer a percentile of the tracked pool but of the world population of analysts: everyone who publishes directional (bullish or bearish) ETH calls (on X, in newsletters, in research notes or when quoted by the press), not only the analysts tracked here.
That population cannot be counted directly, so we estimate it the way field biologists count a population they cannot see: capture–recapture. Two lists are built independently: the tracked ETH rank pool, and every person quoted with a directional ETH call in 180 days of news coverage, merged by name and screened down to analyst-type voices. The size of their overlap gives the size of the whole (Chapman’s estimator: N̂ = (n₁ + 1)(n₂ + 1) ÷ (m + 1) − 1, where n₁ and n₂ are the two list sizes and m the overlap).
For ETH the estimate is about 974 analysts (95% interval 650–1,298); we use N = 950 as the population size. Both lists over-represent prominent analysts, which makes the method under-estimate, so the true number is more likely above 950 than below it.
The badge then reads world_top_pct = 100 × pool rank ÷ N: Top 1% for pool ranks 1–9, Top 5% to rank 47, Top 10% to rank 95, Top 25% to rank 237. This rests on one stated assumption: that the tracked pool is the top group of that population, so rank k inside the pool is rank k in the world. The pool is selected for reach, activity and track record (section 06), but the assumption itself is not tested here; the pool position (“#k of N analysts”) therefore stays visible next to every badge.
Badges on a world scale: the SOL population
For SOL the badge is no longer a percentile of the tracked pool but of the world population of analysts: everyone who publishes directional (bullish or bearish) SOL calls (on X, in newsletters, in research notes or when quoted by the press), not only the analysts tracked here.
That population cannot be counted directly, so we estimate it the way field biologists count a population they cannot see: capture–recapture. Two lists are built independently: the tracked SOL rank pool, and every person quoted with a directional SOL call in 180 days of news coverage, merged by name and screened down to analyst-type voices. The size of their overlap gives the size of the whole (Chapman’s estimator: N̂ = (n₁ + 1)(n₂ + 1) ÷ (m + 1) − 1, where n₁ and n₂ are the two list sizes and m the overlap).
For SOL the estimate is about 628 analysts (95% interval 214–1,042); we use N = 650 as the population size. Both lists over-represent prominent analysts, which makes the method under-estimate, so the true number is more likely above 650 than below it.
The badge then reads world_top_pct = 100 × pool rank ÷ N: Top 1% for pool ranks 1–6, Top 5% to rank 32, Top 10% to rank 65, Top 25% to rank 162. This rests on one stated assumption: that the tracked pool is the top group of that population, so rank k inside the pool is rank k in the world. The pool is selected for reach, activity and track record (section 06), but the assumption itself is not tested here; the pool position (“#k of N analysts”) therefore stays visible next to every badge.
Badges on a world scale: the HYPE population
For HYPE the badge is no longer a percentile of the tracked pool but of the world population of analysts: everyone who publishes directional (bullish or bearish) HYPE calls (on X, in newsletters, in research notes or when quoted by the press), not only the analysts tracked here.
That population cannot be counted directly, so we estimate it the way field biologists count a population they cannot see: capture–recapture. Two lists are built independently: the tracked HYPE rank pool, and every person quoted with a directional HYPE call in 180 days of news coverage, merged by name and screened down to analyst-type voices. The size of their overlap gives the size of the whole (Chapman’s estimator: N̂ = (n₁ + 1)(n₂ + 1) ÷ (m + 1) − 1, where n₁ and n₂ are the two list sizes and m the overlap).
For HYPE the estimate is about 232 analysts (95% interval 58–405); we use N = 250 as the population size. Both lists over-represent prominent analysts, which makes the method under-estimate, so the true number is more likely above 250 than below it.
The badge then reads world_top_pct = 100 × pool rank ÷ N: Top 1% for pool ranks 1–2, Top 5% to rank 12, Top 10% to rank 25, Top 25% to rank 62. This rests on one stated assumption: that the tracked pool is the top group of that population, so rank k inside the pool is rank k in the world. The pool is selected for reach, activity and track record (section 06), but the assumption itself is not tested here; the pool position (“#k of N analysts”) therefore stays visible next to every badge.
Assets without a decided population estimate carry no percentile badge on that asset. Only the pool position (“#k of n analysts”) is shown. An estimate is added per asset as it is made, and the badge appears with it; today: BTC, ETH, SOL, HYPE.
Refresh cadence
Posts are collected from X every 4 hours, from news sources every 30 minutes and from Seeking Alpha and Substack twice a day, and labelled right after collection; licensed sell-side ratings are polled hourly. Call counts and the current bias follow within the hour. Each asset’s market phases and accuracy scores are updated once a day after 00:00 UTC: the open tail of the phases is re-judged, every (analyst, asset) pair whose stance days or ratings changed is re-scored, and that asset’s ranks and badges are recomputed from the stored scores, so a badge can move when other analysts are added or re-scored. A change of the scoring formula re-scores every asset in one batch under a new score version (section 03 states the version in force). The sentence’s “as of” date is the time the page was generated, and as_of in the API is the generation time of that response (cached one hour).
Limits
- Scores are comparative percentiles / adjusted rates, not win probabilities; compare analysts on the same asset.
- Accuracy is scored per asset, inside each asset’s own price phases, for every asset with enough analysts holding calls on it (crypto, stocks, ETFs, commodities); a score is shown without a rank while the asset has fewer than 50 data days for the analyst, a price history under a year, too few calls or too few ranked analysts.
- Note: History depth varies by analyst. X returns at most the 3,200 most recent posts per account, and deeper history is backfilled selectively, so an analyst's record may not cover their full posting history. Scores are computed on the days we hold.
- Share of bullish among the analyst's recent directional calls on the asset, 0–100 (50 = balanced). A stance, not a quality signal.
Cite as: CryptoQuant Analyst Consensus, https://consensus.cryptoquant.com/analyst/<handle> · machine-readable: API docs · llms.txt