WallStreetBets moves markets, but the official Reddit API has strict rate limits and requires OAuth setup. A Reddit SERP query returns the same posts as structured JSON without authentication. This scanner finds ticker mentions, scores sentiment, and flags momentum shifts at $0.005 per search.
Prerequisites
- Python 3.8+
- requests library
- A Scavio API key from scavio.dev
- List of tickers to monitor
Walkthrough
Step 1: Search Reddit for ticker mentions
Query Reddit SERP for WallStreetBets posts mentioning specific tickers.
import os, requests, re
from collections import Counter
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
TICKERS = ['NVDA', 'AAPL', 'TSLA', 'AMD', 'PLTR']
def search_wsb(ticker):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': f'{ticker} site:reddit.com/r/wallstreetbets',
'country_code': 'us'}).json()
posts = data.get('organic_results', [])
return [{'title': p.get('title', ''), 'snippet': p.get('snippet', ''),
'link': p.get('link', '')} for p in posts]
all_mentions = {}
for ticker in TICKERS:
posts = search_wsb(ticker)
all_mentions[ticker] = posts
print(f'{ticker}: {len(posts)} WSB mentions')
print(f'Cost: ${len(TICKERS) * 0.005:.3f}')Step 2: Score sentiment per ticker
Classify post titles and snippets as bullish, bearish, or neutral.
BULLISH = ['moon', 'rocket', 'calls', 'bull', 'buy', 'long', 'squeeze', 'yolo',
'tendies', 'diamond hands', 'undervalued', 'breakout', 'to the moon']
BEARISH = ['puts', 'bear', 'short', 'crash', 'dump', 'overvalued', 'sell',
'bag', 'loss', 'rip', 'drill', 'worthless', 'rug pull']
def score_sentiment(text):
text_lower = text.lower()
bull = sum(1 for w in BULLISH if w in text_lower)
bear = sum(1 for w in BEARISH if w in text_lower)
if bull > bear: return 'bullish'
if bear > bull: return 'bearish'
return 'neutral'
for ticker, posts in all_mentions.items():
sentiments = Counter()
for p in posts:
combined = f"{p['title']} {p['snippet']}"
sentiments[score_sentiment(combined)] += 1
total = len(posts)
bull_pct = sentiments['bullish'] / total * 100 if total else 0
bear_pct = sentiments['bearish'] / total * 100 if total else 0
signal = 'BULLISH' if bull_pct > 60 else 'BEARISH' if bear_pct > 60 else 'MIXED'
print(f'{ticker}: {signal} (bull {bull_pct:.0f}% / bear {bear_pct:.0f}% / neutral {100-bull_pct-bear_pct:.0f}%)')Step 3: Detect momentum shifts
Compare current sentiment against a stored baseline to flag changes.
import json
from datetime import datetime
def build_report(all_mentions):
report = {'date': datetime.now().strftime('%Y-%m-%d'), 'tickers': {}}
for ticker, posts in all_mentions.items():
sentiments = Counter()
for p in posts:
sentiments[score_sentiment(f"{p['title']} {p['snippet']}")] += 1
total = len(posts)
report['tickers'][ticker] = {
'mentions': total,
'bullish_pct': round(sentiments['bullish'] / total * 100, 1) if total else 0,
'bearish_pct': round(sentiments['bearish'] / total * 100, 1) if total else 0,
'top_post': posts[0]['title'] if posts else 'N/A'
}
# Sort by mention count
sorted_tickers = sorted(report['tickers'].items(), key=lambda x: x[1]['mentions'], reverse=True)
print(f'\n=== WSB Sentiment Report {report["date"]} ===')
for ticker, data in sorted_tickers:
signal = 'BULL' if data['bullish_pct'] > 60 else 'BEAR' if data['bearish_pct'] > 60 else 'MIXED'
print(f' {ticker:6} | {data["mentions"]:3} mentions | {signal:5} | bull:{data["bullish_pct"]}% bear:{data["bearish_pct"]}%')
print(f' | Top: {data["top_post"][:60]}')
print(f'\nTotal cost: ${len(all_mentions) * 0.005:.3f}')
return report
build_report(all_mentions)Python Example
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def wsb_scan(ticker):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': f'{ticker} site:reddit.com/r/wallstreetbets', 'country_code': 'us'}).json()
posts = data.get('organic_results', [])
print(f'{ticker}: {len(posts)} WSB posts')
for p in posts[:3]:
print(f' {p.get("title", "")[:60]}')
for t in ['NVDA', 'TSLA', 'AMD']:
wsb_scan(t)
print(f'Cost: $0.015')JavaScript Example
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function wsbScan(ticker) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query: `${ticker} site:reddit.com/r/wallstreetbets`, country_code: 'us' })
}).then(r => r.json());
console.log(`${ticker}: ${(data.organic_results || []).length} WSB posts`);
}
for (const t of ['NVDA', 'TSLA', 'AMD']) await wsbScan(t);Expected Output
NVDA: 10 WSB mentions
AAPL: 8 WSB mentions
TSLA: 12 WSB mentions
AMD: 7 WSB mentions
PLTR: 9 WSB mentions
Cost: $0.025
=== WSB Sentiment Report 2026-05-20 ===
TSLA | 12 mentions | MIXED | bull:42% bear:33%
NVDA | 10 mentions | BULL | bull:70% bear:10%
PLTR | 9 mentions | BULL | bull:67% bear:11%
AAPL | 8 mentions | MIXED | bull:38% bear:25%
AMD | 7 mentions | BULL | bull:71% bear:14%
Total cost: $0.025