Cuotas de cierre de Pinnacle en DuckDB y Parquet
Respuesta: en Builder o Pro, ejecuta un job diario pequeño que pagina GET /v1/closing?date=YYYY-MM-DD (hasta 2.000 filas por llamada), aplana market y outcomes, y escribe un Parquet por día. DuckDB consulta luego la carpeta con SQL, sin servidor de base de datos. Los registros existen desde que PinnFeed guarda cierres.
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/mes). Prueba de 3 días; tarjeta requerida. REST gratis: signup. Related: closing/CLV, backtesting.
Preguntas frecuentes#
¿Bastan Free/Hobby?#
No — /v1/closing devuelve 403 plan_lacks_history fuera de Builder/Pro.
¿Contenido educativo para adultos?#
Sí (18+).
Contenido educativo para mayores de 18 años. Sin pronósticos ni ganancias garantizadas. En España, apuesta solo con operadores con licencia de la DGOJ.