El sentimiento de las noticias financieras es un indicador líder de los movimientos del precio de las acciones. Este tutorial crea un canal que busca noticias sobre acciones específicas utilizando la API de Scavio, realiza un análisis de sentimiento basado en palabras clave en los fragmentos y genera una puntuación de sentimiento que se correlaciona con la dirección del mercado. El canal procesa múltiples tickers en paralelo, almacena datos históricos de sentimiento e identifica divergencias entre el sentimiento y el precio. Analizar cada ticker cuesta $0,005.
Requisitos previos
- Python 3.9+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Una lista de tickers de acciones para monitorear
Guia paso a paso
Paso 1: Búsqueda de noticias financieras por ticker
Para cada cotización bursátil, busque noticias recientes y extraiga señales de sentimiento de titulares de títulos y fragmentos.
import os, requests, json, time, re
from datetime import datetime
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
URL = 'https://api.scavio.dev/api/v1/search'
TICKERS = ['AAPL', 'NVDA', 'TSLA', 'MSFT', 'GOOGL']
def get_stock_news(ticker: str, num: int = 10) -> list:
resp = requests.post(URL, headers=H,
json={'query': f'{ticker} stock news', 'country_code': 'us', 'num_results': num})
return [{'title': r['title'], 'snippet': r.get('snippet', ''), 'url': r['link']}
for r in resp.json().get('organic_results', [])]
news = get_stock_news('NVDA')
print(f'NVDA news: {len(news)} articles')
for n in news[:3]:
print(f' {n["title"][:60]}')Paso 2: Analizar el sentimiento a partir de fragmentos de noticias
Califique el sentimiento de cada artículo utilizando la concordancia de palabras clave. Agregue puntuaciones por ticker para producir una señal de sentimiento general.
BULLISH_WORDS = ['surge', 'soar', 'beat', 'record', 'growth', 'strong', 'upgrade',
'outperform', 'buy', 'bullish', 'rally', 'gains', 'profit', 'revenue up']
BEARISH_WORDS = ['drop', 'fall', 'miss', 'decline', 'weak', 'downgrade', 'sell',
'bearish', 'crash', 'loss', 'layoff', 'warning', 'revenue down', 'lawsuit']
def analyze_sentiment(articles: list) -> dict:
scores = []
for article in articles:
text = f"{article['title']} {article['snippet']}".lower()
bull = sum(1 for w in BULLISH_WORDS if w in text)
bear = sum(1 for w in BEARISH_WORDS if w in text)
score = (bull - bear) / max(bull + bear, 1)
scores.append({'title': article['title'][:50], 'bull': bull, 'bear': bear, 'score': score})
avg_score = sum(s['score'] for s in scores) / len(scores) if scores else 0
signal = 'BULLISH' if avg_score > 0.2 else 'BEARISH' if avg_score < -0.2 else 'NEUTRAL'
return {
'avg_score': round(avg_score, 3),
'signal': signal,
'articles_analyzed': len(scores),
'bullish_articles': sum(1 for s in scores if s['score'] > 0),
'bearish_articles': sum(1 for s in scores if s['score'] < 0),
'details': scores[:5],
}
sentiment = analyze_sentiment(news)
print(f'NVDA Sentiment: {sentiment["signal"]} (score: {sentiment["avg_score"]})')Paso 3: Ejecutar todo el proceso de sentimiento en todos los tickers
Procese todos los tickers y genere un panel de sentimiento del mercado. Guarde los resultados para el seguimiento histórico.
def sentiment_pipeline(tickers: list) -> dict:
results = []
for ticker in tickers:
news = get_stock_news(ticker)
sentiment = analyze_sentiment(news)
sentiment['ticker'] = ticker
sentiment['timestamp'] = datetime.now().isoformat()
results.append(sentiment)
print(f' {ticker:5s} | {sentiment["signal"]:8s} | score: {sentiment["avg_score"]:+.3f} | '
f'{sentiment["bullish_articles"]} bull / {sentiment["bearish_articles"]} bear')
time.sleep(0.3)
# Market overview
avg_market = sum(r['avg_score'] for r in results) / len(results)
market_signal = 'BULLISH' if avg_market > 0.1 else 'BEARISH' if avg_market < -0.1 else 'MIXED'
print(f'\nMarket Sentiment: {market_signal} (avg: {avg_market:+.3f})')
print(f'Cost: ${len(tickers) * 0.005:.3f} ({len(tickers)} tickers)')
# Save for historical tracking
with open('sentiment_history.jsonl', 'a') as f:
for r in results:
f.write(json.dumps(r) + '\n')
return {'results': results, 'market_signal': market_signal}
print('Financial News Sentiment Dashboard')
print('=' * 65)
sentiment_pipeline(TICKERS)Ejemplo en Python
import os, requests, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
BULL = ['surge', 'beat', 'growth', 'strong', 'rally', 'profit']
BEAR = ['drop', 'miss', 'decline', 'weak', 'crash', 'loss']
def stock_sentiment(ticker):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': f'{ticker} stock news', 'country_code': 'us', 'num_results': 10})
articles = resp.json().get('organic_results', [])
scores = []
for a in articles:
text = f"{a['title']} {a.get('snippet', '')}".lower()
b = sum(1 for w in BULL if w in text)
r = sum(1 for w in BEAR if w in text)
scores.append((b - r) / max(b + r, 1))
avg = sum(scores) / len(scores) if scores else 0
signal = 'BULL' if avg > 0.2 else 'BEAR' if avg < -0.2 else 'NEUTRAL'
print(f'{ticker}: {signal} ({avg:+.2f})')
for t in ['AAPL', 'NVDA', 'TSLA']:
stock_sentiment(t)
time.sleep(0.3)Ejemplo en JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const BULL = ['surge', 'beat', 'growth', 'strong', 'rally'];
const BEAR = ['drop', 'miss', 'decline', 'weak', 'crash'];
async function stockSentiment(ticker) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: `${ticker} stock news`, country_code: 'us', num_results: 10 })
});
const articles = (await resp.json()).organic_results || [];
let totalScore = 0;
for (const a of articles) {
const text = `${a.title} ${a.snippet || ''}`.toLowerCase();
const b = BULL.filter(w => text.includes(w)).length;
const r = BEAR.filter(w => text.includes(w)).length;
totalScore += (b - r) / Math.max(b + r, 1);
}
const avg = articles.length ? totalScore / articles.length : 0;
console.log(`${ticker}: ${avg > 0.2 ? 'BULL' : avg < -0.2 ? 'BEAR' : 'NEUTRAL'} (${avg.toFixed(2)})`);
}
(async () => { for (const t of ['AAPL', 'NVDA']) await stockSentiment(t); })();Salida esperada
Financial News Sentiment Dashboard
=================================================================
AAPL | BULLISH | score: +0.312 | 6 bull / 2 bear
NVDA | BULLISH | score: +0.445 | 8 bull / 1 bear
TSLA | NEUTRAL | score: +0.089 | 4 bull / 3 bear
MSFT | BULLISH | score: +0.267 | 5 bull / 2 bear
GOOGL | NEUTRAL | score: -0.034 | 3 bull / 4 bear
Market Sentiment: BULLISH (avg: +0.216)
Cost: $0.025 (5 tickers)