Closing odds Pinnacle in DuckDB e Parquet
Risposta: su Builder o Pro, esegui un piccolo job giornaliero che pagina GET /v1/closing?date=YYYY-MM-DD (fino a 2.000 righe per chiamata), appiattisce market e outcomes, e scrive un Parquet al giorno. DuckDB interroga poi la cartella in SQL, senza server database. I record esistono da quando PinnFeed archivia le closing.
1. Daily export (Python)#
import os, sys, requests, pandas as pd
H = {"x-api-key": os.environ["PINNFEED_KEY"]} # ps_live_...
def closing_day(day, sport):
rows, offset = [], 0
while True:
r = requests.get("https://pinnfeed.io/v1/closing", headers=H, timeout=30,
params={"date": day, "sport": sport, "limit": 2000, "offset": offset})
r.raise_for_status() # 403 plan_lacks_history on Free/Hobby
batch = r.json()["closing"]
rows += batch
if len(batch) < 2000:
return rows
offset += 2000
day = sys.argv[1] # e.g. 2026-11-08
out = []
for row in closing_day(day, "soccer"):
m = row["market"]
for o in m["outcomes"] or []:
out.append({
"event_id": row["eventId"], "league": row["league"]["name"], "home": row["home"], "away": row["away"],
"start_time": row["startTime"], "captured_at": row["capturedAt"],
"market": m["type"], "period": m["period"], "line": m["line"], "main": m["main"],
"margin": m["margin"], "max_stake": m["maxStake"],
"outcome": o.get("name"), "decimal": o.get("decimal"), "fair": o.get("fair"),
})
os.makedirs("closing", exist_ok=True)
pd.DataFrame(out).to_parquet(f"closing/soccer-{day}.parquet", index=False) # needs pyarrow
print(len(out), "outcome rows")
2. Query with DuckDB#
-- duckdb shell, from the folder that contains closing/
SELECT league, avg(margin) AS avg_margin
FROM read_parquet('closing/*.parquet')
GROUP BY 1
ORDER BY 2 DESC
LIMIT 20;
CTA#
Builder (99 €). 3-day trial; card required. Free REST: signup. Related: closing/CLV, backtesting.
Domande frequenti#
Free/Hobby bastano?#
No — /v1/closing restituisce 403 plan_lacks_history fuori Builder/Pro.
Contenuto educativo per adulti?#
Sì (18+).
Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.