Files
winning-wallet-finder_github/research/grade_surge.py
T
jaxperro eeeed39e22 surgebot: Study A paper harness, deploy-ready for the Friday sprint (#16)
Real-time PAPER trader of the FROZEN surge signal on its own Fly app
(wwf-surgebot, recorder-pattern image, no keys, no bot imports):
$100 paper book · 5%-of-equity daily stakes ($1 venue floor) · cash-gated
all-or-nothing · event cap 2 · paper FAK against the live CLOB book inside
p_ref*1.05 · provisional CLOB settles re-graded nightly with CTF payout
vectors (grade_surge.py -> surge_paper_ledger.jsonl). Informed set
published daily (informed_set.py -> params/informed_set.json, frozen
method). Unit-tested: fill/crater/event-cap/cash paths exact; live smoke:
dual sockets + sizing clean. Believing any of it stays gated on the #16
forward verdict.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 15:15:53 -04:00

80 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""Nightly chain-truth grading of the surge paper harness (wwf-surgebot).
Pulls /data/surge_state.json off the box (read-only — never writes back),
re-grades every settled entry with CTF payout vectors (payouts.truth; the
harness's provisional CLOB winner flags lie on operator-resolved markets,
[[polymarket-resolution-truth]]), and appends one row per settle to
research/surge_paper_ledger.jsonl (keyed asset+ts, idempotent). Also emits
the running paper-book summary the #16 sprint decision reads."""
import json
import os
import shutil
import subprocess
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
LEDGER = os.path.join(HERE, "surge_paper_ledger.jsonl")
TMP = os.path.join(HERE, ".surge_state.pull.json")
FLYCTL = shutil.which("flyctl") or "/opt/homebrew/bin/flyctl"
def main():
r = subprocess.run([FLYCTL, "ssh", "sftp", "get", "/data/surge_state.json",
TMP, "-a", "wwf-surgebot"], capture_output=True,
timeout=300, stdin=subprocess.DEVNULL)
if not os.path.exists(TMP) or os.path.getsize(TMP) == 0:
print("[grade_surge] box unreachable or no state yet — skip")
return 0
st = json.load(open(TMP))
os.remove(TMP)
sys.path.insert(0, os.path.join(HERE, "..", "live"))
import payouts
have = set()
try:
for ln in open(LEDGER):
try:
d = json.loads(ln)
have.add((d["asset"], d["ts"]))
except Exception:
pass
except FileNotFoundError:
pass
settled = st.get("settled", [])
new = [s for s in settled if (s["asset"], s["ts"]) not in have]
if new:
payouts.ensure(sorted({s["cond"] for s in new if s.get("cond")}))
graded = flips = 0
with open(LEDGER, "a") as fh:
for s in new:
t = payouts.truth(s.get("cond"), s.get("asset")) if s.get("cond") else None
pay = s["payout"] if t is None else t
pnl = round(s["shares"] * pay - s["cost"] - s["fee"], 2)
if t is not None and abs(t - s["payout"]) > 1e-9:
flips += 1
fh.write(json.dumps({**s, "chain_payout": pay, "chain_pnl": pnl,
"flip": t is not None
and abs(t - s["payout"]) > 1e-9}) + "\n")
graded += 1
total = wins = 0
pnl_sum = 0.0
try:
for ln in open(LEDGER):
d = json.loads(ln)
total += 1
wins += d["chain_payout"] == 1.0
pnl_sum += d["chain_pnl"]
except FileNotFoundError:
pass
c = st.get("counters", {})
print(f"[grade_surge] +{graded} settles ({flips} provisional flips) · "
f"book: {total} settled {wins}W · chain P&L ${pnl_sum:+.2f} · "
f"cash ${st.get('cash', 0):.2f} · open {len(st.get('open', {}))} · "
f"lifetime trig {c.get('triggers')} fill {c.get('fills')} "
f"crater {c.get('craters')}")
return 0
if __name__ == "__main__":
sys.exit(main())