Quote Pinnacle in un DataFrame pandas
Risposta: chiama GET /v1/odds e scorri eventi → mercati → esiti per costruire una riga per esito. Ottieni un DataFrame ordinato con decimal, fair, fairProb, margin e maxStake per ogni prezzo, pronto per groupby, Parquet o un notebook. Funziona su tutti i piani; su Free i dati hanno 30 secondi di ritardo.
Codice#
# pip install requests pandas
import os, requests, pandas as pd
r = requests.get(
"https://pinnfeed.io/v1/odds",
headers={"x-api-key": os.environ["PINNFEED_KEY"]}, # ps_live_...
params={"sport": "soccer", "main": "true", "limit": 200},
timeout=20,
)
r.raise_for_status()
rows = []
for ev in r.json()["events"]:
for m in ev.get("markets", []):
for o in m.get("outcomes", []):
rows.append({
"event_id": ev["id"], "start": ev.get("startTime"), "live": ev.get("live"),
"league": (ev.get("league") or {}).get("name"),
"home": ev.get("home"), "away": ev.get("away"),
"market": m.get("type"), "period": m.get("period"), "line": m.get("line"),
"margin": m.get("margin"), "max_stake": m.get("maxStake"),
"outcome": o.get("name"), "decimal": o.get("decimal"),
"fair": o.get("fair"), "fair_prob": o.get("fairProb"),
})
df = pd.DataFrame(rows)
df["start"] = pd.to_datetime(df["start"], utc=True)
print(df.groupby("market")["margin"].describe())
df.to_csv("pinnacle_soccer.csv", index=False)
Passi successivi#
- Mercati con volume:
df[df.max_stake >= 100]. - Oltre 200 eventi: pagina con
offset(documentazione REST). - Quote di chiusura per il CLV su Builder:
/v1/closing/{id}. - Variazioni live senza polling: client WebSocket.
Piani#
Free (0 €): 30 s di ritardo, 2 sport, mercati principali, 1.000 richieste al giorno. Hobby (29 €/mese): REST in tempo reale. Builder (99 €/mese): WebSocket, tutti i mercati e storico delle chiusure. Prova di 3 giorni; carta richiesta, addebito dopo il giorno 3 salvo disdetta.
Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.
Domande frequenti#
Perché una riga per esito?#
Ogni prezzo sta in una colonna, così filtri, pivot e join restano semplici. Una riga per mercato: df.pivot_table(index=["event_id","market","line"], columns="outcome", values="decimal").
Funziona in Jupyter o Colab?#
Sì. Imposta la chiave con os.environ["PINNFEED_KEY"] = "ps_live_..." in una cella che non condividi.
Esiste una versione polars?#
Passa la stessa lista rows a polars.DataFrame(rows).