Pinnacle-Closing-Quoten in DuckDB und Parquet
Antwort: auf Builder oder Pro führen Sie einen kleinen Tagesjob aus, der GET /v1/closing?date=YYYY-MM-DD paginiert (bis 2.000 Zeilen pro Aufruf), market und outcomes flacht und eine Parquet-Datei pro Tag schreibt. DuckDB fragt den Ordner danach mit SQL ab — ohne Datenbankserver. Datensätze existieren ab dem Start der Closing-Speicherung.
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 €/Monat). 3 Tage Testphase; Karte erforderlich. REST gratis: Signup. Related: closing/CLV, backtesting.
Häufige Fragen#
Reicht Free/Hobby?#
Nein — /v1/closing liefert 403 plan_lacks_history außerhalb Builder/Pro.
Bildungsinhalt für Erwachsene?#
Ja (18+).
Bildungsinhalt für Erwachsene (18+). Keine Tipps, kein Gewinnversprechen. In Deutschland nur bei Anbietern auf der GGL-Whitelist wetten.