sentiment_anchor
sentiment_anchor is a master switch wired to the crowd's mood, expressed as one number from 0 to 100. That number is the Crypto Fear & Greed Index. Zero is blind panic, 100 is euphoria. You pick a band — "only when it's below 25" — and every cycle the bot looks up the most recent daily reading. If it's inside your band the bot goes on to do whatever it was going to do. If it isn't, the bot places no trades at all that cycle, in any market. It is the signal for "only trade when everybody else has lost their nerve", or its mirror, "only trade when everybody else has lost their mind".
- Bots using it
- 3 (1 out-of-sample, 2 archived; none live)
- Data source
- alternative.me Fear & Greed
- Refresh
- Twice a day (index updates daily)
- History stored
- 3,108 days back to 1 Feb 2018
- Backtest-replayable
- No — see catch #3
- Anchor module
- quants/sentiment_anchor.py
below 25 and strictly above 80.
2018 starts 1 February and 2026 ends 9 August, so those two bars cover part-years.
Where the data comes from
One endpoint, and it is refreshingly boring: https://api.alternative.me/fng/?limit=0. Free, no
API key, no rate-limit dance, no account. We requested it from the production box on the day this page was
written and it returned HTTP 200 with today's reading of 30 — "Fear".
That single number is a composite the vendor builds, not a measurement of anything in particular. alternative.me publishes its own recipe, and it is worth reading before you gate real money on it. Six factors, weighted:
| Factor | Weight | What it is |
|---|---|---|
| Volatility | 25% | BTC volatility and max drawdown vs its own 30- and 90-day averages |
| Momentum / volume | 25% | BTC volume and momentum vs the same trailing averages |
| Social media | 15% | X/Twitter hashtag counts and interaction rate. Reddit is written but not in the live index |
| Surveys | 15% | Currently paused, in the vendor's own words — weekly Strawpoll crypto polls |
| BTC dominance | 10% | Bitcoin's share of total crypto market cap |
| Trends | 10% | Google Trends search volume for Bitcoin queries |
Those weights and the "currently paused" note are transcribed from alternative.me's own methodology page, fetched from prod on the day of writing — not from anything we remember. The same page says, plainly, "the current index is for bitcoin only". Keep that sentence; it comes back in catch #4.
The poller
predictive/sentiment_poller.py, on cron 40 */12 * * * — twice a day, at 00:40 and
12:40 UTC. The index itself only moves once a day, so twice is belt-and-braces rather than a real refresh rate.
The interesting part is limit=0, which asks the vendor for the entire history — every daily
reading since they started publishing. The poller then INSERT OR REPLACEs the whole series on
every single run. That has one delightful side effect: because each run stamps every row with the same
fetched_at, you can read the last successful run straight off any row in the table. Right now
all 3,108 rows say 2026-08-09T12:40:02+00:00. That is how we know both of today's runs failed —
see catch #2.
The table
crypto_sentiment in predictive.db: one row per day, 3,108 of them, from
1 February 2018 to 9 August 2026. Date, value, the vendor's classification label, the original
unix timestamp, and when we fetched it. No pruning — this is the deepest single history in the signal library
by a wide margin, and the fact that nothing is allowed to use it is catch #3.
The classification labels come from the vendor, and the band boundaries below are what those labels actually resolve to across all 3,108 of our rows — observed, not quoted from a spec:
| Label | Range | Days | Share |
|---|---|---|---|
| Extreme Fear | 5–25 | 739 | 23.8% |
| Fear | 26–46 | 899 | 28.9% |
| Neutral | 47–54 | 399 | 12.8% |
| Greed | 55–75 | 790 | 25.4% |
| Extreme Greed | 76–95 | 281 | 9.0% |
What it means for your bot
Config is two optional keys, and you need at least one:
{"below": 25} or {"above": 75}, each a number from 0 to 100. The builder renders
them as "only when crypto Fear & Greed < 25 (extreme fear)".
Mechanically it is the simplest gate we have. Read the newest row. Is it no more than two days old? Is the value inside your band? Yes to both and the bot proceeds. Anything else — no row, a null value, an unparseable date, a reading three days old, a value outside the band — and the answer is no trade. It fails closed, and unlike some of our other anchors it genuinely does (compare finance_anchor, whose docstring makes the same promise and whose freshness check does not keep it).
What it is not is a filter on markets. It is a global gate: the engine short-circuits the entire strategy for that cycle. Your bot does not trade fewer markets when the mood is wrong. It trades none.
The three bots that have used it
The registry reports "1", which is its count of bots whose status is live or out-of-sample. The real
picture, from quants.db:
| Bot | Status | Gate | Fills | Settled | P&L |
|---|---|---|---|---|---|
| Crypto Greed Fade | oos | above: 80 | 0 | 0 | — |
| Crypto Fear Reversion | archived | below: 20 | 12 | 12 | −$12.92 |
| Grok Lab: Poly Tail Lottery +sentiment | archived | below: 25 | 32 | 15 | −$75.00 |
Crypto Fear Reversion wanted capitulation: Fear & Greed under 20, BTC perp funding negative, and a mid-band crypto market that had just dropped 8¢ in an hour. It filled 12 times on 11–12 June, all on Polymarket, at an average entry of 38.8¢. It won 4 of 12 — 33.3% against a break-even of 38.8%, which is why it lost. Archived on 16 June.
Grok Lab: Poly Tail Lottery +sentiment was a repair attempt: take a bot that was buying 3–12¢ longshots and losing, and bolt the fear gate onto it to see whether cheap longshots behave differently in a panic. They do not. It filled 32 times at an average entry of 6.5¢; of the 15 that have settled, all 15 lost, for −$75.00. Seventeen are still open, in markets like "Will China invade Taiwan before 2027" that will not settle for a long time — so that figure is not final, but nothing has settled in its favour yet. Archived on 16 June.
Crypto Greed Fade is the mirror trade: at extreme greed, fade an 8¢ upward spike by buying NO. It has never filled. See catch #1.
The catch
This is the signal where the catch is not a bug in our code or a broken vendor feed. It is that the state you are waiting for may simply not happen, for years, and nothing tells you.
1. The one armed bot's gate has never opened — 17,318 evaluations, zero
Crypto Greed Fade has been armed since 15:25 UTC on 11 June 2026. The engine has evaluated it 17,318 times since. Candidates found: 0. Fills: 0. Errors: 0. It is not broken — it is working exactly as written, and the condition it waits for has not occurred.
It needs Fear & Greed strictly above 80. Since it was armed, the index has ranged from 11 to 33, averaging 22.9. The whole of 2026 tops out at 61. The last reading above 80 anywhere in our history was 22 January 2025 (value 84) — 565 days before this page was written.
In fairness to the bot, and this is the part that would be dishonest to leave out: this is not unprecedented and it is not evidence the signal is useless. Above-80 is a genuinely rare state — 149 of 3,108 days, 4.8%. And we have a longer drought on record: 841 days between 9 November 2021 and 28 February 2024, after which it came back and printed 34 such days in 2024. A gate on a rare regime is supposed to be shut most of the time. The honest warning is narrower: "rare" and "never, at the scale of your patience" are easy to confuse, and nothing in the product distinguishes "waiting correctly" from "will never fire". Which brings us to the number you should actually check before you build.
2. Today's reading is missing right now, and the gate does not care yet
Both of today's scheduled runs — 00:40 and 12:40 UTC on 10 August 2026 — died with
sqlite3.OperationalError: database is locked. The poller has no retry and no alert. Over the
life of its log it has 109 successes and 2 failures, and the two failures are the two most recent
runs.
So the newest row in the table is 9 August, value 31. The live endpoint, queried today, says
30 for 10 August. In this instance the difference is immaterial — no bot's threshold sits between 30
and 31 — but that is luck, not design. And the freshness rule is _STALE_DAYS = 2, so a stale
reading has to be more than two days old before the gate fails closed. At one day old, the gate is
happily trading on yesterday's mood and saying nothing. If the lock persists, it will keep doing that
through 11 August and only shut on the 12th.
We have not fixed this here — the dictionary loop is not allowed to edit pollers, and
database is locked on predictive.db is a shared problem that has taken out other
nightly jobs too, so it wants one deliberate fix rather than a patch on this file. It has been flagged.
3. The backtester cannot replay it — and this is the one where the history is right there
sentiment_anchor is in the backtester's unsupported set. Put it in a bot and the backtest runs
without the gate, returns a curve anyway, and flags unsupported_rules. That curve is not
testing your signal. It is testing your bot with the signal deleted.
What makes this one different from every other unreplayable anchor in the library is that the excuse doesn't apply. The others can't be replayed because we never captured the history. Here we have 3,108 days — eight and a half years — sitting in the table, backfilled on the very first run, one row per day, indexed by date. The only missing piece is a lookup in the replay loop. The backtester's own comment says so: "full F&G history IS stored… but the backtest replay loop doesn't yet look up the by-date value."
Meanwhile the poller's docstring claims the opposite outright — "the signal is backtest-replayable from day one, not live-only." It is not. Two files in the same repository disagree, and the backtester is the one that decides. Believe the backtester.
4. It is a Bitcoin number, and it gates everything your bot touches
The vendor says it: "the current index is for bitcoin only." Roughly half its weight is Bitcoin's own volatility and volume, and another tenth is Bitcoin's share of crypto market cap. It is a read on how Bitcoin traders feel about Bitcoin.
The gate does not know that. It is global, so it applies to every market your bot is configured for. Our own Grok Lab bot was configured across crypto, politics, sports, world-events and other — which means it spent June deciding whether to buy "Will China invade Taiwan before 2027" on the strength of Bitcoin sentiment. Sometimes a global risk-appetite proxy is defensible. Applying it to a geopolitical longshot is a stretch, and it happened because the gate is a whole-bot switch and nobody had to think about it.
5. Half of it is a trailing average, so it describes rather than predicts
Look at the recipe again. Volatility is measured "in comparison with the last 30/90 day average values". So is momentum and volume. That is 50% of the index, by construction, computed as today versus the recent past. Social media and Google Trends — another 25% — react to price moves that have already happened.
The index is therefore mostly a well-presented summary of what just happened. That is fine, and genuinely useful as a regime label. It is not a forecast, and "the crowd is fearful, therefore the price will rise" is folklore, not a mechanism. Extreme fear can persist through an entire drawdown — 2022 had 193 days of it. If you are buying the fear tail you should be able to say why that regime changes the odds in the specific markets you trade, which is a different claim from "sentiment is low".
6. One of the six ingredients is switched off, and another was never switched on
Surveys are 15% of the published weighting and the vendor's own page says "currently paused". The Reddit half of the social-media component is described as "still not in the live index". The page does not say how the missing 15% is redistributed among the remaining factors, and the sub-formulas are not published at all.
Practically: the number you are gating on is not built the way the documentation describes, the vendor is upfront about that, and you cannot reconstruct it. You are trusting a black box that has told you it is partly empty. That is not a reason to avoid it — it is a reason not to treat 68 and 72 as meaningfully different.
7. When the gate was open, it filtered nothing
Both archived bots ran 11–16 June 2026, when the index read 12, 12, 13, 18, 20 and 23. A
below: 25 gate was wide open every one of those days; a below: 20 gate for all but
the last two. Neither bot was ever stopped by its sentiment gate. They just traded, and lost.
This is the failure mode nobody expects, and it is the opposite of catch #1. A gate that is always open is
as uninformative as one that is always shut — but it feels like it is working, because trades are happening
and the bot has a signal attached to it. If you are picking a threshold, check what the index has actually
been doing lately. A below: 25 gate in 2026 has been open 123 of 221 days. It is barely
a filter.
8. The comparisons are strict, and the labels don't line up with the vendor's
below and above are both strict. {"above": 80} does not fire at
exactly 80. {"below": 25} does not fire at exactly 25 — which matters more than it sounds,
because 25 is the top of the vendor's "Extreme Fear" band, and 2023's lowest reading all year was
exactly 25. A bot gated at below: 25 sat out 2023 entirely; one gated at
below: 26 would not have.
The builder's English is also a half-step off the vendor's labels: it appends "(greed)" for any
above of 75 or more, but 76 and up is "Extreme Greed" in the source data. Cosmetic, but if you
are reasoning from the phrase rather than the number you will be one band out.
How to actually use it
None of the above makes it a bad signal. It is free, it is honest about its own construction, it fails closed properly, and it carries the deepest history of anything on our shelf. A short list of what follows:
- Check the base rate before you pick a threshold. This is the single most useful thing on this page. Above 80 has happened on 4.8% of days ever and not once since January 2025. Below 25 has happened on 21.8%. Below 20, 11.2%. Pick the tail you want, then look at what it has actually been doing this year.
- A gate that never opens and a gate that never closes are both broken. Catches #1 and #7 are the same mistake at opposite ends. The useful range is a threshold that is shut most of the time and opens sometimes.
- Don't ask a backtest whether this works. It will answer, and the answer will be about a bot that doesn't have the gate. Forward-test it, and expect to wait.
-
Pair it with something market-specific. On its own it is one Bitcoin mood number applied to your
entire universe. Both archived bots combined it with a price move
(
ya_change_max_cents) and a volume floor, which is the right instinct. - Judge the results against your entry price, not against 50%. Crypto Fear Reversion won a third of its trades and that was a losing record, because it was paying 38.8¢. This trips up everyone.
- Remember it is daily. One value per UTC day. There is no such thing as an intraday sentiment gate here, and two bots that fire eleven hours apart are reading the same number.
Where to go next
finance_anchor is the same shape of global switch wired to a market price instead of a mood, and it is the cautionary tale about fail-closed promises that aren't kept. eco_anchor is the other signal whose real problem is that its gate is almost always shut. resolution_anchor is where the "compare it to the entry price, not to 50%" argument is made properly. wx_anchor and arb_anchor are the two signals with real trade volume behind them.
One curiosity for later: btc_dominance_anchor is a separate signal in our library, polled every
five minutes from CoinGecko, used by no bot. It is also 10% of the number on this page. Gating on both means
counting the same input twice.
Written 10 August 2026. Every number on this page comes from the output of
quants/signal_registry.py, the source of quants/sentiment_anchor.py,
predictive/sentiment_poller.py and quants/backtest.py, a read-only query against
predictive.db or quants.db, the poller's own log, or a live request made from the
production box to alternative.me on the day of writing — including its methodology page, from which the six
factor weights and the "currently paused" note are transcribed. Index history covers 1 February 2018 to
9 August 2026; bot records cover 11 June to 10 August 2026 and are
simulated. Twenty-seven settled trades across two archived bots is
not a track record and is not offered as one. If you find something here that is wrong, it is a bug —
tell us.