Los mercados de predicción como Polymarket y Kalshi fijan las probabilidades de eventos de precios según el sentimiento de los comerciantes, pero los comerciantes a menudo reaccionan lentamente a las noticias de última hora. Un agente que combina la búsqueda de noticias en tiempo real con datos de predicción del mercado puede identificar discrepancias: un mercado valora un evento al 30%, pero las noticias recientes sugieren fuertemente que sucederá. Este tutorial crea un agente Python que obtiene posiciones de mercado de predicción a través de sus API públicas, busca las últimas noticias sobre cada pregunta del mercado a través de Scavio y produce un informe que destaca los mercados donde el sentimiento de las noticias difiere de las probabilidades actuales. El costo de búsqueda es de $0,005 por cada pregunta de mercado marcada.
Requisitos previos
- Python 3.10+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Familiaridad con las API REST y JSON
Guia paso a paso
Paso 1: Obtener mercados de predicción activos
Extraiga mercados activos de la API pública de Polymarket. Cada mercado tiene una pregunta, probabilidad actual y metadatos. Filtre los mercados con suficiente volumen para que sean significativos.
import os, requests, json
from datetime import datetime
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
SEARCH_HEADERS = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def get_active_markets(min_volume=50000, limit=20):
resp = requests.get('https://gamma-api.polymarket.com/markets',
params={'limit': limit, 'active': True, 'ascending': False,
'order': 'volume'})
markets = resp.json()
return [m for m in markets
if float(m.get('volume', 0)) >= min_volume
and m.get('question')]Paso 2: Busque noticias recientes sobre cada pregunta del mercado
Para cada mercado, busque en Google News a través de la API de Scavio con la pregunta del mercado como consulta. Recopile los 5 titulares y fragmentos principales como contexto de las noticias.
def search_news(question):
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers=SEARCH_HEADERS,
json={'query': question, 'country_code': 'us'})
data = resp.json()
results = data.get('organic_results', [])[:5]
news_items = []
for r in results:
news_items.append({
'title': r.get('title', ''),
'snippet': r.get('snippet', ''),
'url': r.get('link', ''),
'date': r.get('date', ''),
})
return news_itemsPaso 3: Analizar el sentimiento y producir un informe
Para cada mercado, compare los titulares de las noticias con la probabilidad del mercado. Marque los mercados donde las noticias sugieren fuertemente un resultado diferente al que implica el precio de mercado.
def analyze_market(market, news):
question = market['question']
probability = float(market.get('outcomePrices', '[0.5]').strip('[]').split(',')[0])
positive_words = ['will', 'confirmed', 'expected', 'likely', 'approved', 'passed', 'wins']
negative_words = ['unlikely', 'rejected', 'denied', 'fails', 'canceled', 'delayed']
headline_text = ' '.join(n['title'].lower() + ' ' + n['snippet'].lower() for n in news)
pos_count = sum(1 for w in positive_words if w in headline_text)
neg_count = sum(1 for w in negative_words if w in headline_text)
news_sentiment = 'POSITIVE' if pos_count > neg_count else 'NEGATIVE' if neg_count > pos_count else 'NEUTRAL'
divergence = False
if news_sentiment == 'POSITIVE' and probability < 0.4:
divergence = True
elif news_sentiment == 'NEGATIVE' and probability > 0.6:
divergence = True
return {
'question': question,
'market_probability': f"{probability:.0%}",
'news_sentiment': news_sentiment,
'divergence': divergence,
'top_headline': news[0]['title'] if news else '',
'source': news[0]['url'] if news else '',
}Paso 4: Ejecute el agente completo y genere el informe
Combine todos los pasos: busque mercados, busque noticias para cada uno, analice e imprima un informe ordenado por señales de divergencia.
def run_agent():
markets = get_active_markets(limit=15)
print(f'Analyzing {len(markets)} active markets...\n')
briefing = []
for m in markets:
news = search_news(m['question'])
analysis = analyze_market(m, news)
briefing.append(analysis)
divergent = [b for b in briefing if b['divergence']]
aligned = [b for b in briefing if not b['divergence']]
if divergent:
print('--- DIVERGENCE SIGNALS ---')
for b in divergent:
print(f" {b['question'][:70]}")
print(f" Market: {b['market_probability']} | News: {b['news_sentiment']}")
print(f" Headline: {b['top_headline'][:80]}")
print()
print(f'--- SUMMARY ---')
print(f'{len(divergent)} divergence signals, {len(aligned)} aligned')
print(f'Cost: ${len(markets) * 0.005:.3f}')
return briefing
run_agent()Ejemplo en Python
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def get_markets(limit=10):
return requests.get('https://gamma-api.polymarket.com/markets',
params={'limit': limit, 'active': True, 'order': 'volume',
'ascending': False}).json()
def search_news(question):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': question, 'country_code': 'us'}).json()
return data.get('organic_results', [])[:5]
def run():
markets = get_markets()
for m in markets:
if not m.get('question'): continue
news = search_news(m['question'])
prob = float(m.get('outcomePrices', '[0.5]').strip('[]').split(',')[0])
headlines = ' '.join(n.get('title', '').lower() for n in news)
pos = sum(1 for w in ['confirmed', 'approved', 'wins', 'likely'] if w in headlines)
neg = sum(1 for w in ['rejected', 'unlikely', 'fails', 'denied'] if w in headlines)
sentiment = 'POS' if pos > neg else 'NEG' if neg > pos else 'NEUTRAL'
flag = '*' if (sentiment == 'POS' and prob < 0.4) or (sentiment == 'NEG' and prob > 0.6) else ' '
print(f'{flag} [{prob:.0%}] {m["question"][:60]} | News: {sentiment}')
print(f'Cost: ${len(markets) * 0.005:.3f}')
run()Ejemplo en JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const SH = { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' };
async function getMarkets(limit = 10) {
return fetch(`https://gamma-api.polymarket.com/markets?limit=${limit}&active=true&order=volume&ascending=false`)
.then(r => r.json());
}
async function searchNews(question) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH, body: JSON.stringify({ query: question, country_code: 'us' })
}).then(r => r.json());
return (data.organic_results || []).slice(0, 5);
}
async function run() {
const markets = await getMarkets();
for (const m of markets) {
if (!m.question) continue;
const news = await searchNews(m.question);
const prob = parseFloat((m.outcomePrices || '[0.5]').replace(/[\[\]]/g, '').split(',')[0]);
const headlines = news.map(n => (n.title || '').toLowerCase()).join(' ');
const pos = ['confirmed', 'approved', 'wins'].filter(w => headlines.includes(w)).length;
const neg = ['rejected', 'unlikely', 'fails'].filter(w => headlines.includes(w)).length;
const sentiment = pos > neg ? 'POS' : neg > pos ? 'NEG' : 'NEUTRAL';
const flag = (sentiment === 'POS' && prob < 0.4) || (sentiment === 'NEG' && prob > 0.6) ? '*' : ' ';
console.log(`${flag} [${(prob * 100).toFixed(0)}%] ${m.question.slice(0, 60)} | News: ${sentiment}`);
}
console.log(`Cost: $${(markets.length * 0.005).toFixed(3)}`);
}
run().catch(console.error);Salida esperada
Analyzing 15 active markets...
--- DIVERGENCE SIGNALS ---
Will the Fed cut interest rates in June 2026?
Market: 28% | News: POSITIVE
Headline: Fed officials signal June rate cut is likely amid cooling inflation
Will SpaceX complete Starship orbital flight by July 2026?
Market: 65% | News: NEGATIVE
Headline: SpaceX delays Starship test flight after engine review
--- SUMMARY ---
2 divergence signals, 13 aligned
Cost: $0.075