Les communautés financières de Reddit comme r/wallstreetbets, r/stocks et r/investing révèlent le sentiment des investisseurs particuliers des heures avant qu'il n'apparaisse dans l'évolution des prix. Ce scanner utilise le point de terminaison de recherche Reddit de Scavio pour extraire les discussions récentes mentionnant des tickers boursiers, les note selon le sentiment et l'engagement, et produit une liste de surveillance classée. Chaque analyse de subreddit coûte 0,005 $.
Prérequis
- Python 3.8+
- bibliothèque requests
- Une clé API Scavio depuis scavio.dev
- Tickers cibles ou mots-clés boursiers
Parcours
Étape 1: Configurer le scanner boursier Reddit
Configurer le scanner avec les subreddits cibles et l'extraction de tickers.
import os, requests, re
from collections import defaultdict
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
SUBREDDITS_QUERIES = ['wallstreetbets stock', 'stocks investing', 'investing portfolio']
TICKER_PATTERN = re.compile(r'\b[A-Z]{2,5}\b')
COMMON_WORDS = {'THE', 'AND', 'FOR', 'ARE', 'BUT', 'NOT', 'YOU', 'ALL', 'CAN', 'HER',
'WAS', 'ONE', 'OUR', 'OUT', 'HAS', 'ITS', 'HIS', 'HOW', 'MAY', 'NEW'}
def extract_tickers(text):
found = TICKER_PATTERN.findall(text)
return [t for t in found if t not in COMMON_WORDS and len(t) >= 2]
print('Reddit stock scanner configured.')Étape 2: Analyser Reddit pour les discussions boursières
Rechercher dans les communautés financières Reddit et extraire les mentions de tickers avec leur contexte.
def scan_reddit(query):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': query, 'platform': 'reddit', 'country_code': 'us'}).json()
results = data.get('organic_results', [])[:15]
mentions = defaultdict(list)
for r in results:
text = f"{r.get('title', '')} {r.get('snippet', '')}"
tickers = extract_tickers(text)
for t in tickers:
mentions[t].append({'title': r.get('title', '')[:80],
'snippet': r.get('snippet', '')[:120], 'link': r.get('link', '')})
return mentions
all_mentions = defaultdict(list)
for q in SUBREDDITS_QUERIES:
mentions = scan_reddit(q)
for ticker, posts in mentions.items():
all_mentions[ticker].extend(posts)
print(f' {q}: {len(mentions)} tickers found')
print(f'Total unique tickers: {len(all_mentions)}')Étape 3: Noter les tickers par sentiment et volume
Attribuer des scores de sentiment basés sur des mots-clés de contexte et classer par volume de mentions.
BULLISH = ['buy', 'moon', 'calls', 'bullish', 'undervalued', 'squeeze', 'breakout', 'long']
BEARISH = ['sell', 'puts', 'bearish', 'overvalued', 'crash', 'short', 'dump', 'avoid']
def score_ticker(ticker, posts):
bull = bear = 0
for p in posts:
text = f"{p['title']} {p['snippet']}".lower()
bull += sum(1 for w in BULLISH if w in text)
bear += sum(1 for w in BEARISH if w in text)
total = bull + bear or 1
sentiment = (bull - bear) / total
return {'ticker': ticker, 'mentions': len(posts), 'bullish': bull,
'bearish': bear, 'sentiment': round(sentiment, 2)}
scored = [score_ticker(t, p) for t, p in all_mentions.items()]
scored.sort(key=lambda x: x['mentions'], reverse=True)
print(f'\nTop tickers by mention volume:')
for s in scored[:10]:
signal = 'BULL' if s['sentiment'] > 0.3 else 'BEAR' if s['sentiment'] < -0.3 else 'NEUTRAL'
print(f' ${s["ticker"]:5} | {s["mentions"]:3} mentions | sentiment: {s["sentiment"]:+.2f} | {signal}')Étape 4: Générer une liste de surveillance quotidienne
Filtrer les tickers à fort signal et produire une liste de surveillance classée.
def generate_watchlist(scored, min_mentions=2):
watchlist = [s for s in scored if s['mentions'] >= min_mentions]
watchlist.sort(key=lambda x: abs(x['sentiment']) * x['mentions'], reverse=True)
cost = len(SUBREDDITS_QUERIES) * 0.005
print(f'\n=== Reddit Stock Watchlist ({len(watchlist)} tickers) ===')
print(f'Cost: ${cost:.3f} ({len(SUBREDDITS_QUERIES)} queries)')
for i, s in enumerate(watchlist[:15], 1):
signal = 'BULL' if s['sentiment'] > 0.3 else 'BEAR' if s['sentiment'] < -0.3 else 'MIXED'
print(f' {i:2}. ${s["ticker"]:5} | {s["mentions"]:3}x | {signal:7} | score: {s["sentiment"]:+.2f}')
return watchlist
watchlist = generate_watchlist(scored)Exemple Python
import os, requests, re
from collections import defaultdict
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
TICKER_RE = re.compile(r'\b[A-Z]{2,5}\b')
SKIP = {'THE','AND','FOR','ARE','NOT','YOU','ALL','CAN','HAS','NEW'}
def scan(query):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': query, 'platform': 'reddit', 'country_code': 'us'}).json()
tickers = defaultdict(int)
for r in data.get('organic_results', [])[:10]:
for t in TICKER_RE.findall(f"{r.get('title','')} {r.get('snippet','')}"):
if t not in SKIP: tickers[t] += 1
for t, c in sorted(tickers.items(), key=lambda x: -x[1])[:5]:
print(f' ${t}: {c} mentions')
scan('wallstreetbets stock picks')Exemple JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function scan(query) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query, platform: 'reddit', country_code: 'us' })
}).then(r => r.json());
const tickers = {};
const skip = new Set(['THE','AND','FOR','ARE','NOT','YOU','ALL','CAN','HAS','NEW']);
for (const r of (data.organic_results || []).slice(0, 10)) {
const text = `${r.title || ''} ${r.snippet || ''}`;
for (const m of text.matchAll(/\b[A-Z]{2,5}\b/g)) {
if (!skip.has(m[0])) tickers[m[0]] = (tickers[m[0]] || 0) + 1;
}
}
Object.entries(tickers).sort((a,b) => b[1]-a[1]).slice(0,5)
.forEach(([t,c]) => console.log(` $${t}: ${c} mentions`));
}
scan('wallstreetbets stock picks').catch(console.error);Sortie attendue
wallstreetbets stock: 8 tickers found
stocks investing: 6 tickers found
investing portfolio: 5 tickers found
Total unique tickers: 14
Top tickers by mention volume:
$NVDA | 7 mentions | sentiment: +0.65 | BULL
$TSLA | 5 mentions | sentiment: -0.40 | BEAR
$AAPL | 4 mentions | sentiment: +0.33 | BULL
$AMD | 3 mentions | sentiment: +0.50 | BULL
$SPY | 3 mentions | sentiment: +0.20 | NEUTRAL
=== Reddit Stock Watchlist (8 tickers) ===
Cost: $0.015 (3 queries)