Download quad_resolutions.csv from 40Hz/kronos-data: direct link, hf CLI and curl.
- Browser
- Download file 4.89 kB
-
https://huggingface.co/40Hz/kronos-data/resolve/main/quad_resolutions.csv
- Command line
-
hf download hf://40Hz/kronos-data/quad_resolutions.csv
-
curl -L -o quad_resolutions.csv https://huggingface.co/40Hz/kronos-data/resolve/main/quad_resolutions.csv
4.89 kB
| #!/usr/bin/env python3 | |
| """quad_resolve.py - resolve paper BUY_YES signals against real market outcomes. | |
| Reads the append-only ledger (mode=paper, action=BUY_YES_15M_UP), fetches each | |
| market from gamma-api, and writes quad_resolutions.csv with win/loss + ROI per | |
| signal. This is what the OOS evaluation needs (ledger alone never resolves). | |
| Math (standard Polymarket YES): entry price p, shares = notional/p. | |
| win -> payout shares*$1, ROI = (1-p)/p | |
| loss -> payout 0, ROI = -1.0 | |
| outcomes = ["Up","Down"]; outcomePrices[0] is Up (the side we buy). | |
| Idempotent: skips markets already in the resolutions file. | |
| """ | |
| import csv | |
| import json | |
| import os | |
| import sys | |
| import urllib.request | |
| from datetime import datetime, timezone | |
| LEDGER = os.environ.get("LEDGER_PATH", "/home/neo/quad_ledger.csv") | |
| RESOLUTIONS = os.environ.get("RESOLUTIONS_PATH", "/home/neo/quad_resolutions.csv") | |
| FIELDS = ["ts", "coin", "market_id", "question", "yes_price", "resolve_ts", | |
| "outcome", "win", "roi"] | |
| def now_iso(): | |
| return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") | |
| def parse_yes_price(raw): | |
| """Ledger stores yes_price as either a JSON array of both outcome prices | |
| (autopilot) or a single YES price float (live-order paper mode).""" | |
| if not raw: | |
| return None | |
| raw = raw.strip() | |
| try: | |
| arr = json.loads(raw) | |
| if isinstance(arr, list) and arr: | |
| return float(arr[0]) # index 0 == Up == our side | |
| except Exception: | |
| pass | |
| try: | |
| return float(raw) | |
| except Exception: | |
| return None | |
| def fetch_market(mid): | |
| url = f"https://gamma-api.polymarket.com/markets/{mid}" | |
| req = urllib.request.Request(url, headers={"User-Agent": "quad-lab/0.1"}) | |
| with urllib.request.urlopen(req, timeout=30) as r: | |
| return json.load(r) | |
| def outcome_prices(m): | |
| """gamma-api returns outcomePrices as a JSON *string* like '["1", "0"]'.""" | |
| raw = m.get("outcomePrices") | |
| if isinstance(raw, list): | |
| return [str(x) for x in raw] | |
| if isinstance(raw, str): | |
| try: | |
| arr = json.loads(raw) | |
| return [str(x) for x in arr] | |
| except Exception: | |
| return [] | |
| return [] | |
| def load_resolved(): | |
| ids = set() | |
| if os.path.exists(RESOLUTIONS): | |
| with open(RESOLUTIONS) as f: | |
| for r in csv.DictReader(f): | |
| ids.add(r["market_id"]) | |
| return ids | |
| def append_resolution(row): | |
| exists = os.path.exists(RESOLUTIONS) | |
| with open(RESOLUTIONS, "a", newline="") as f: | |
| w = csv.DictWriter(f, fieldnames=FIELDS) | |
| if not exists: | |
| w.writeheader() | |
| w.writerow({k: row.get(k, "") for k in FIELDS}) | |
| def main(): | |
| if not os.path.exists(LEDGER): | |
| sys.exit(f"ledger not found: {LEDGER}") | |
| rows = [] | |
| with open(LEDGER) as f: | |
| rows = [r for r in csv.DictReader(f)] | |
| signals = [r for r in rows if r.get("action") == "BUY_YES_15M_UP" | |
| and r.get("mode") == "paper" and r.get("market_id")] | |
| done = load_resolved() | |
| pending = [r for r in signals if r.get("market_id") not in done] | |
| print(f"signals={len(signals)} already_resolved={len(signals) - len(pending)} pending={len(pending)}") | |
| wins = losses = unresolved = 0 | |
| total_roi = 0.0 | |
| for r in pending: | |
| mid = r["market_id"] | |
| try: | |
| m = fetch_market(mid) | |
| except Exception as e: | |
| print(f" {mid} {r['coin']}: fetch err {e}") | |
| unresolved += 1 | |
| continue | |
| status = m.get("umaResolutionStatus") | |
| prices = outcome_prices(m) | |
| if status != "resolved" or len(prices) < 2 or m.get("closed") is not True: | |
| print(f" {mid} {r['coin']}: not resolved yet (status={status})") | |
| unresolved += 1 | |
| continue | |
| p = parse_yes_price(r.get("yes_price")) | |
| if p is None: | |
| print(f" {mid} {r['coin']}: unparsable yes_price={r.get('yes_price')!r}") | |
| unresolved += 1 | |
| continue | |
| up_won = prices[0] == "1" | |
| roi = (1 - p) / p if up_won else -1.0 | |
| row = {"ts": now_iso(), "coin": r["coin"], "market_id": mid, | |
| "question": r.get("question", ""), "yes_price": str(p), | |
| "resolve_ts": r.get("resolve_ts", ""), | |
| "outcome": "UP" if up_won else "DOWN", | |
| "win": str(up_won), "roi": f"{roi:.4f}"} | |
| append_resolution(row) | |
| wins += 1 if up_won else 0 | |
| losses += 0 if up_won else 1 | |
| total_roi += roi | |
| print(f" {mid} {r['coin']}: price={p} -> {'WIN' if up_won else 'LOSS'} roi={roi:+.3f}") | |
| if wins + losses: | |
| n = wins + losses | |
| print(f"\nresolved now: {wins}W/{losses}L hit={wins/n:.3f} mean_roi={total_roi/n:+.3f}") | |
| if unresolved: | |
| print(f"unresolved still: {unresolved}") | |
| print("done", now_iso()) | |
| if __name__ == "__main__": | |
| main() |