🎯 Alternative.me Fear & Greed Index
The Fear & Greed Index is a free, daily sentiment indicator that measures market psychology by analyzing cryptocurrency volatility, market momentum, dominance, trending, and social volume. Values range from 0 (Extreme Fear) to 100 (Extreme Greed).
Index Zones
- 0–24: 😱 Extreme Fear — panic selling, potential contrarian buy opportunity
- 25–44: 😨 Fear — uncertainty, sellers gaining momentum
- 45–55: 😐 Neutral — balanced sentiment, choppy trading
- 56–74: 😏 Greed — risk appetite rising, FOMO building
- 75–100: 🤑 Extreme Greed — euphoria, potential pullback risk
API Endpoint: https://api.alternative.me/fng/?limit=30&format=json (no key required)
import requests
from datetime import datetime
def get_fear_greed(limit: int = 30) -> list:
"""
Fetch Fear & Greed Index history.
Values: 0 (Extreme Fear) → 100 (Extreme Greed)
Zones: 0-24 Extreme Fear | 25-44 Fear | 45-55 Neutral | 56-74 Greed | 75-100 Extreme Greed
"""
url = f"https://api.alternative.me/fng/?limit={limit}&format=json"
data = requests.get(url, timeout=10).json()
return data["data"]
def classify_sentiment(value: int) -> str:
if value <= 24: return "😱 Extreme Fear"
if value <= 44: return "😨 Fear"
if value <= 55: return "😐 Neutral"
if value <= 74: return "😏 Greed"
return "🤑 Extreme Greed"
# Current reading
history = get_fear_greed(7)
today = history[0]
score = int(today["value"])
label = today["value_classification"]
ts = datetime.fromtimestamp(int(today["timestamp"]))
print(f"Fear & Greed: {score}/100 — {classify_sentiment(score)}")
print(f"As of: {ts.strftime('%Y-%m-%d')}")
print()
# 7-day trend
print("7-Day History:")
for entry in history:
val = int(entry["value"])
bar = "█" * (val // 10)
print(f" {datetime.fromtimestamp(int(entry['timestamp'])).strftime('%m-%d')} {val:>3} {bar}")
🔄 Contrarian Signal Logic
Extreme sentiment often marks inflection points. When the crowd is maximally fearful or greedy, contrarian traders look for reversals. This approach treats Fear & Greed as a mean-reversion indicator.
Signal Interpretation
- CONTRARIAN_BUY_WATCH: Average sentiment < 25 over 14 days — market in capitulation, potential floor-building
- CONTRARIAN_CAUTION: Average sentiment > 75 over 14 days — euphoria phase, watch for pullbacks
- RECOVERING: Average 25–40 with upward trend — fear easing, recovery phase
- NEUTRAL: Mixed signals or mid-range averages
import pandas as pd
def fear_greed_signal(lookback_days: int = 14) -> dict:
"""
Generate a contrarian signal:
- Sustained extreme fear (avg < 25): potential buy signal
- Sustained extreme greed (avg > 75): potential caution signal
"""
history = get_fear_greed(lookback_days)
values = [int(h["value"]) for h in history]
avg = sum(values) / len(values)
trend = values[0] - values[-1] # positive = rising (more greed recently)
signal = "NEUTRAL"
if avg < 25:
signal = "CONTRARIAN_BUY_WATCH" # Market extremely fearful
elif avg > 75:
signal = "CONTRARIAN_CAUTION" # Market extremely greedy
elif avg < 40 and trend > 10:
signal = "RECOVERING" # Fear recovering toward neutral
return {
"avg_14d": round(avg, 1),
"current": values[0],
"trend_direction": "↑ Rising" if trend > 0 else "↓ Falling",
"signal": signal,
}
result = fear_greed_signal()
print(f"14-day avg: {result['avg_14d']}")
print(f"Current: {result['current']}")
print(f"Trend: {result['trend_direction']}")
print(f"Signal: {result['signal']}")
🔴 Reddit Crypto Sentiment (OAuth)
Reddit's crypto communities (r/CryptoCurrency, r/Bitcoin, r/ethereum) reflect real-time community mood. Using the PRAW library and free Reddit OAuth credentials, you can score posts based on bullish/bearish language.
Setup Reddit OAuth
- Visit reddit.com/prefs/apps
- Create a new app (type: "script")
- Note your
client_idandclient_secret - Install:
pip install praw
API Rate Limit: ~60 requests/minute (free tier). Analyze 50–100 recent posts per subreddit for stability.
import praw
# Free Reddit app at reddit.com/prefs/apps — choose "script" type
reddit = praw.Reddit(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
user_agent="OpenClaw/1.0 (crypto-sentiment-bot)",
)
BULL_WORDS = {"moon","bullish","buy","long","pump","breakout","accumulate","hodl","ath","rally"}
BEAR_WORDS = {"crash","bearish","sell","short","dump","correction","rug","scam","dead","rekt"}
def score_post(text: str) -> int:
"""Simple bag-of-words sentiment: +1 bull, -1 bear."""
words = set(text.lower().split())
bull = len(words & BULL_WORDS)
bear = len(words & BEAR_WORDS)
return bull - bear
def subreddit_sentiment(sub_name: str, limit: int = 100) -> dict:
"""Score recent hot posts in a subreddit."""
sub = reddit.subreddit(sub_name)
scores = []
for post in sub.hot(limit=limit):
text = f"{post.title} {post.selftext}"
score = score_post(text)
scores.append({
"title": post.title[:60],
"score": score,
"upvotes": post.score,
"comments": post.num_comments,
})
avg = sum(s["score"] for s in scores) / len(scores)
bull_count = sum(1 for s in scores if s["score"] > 0)
bear_count = sum(1 for s in scores if s["score"] < 0)
return {
"subreddit": sub_name,
"posts_analyzed": len(scores),
"avg_sentiment": round(avg, 3),
"bullish_posts": bull_count,
"bearish_posts": bear_count,
"bull_pct": round(bull_count / len(scores) * 100, 1),
}
for sub in ["CryptoCurrency", "Bitcoin", "ethereum"]:
result = subreddit_sentiment(sub, limit=50)
emoji = "🟢" if result["avg_sentiment"] > 0 else "🔴"
print(f"{emoji} r/{result['subreddit']:<20} avg: {result['avg_sentiment']:+.3f} | "
f"bull: {result['bull_pct']}%")
Limitations & Tuning
- Sarcasm: "This will moon" vs. "Yeah, this coin is mooning" (sarcasm) look identical to simple bag-of-words
- Meme speak: "HODL," "REKT," "diamond hands" require context dictionaries
- Spam/bots: Filter by upvote count or comment count to weight quality
- Language models: Consider VADER (rule-based) or transformer models (TextBlob, Hugging Face) for nuance
pip install nltk) or fine-tuned transformers for more accurate sentiment classification.
🔥 CoinGecko Trending Coins
CoinGecko's trending endpoint shows the top 7 coins by recent search volume. This reflects what retail investors are chasing right now — useful for detecting alt-season (altcoins rallying) vs. blue-chip dominance.
API Endpoint: https://api.coingecko.com/api/v3/search/trending (free, no key, updates ~every 10 minutes)
def get_trending_coins() -> list:
"""
Top 7 trending coins on CoinGecko (by search volume).
Updates every ~10 minutes. No API key needed.
"""
BASE = "https://api.coingecko.com/api/v3"
data = requests.get(f"{BASE}/search/trending", timeout=10).json()
coins = data.get("coins", [])
print("🔥 Trending Coins (by search volume):")
results = []
for item in coins:
c = item["item"]
results.append({
"rank": c["market_cap_rank"],
"name": c["name"],
"symbol": c["symbol"].upper(),
"score": c.get("score", 0),
"price_btc": c.get("price_btc", 0),
})
for r in results:
print(f" #{r['rank']:>5} {r['symbol']:<8} {r['name']}")
return results
trending = get_trending_coins()
Interpreting Trending
- Major coins trending (BTC, ETH, SOL, BNB): Institutional interest, broad market conviction
- Mostly altcoins trending: Alt-season indicator — retail FOMO, higher risk appetite
- Niche/meme coins trending: Speculative fervor, potential bubble zone
- Stable trends (same 7 coins daily): Low volatility in interest, consolidation phase
📊 Composite Crypto Sentiment Score
Combine Fear & Greed, Reddit bullishness, and trending diversity into a single 0–100 momentum metric. This weighted approach balances multiple signal sources and reduces false positives from single indicators.
Weighting Methodology
- 40% Fear & Greed Index: Market structure & volatility (official, daily update)
- 40% Reddit Bullishness: Community mood across 3 major subreddits (real-time, grassroots)
- 20% Trending Diversity: Retail interest & alt-season phase (volume-based, 10-min updates)
def composite_crypto_sentiment() -> dict:
"""
Combine Fear/Greed + Reddit sentiment + trending signal
into a single 0-100 momentum score.
Weights:
40% Fear & Greed Index (normalized 0-100)
40% Reddit bullishness (bull_pct across 3 subs)
20% Trending diversity (are top 7 major coins or alts?)
"""
# Fear & Greed (already 0-100)
fg = get_fear_greed(1)
fg_score = int(fg[0]["value"])
# Reddit (average bull_pct across 3 subs → normalize to 0-100)
reddit_scores = []
for sub in ["CryptoCurrency", "Bitcoin", "ethereum"]:
try:
r = subreddit_sentiment(sub, limit=30)
reddit_scores.append(r["bull_pct"])
except Exception:
reddit_scores.append(50) # neutral fallback
reddit_score = sum(reddit_scores) / len(reddit_scores)
# Trending (are top coins well-known? proxy for alt-season)
trending = get_trending_coins()
major_symbols = {"BTC","ETH","SOL","BNB","XRP","ADA","DOT","AVAX","MATIC","LINK"}
major_count = sum(1 for t in trending if t["symbol"] in major_symbols)
# Alt-season = mostly unknowns trending = more speculative/risky mood
trending_score = (major_count / len(trending)) * 100 if trending else 50
composite = (fg_score * 0.4) + (reddit_score * 0.4) + (trending_score * 0.2)
return {
"fear_greed": fg_score,
"reddit_bullish_pct": round(reddit_score, 1),
"major_trending_pct": round(trending_score, 1),
"composite_score": round(composite, 1),
"interpretation": classify_sentiment(int(composite)),
}
result = composite_crypto_sentiment()
print(f"\n=== Composite Crypto Sentiment ===")
for k, v in result.items():
print(f" {k:<25}: {v}")
Example Output
=== Composite Crypto Sentiment ===
fear_greed : 42
reddit_bullish_pct : 58.3
major_trending_pct : 71.4
composite_score : 54.7
interpretation : 😐 Neutral
📋 Sentiment Signal Reference
Free sentiment signals and their strengths:
| Signal | Source | Update Freq | Best For |
|---|---|---|---|
| Fear & Greed Index | Alternative.me | Daily (UTC midnight) | Market cycle positioning, extremes |
| Subreddit hot posts | Reddit OAuth | Real-time | Short-term crowd mood, community focus |
| Trending search | CoinGecko | Every 10 min | Momentum, alt-season detection, retail interest |
| Google Trends | pytrends (free) | Daily | Mainstream retail interest, top-of-market froth |
| Twitter/X mentions | Limited free access | Real-time | News-driven spikes, influencer impact |
⚠️ Sentiment Caveats & Limitations
Advanced Improvements
- Sentiment velocity: Track rate of change (dF&G/dt) to detect fast reversals
- Divergences: Compare Fear & Greed vs. price — bullish divergence = uptrend likely to resume
- Macro context: Combine with Fed announcements, CPI data, macro risk-off/risk-on signals
- Transformer models: Fine-tune BERT/RoBERTa on labeled crypto text for state-of-art sentiment