Fenestra

Methodology

How a public post becomes a call, how we price it, how we label what happened, and how a caller's score is built. This describes the code that runs the site today, including where it is weak.

Last updated:

1. Where calls come from

We track an approved list of public callers. Today that means public Telegram channels, read through Telegram's public web preview (t.me/s/<channel>) without logging in. A scheduled pass runs about every 30 minutes: it reads the newest page of each channel (a few pages the first time we see one), stores new posts, extracts calls, fetches prices, re-labels outcomes and recomputes scores. Reposts of identical text from the same channel are stored once. We count every call we capture, winners and losers, including calls the caller later deletes.

Callers added by visitors. Anyone can add a public Telegram channel from the leaderboard or Check. We check it automatically on the spot: it must have a public preview, a post in the last 3 weeks, and at least 3 of its newest posts must name a token or contract address. Bot, tracker and trending feeds are turned away. Channels that pass are tracked like the rest from that moment on, are marked "Added by the community", and rank only after enough scored calls. Calls made before we started tracking are not backfilled beyond the newest few pages.

2. Reading a post

A post becomes a call when it names something tradable and says, or clearly implies, to buy or sell it. Four kinds count as calls: trade signals, conditional signals, directional calls and memecoin calls.

3. Price data

So for most calls our price history has one point per hour, plus a snapshot roughly every 30 minutes for recent memecoins. We do not see every trade or the exact intra-hour path.

4. Labelling an outcome

Each call is evaluated at five horizons: 15m, 1h, 4h, 1d and 1w after the post. For a horizon, we take every price point whose start time is at or after the post time and no later than post time plus the horizon.

Calls with an entry and a stop are judged as a trade. The entry is the midpoint of the stated entry range. If the price never trades through the entry in the window, the call is unresolved. Once the entry is touched, we go through the price points in time order, starting with the one where the entry was touched, and look for the first one that reached the first target or the stop. Whichever came first decides the call: the first target makes it a win and the stop makes it a loss, and anything that happens afterwards is ignored. If neither is reached, the label follows the return from entry to the last close, as in section 6. The result in R (multiples of the distance from entry to stop) is measured at the exit price: the stop, the first target, or the last close. We also record the best and worst excursion in the window. Same-candle rule: with hourly data, a single price point can touch both the target and the stop, and we cannot tell which came first. In that case we assume the stop came first and label the call a loss at −1R. This is the conservative choice: it never gives the caller a win we cannot prove.

All other calls are judged as an event study: the move from the start price to the end price. Memecoin calls get the labels in section 5; everything else gets the labels in section 6.

5. Memecoin labels

For a memecoin call, we compare the highest price in the window to the start price (the peak multiple) and the last price to the start price (the terminal multiple). The first rule that matches wins, except that a 2x or 5x reached before a collapse beats rugged and dead (see "Order of events" below):

LabelRule
ruggedPool liquidity fell to 20% or less of its first reading in the window (where we have at least two liquidity readings), or the terminal multiple is 0.02 or less (down 98% or more).
migratedThe token's pool migrated during the window (for example from a launchpad to a DEX), where our data reports it.
deadTerminal multiple 0.1 or less (down 90% or more).
5x_hitPeak multiple 5 or more.
2x_hitPeak multiple 2 or more.
flatNone of the above.

A 2x or 5x hit means the price touched that level at some point in the window, measured from our start price. It does not mean a follower could have sold there: the peak may have lasted seconds and liquidity may have been too thin. We also record the time it took to reach 2x.

Order of events. When a token both reached 2x and crossed the rugged or dead level in the window, the label follows what happened first, using the price points in time order. A call that hit 2x and only later went to zero is a 2x_hit (or 5x_hit, counting only the peak before the collapse); a call that collapsed first is rugged or dead. If the 2x and the collapse happen within the same price point, we cannot tell the order and count the collapse first. For a liquidity rug, we assume the liquidity was pulled right after the last healthy liquidity reading, so the 2x only counts if it was complete before that reading.

6. Directional labels

For other calls without a resolved target or stop, the label follows the return in the call's direction:

The ±0.25% band is narrow on purpose (we judge direction, not size), but it means small moves count. Fees, funding and slippage are not deducted.

