Skip to main content
⚠️
Sentiment signals are lagging and noisy — they reflect crowd psychology, not fundamental value. Never use sentiment as a sole trading signal.
Crypto & DeFi · Part 4 of 5

Sentiment & Fear/Greed

Gauge market psychology using the Fear & Greed Index, Reddit community signals, and trending coin data — all from free APIs.

Alternative.me Reddit OAuth CoinGecko Trending No Paid APIs

🎯 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

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}")
💡 Tip: The Fear & Greed Index updates daily at midnight UTC. Historical data helps identify cycles and reversals. Watch for sustained extremes (>7 days) as they often precede corrections or recoveries.

🔄 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

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']}")
⚠️ Remember: Contrarian signals work best in cyclical markets. In strong uptrends or downtrends, sustained extreme sentiment can persist for weeks. Pair with technical support/resistance and volume confirmation.

🔴 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

  1. Visit reddit.com/prefs/apps
  2. Create a new app (type: "script")
  3. Note your client_id and client_secret
  4. 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

🎓 Advanced: Replace bag-of-words with VADER sentiment analyzer (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

💡 Signal: Compare trending composition week-over-week. A shift from 70% major coins to 30% major coins signals a sentiment change toward risk-on behavior.

📊 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

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
📈 Actionable: Composite scores >60 suggest position-taking into strength; scores <40 may favor accumulation or hedging. Monitor day-over-day changes to detect sentiment shifts before they're priced in.

📋 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

Sentiment Lags Price: Fear & Greed often reflects yesterday's volatility and dominance. By the time sentiment shifts, a significant move may already be underway. Use sentiment for confirmation, not prediction.
Reddit Word Lists Need Tuning: "Moon" can be sarcasm ("this dog coin will moon to $0.000001"), and "hodl" vs. "hold" skew results. Context-aware models (VADER, transformer-based) improve accuracy.
Fear & Greed Is Backward-Looking: The index is built from yesterday's volatility, momentum, and dominance data. It doesn't predict tomorrow's market behavior; it rates how scared/greedy traders were historically.
Best Use Cases: Position sizing (reduce size in extreme greed), portfolio rebalancing (sell into euphoria), and hedging (buy puts in extremes). Sentiment works best as a macro filter, not entry/exit logic.

Advanced Improvements