7. Which verdict a page shows

Each call has up to five labels, one per horizon. Caller and token pages show, for each call, the longest horizon that has a real result (1w, then 1d, 4h, 1h, 15m), skipping insufficient_data and unresolved. A recent call therefore shows a short-horizon verdict that can change as time passes. The summaries on a caller page (2x rate, rug-or-dead rate, win rate, average return) are computed from those per-call verdicts. Win rate is wins divided by wins plus losses; neutral calls are not in it.

8. The caller score

The score used for ranking is computed from the 1d outcomes over all of a caller's calls (the "overall" bucket). It is a number from 0 to 1:

score = 0.85 × base + 0.15 × extra − compliance penalty, clamped to 0…1

Base (85%)

WeightComponentHow it is computed
0.35ExpectancyFor a caller whose calls are all memecoin calls: the average 1d return as a fraction (+50% = 0.5). Otherwise: the average result in R of calls that had an entry and stop. Normalised as (expectancy + 1) / 2 and clamped to 0…1, so anything at or above +1 counts as full marks and anything at or below −1 as zero. No data counts as 0.5.
0.20Hit rateAll-memecoin callers: share of labelled 1d memecoin calls that hit 2x or 5x. Others: wins / (wins + losses). No data counts as 0.5. For a caller with both kinds of calls, this counts only win and loss labels; their memecoin labels appear on the caller page, not in this number.
0.20SpecificityAverage of how specific each call was, 0 to 1: instrument 0.25, direction 0.15, entry 0.20, stop 0.15, target 0.15, timeframe or style 0.10 (rule-read calls can be capped lower).
0.15Sample confidenceNumber of calls / 10, capped at 1.
0.10RecencyAverage over calls of 1 (under 7 days old), 0.8 (under 30), 0.6 (under 90) or 0.4 (older).

Extra (15%)

WeightComponentHow it is computed
0.40Timeliness1 − (minutes between the post and our processing of it) / 240, clamped. Honest note: this mostly measures our ingestion delay rather than the caller, and is a candidate for removal.
0.25ActionabilityShare of human-reviewed calls approved as real calls; 0.75 when none were reviewed.
0.20NoveltySpecificity + 0.1, clamped.
0.15Liquidity fit1 for perpetuals and major venues, 0.7 for other priced instruments, 0.4 otherwise.

Compliance penalty

0.05 for each call marked as policy-blocked or unverifiable, plus 0.10 if the source is inactive, capped at 0.35.

The score is a ranking aid, not a forecast. Read it with the caller's actual calls, sample size and flags.

9. Leaderboard and minimum sample

The leaderboard lists active, publicly listed callers whose score covers at least the minimum sample, currently 10 calls (the public_leaderboard_min_sample setting). The sample counts captured calls, including ones still without a result. Callers are ordered by score. Each leaderboard publication is saved as a snapshot with a hash of its contents, so a published ranking can be checked later. On Pulse, a caller is shown as ranked when they meet the same minimum. Callers below it still have public pages, labelled as new or with too few calls.

10. Deleted, edited and late flags

"Late" is a heuristic. A big run-up before a call often means the caller's circle bought first and followers became exit liquidity, but it can also be an honest call on momentum, or news. The flag describes the price, not intent. Deleted and edited flags are also facts about the post, not accusations.

11. Limitations

12. Token safety

Token pages for Solana tokens show a token safety checklist. The data comes from RugCheck's public token report, refreshed at most every 5 minutes; when RugCheck is down we read only the mint account from Solana RPC (mint and freeze authority, Token-2022 extensions). Holder figures use RugCheck's top holders and leave out AMM pools, lockers and the burn address, so a pool holding half the supply doesn't look like a whale. The verdict is our own rule set, applied in order:

The main pool is the one with the most liquidity. A smaller pool with under 50% locked and at least $1,000 of liquidity is shown as a note but doesn't change the verdict. "Clean" means none of our checks fired, not that a token is safe: a dev can still sell, and holder data covers only the largest wallets. Not investment advice.

13. Corrections

If a call was misread, mispriced or wrongly flagged, tell us with evidence and we will check it. See Disputes. When this methodology changes in a way that moves scores, we will update this page and its date.