"""Polybot live dashboard — Gradio Space (fsanyoto/polybot-dashboard-app), design v2.
v2 (owner Jul-3): standardized design system (tokens/cards/pills — adapted from nexu-io/open-design, Apache-2.0,
vendored at HF `open source resources/open-design/`) + a plain-language GLOSSARY driving hover (i) tooltips on
every metric, + KIND-AWARE score columns (the round-7 regressor logged `pred_ret` — a predicted RETURN, not a
probability; conflating it under "P_rev" was exactly the owner's confusion).
READ-ONLY consumer of the box publishers; auth = Gradio login (DASH_USER/DASH_PASS secrets); data repo private.
"""
import os, json, time, html, datetime as dt
import pandas as pd
import gradio as gr
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from huggingface_hub import HfApi, hf_hub_download
TOK = os.environ.get("HF_TOKEN")
DATA = "fsanyoto/polybot-dashboard"
api = HfApi(token=TOK)
# ── design tokens (single source for every color/spacing decision) ──
# v3 (owner Jul-6): LIGHT / clean aesthetic (afterquery-style) — warm off-white ground, ink text,
# one restrained slate-blue accent. Semantic colors kept muted (good/warn/alert), not decorative.
C = {"bg": "#FBFAF8", "card": "#FFFFFF", "card2": "#F6F4EF", "border": "#EAE7E1", "text": "#17171B",
"muted": "#74726C", "green": "#1C7C54", "amber": "#B7791F", "red": "#B23A2E", "blue": "#2E4B6B",
"purple": "#6D5BA8"}
CSS = f"""
.gradio-container {{ background: {C['bg']} !important; }}
.pb-card {{ background:{C['card']}; border:1px solid {C['border']}; border-radius:12px; padding:14px 16px; }}
.pb-row {{ display:flex; flex-wrap:wrap; gap:10px; }}
.pb-stat {{ background:{C['card']}; border:1px solid {C['border']}; border-radius:12px; padding:10px 14px; min-width:128px; }}
.pb-stat .k {{ font-size:11px; color:{C['muted']}; letter-spacing:.4px; text-transform:uppercase; }}
.pb-stat .v {{ font-size:21px; font-weight:650; color:{C['text']}; margin-top:2px; font-variant-numeric:tabular-nums; }}
.pb-stat .sub {{ font-size:10.5px; color:{C['muted']}; margin-top:2px; font-variant-numeric:tabular-nums; }}
.pb-bar {{ height:5px; border-radius:3px; background:{C['card2']}; margin-top:6px; overflow:hidden; }}
.pb-bar i {{ display:block; height:100%; border-radius:3px; }}
.pb-pill {{ display:inline-block; padding:3px 11px; border-radius:999px; color:#fff; font-size:12.5px; font-weight:600; margin-right:6px; }}
.pb-tbl {{ width:100%; border-collapse:collapse; font-size:13px; color:{C['text']}; }}
.pb-tbl th {{ text-align:left; color:{C['muted']}; font-weight:600; font-size:11.5px; text-transform:uppercase;
letter-spacing:.4px; padding:7px 9px; border-bottom:1px solid {C['border']}; white-space:nowrap; }}
.pb-tbl td {{ padding:6px 9px; border-bottom:1px solid {C['card2']}; white-space:nowrap; font-variant-numeric:tabular-nums; }}
.pb-badge {{ padding:2px 9px; border-radius:6px; font-size:12px; font-weight:600; }}
.tip {{ position:relative; display:inline-block; border-bottom:1px dotted {C['muted']}; cursor:help; }}
.tip .tt {{ visibility:hidden; opacity:0; transition:opacity .12s; position:absolute; z-index:99; bottom:135%;
left:50%; transform:translateX(-50%); width:330px; background:{C['card']}; color:{C['text']};
border:1px solid {C['border']}; border-radius:10px; padding:10px 12px; font-size:12.5px; font-weight:400;
line-height:1.45; white-space:normal; text-transform:none; letter-spacing:0; box-shadow:0 8px 28px #0000001a; }}
.tip:hover .tt {{ visibility:visible; opacity:1; }}
/* (i) TOOLTIP UN-CLIP (Jul-12, owner: tooltip "covered by the other space"): the tips live inside
overflow-x:auto table cards + Gradio block wrappers — an absolute tooltip gets CLIPPED by any
scrolling ancestor and out-stacked by later sibling blocks. Fix: while a tip is hovered, raise its
stacking context AND let every ancestor that clips show overflow (modern :has(); hover-only, so
the table's scroll behavior is untouched when not reading a tip). */
.tip {{ z-index:auto; }}
.tip:hover {{ z-index:9999; position:relative; }}
.tip .tt {{ pointer-events:none; }}
.pb-card:has(.tip:hover), .block:has(.tip:hover), .html-container:has(.tip:hover),
.gradio-container .prose:has(.tip:hover) {{ overflow:visible !important; }}
.block:has(.tip:hover), .html-container:has(.tip:hover) {{ position:relative; z-index:80; }}
.pb-i {{ display:inline-block; width:14px; height:14px; line-height:14px; text-align:center; border-radius:50%;
background:{C['border']}; color:{C['blue']}; font-size:10px; font-weight:700; margin-left:5px; }}
/* DARK-MODE NEUTRALIZER (Jul-6): the v3 palette is LIGHT-only, but gr.themes.Base() follows the BROWSER's dark
preference — Gradio then paints its own text/tabs/labels light-on-our-light-ground (the "fonts messed up" bug).
Re-pin every Gradio var to the palette when the .dark class is present; the js= hook below also forces
__theme=light so this is belt-and-braces. */
.dark, .dark .gradio-container {{
--body-background-fill:{C['bg']}; --background-fill-primary:{C['card']}; --background-fill-secondary:{C['card2']};
--body-text-color:{C['text']}; --body-text-color-subdued:{C['muted']}; --block-background-fill:{C['card']};
--border-color-primary:{C['border']}; --block-border-color:{C['border']};
--block-label-text-color:{C['muted']}; --block-title-text-color:{C['text']};
--link-text-color:{C['blue']}; --color-accent-soft:{C['card2']};
background:{C['bg']} !important; color:{C['text']};
}}
.dark .gradio-container * {{ color-scheme: light; }}
/* ── MM-BACKTESTS: dense newest-first run list + click-to-open right drawer (CSS-only, no JS) ── */
.mmb-r {{ position:absolute; opacity:0; width:0; height:0; pointer-events:none; }}
.mmb-list {{ display:flex; flex-direction:column; border:1px solid {C['border']}; border-radius:12px; overflow:hidden; background:{C['card']}; }}
.mmb-row {{ display:flex; align-items:center; gap:11px; padding:10px 14px; border-bottom:1px solid {C['card2']}; cursor:pointer; transition:background .12s, box-shadow .12s; box-shadow:inset 3px 0 0 transparent; }}
.mmb-row:hover {{ box-shadow:inset 3px 0 0 {C['border']}; }}
.mmb-row:last-of-type {{ border-bottom:0; }}
.mmb-row:hover {{ background:{C['card2']}; }}
.mmb-dot {{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }}
.mmb-q {{ flex:1; font-family:monospace; font-size:12.5px; font-weight:600; color:{C['text']}; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }}
.mmb-mkt {{ font-family:monospace; font-size:11px; color:{C['muted']}; width:78px; text-align:right; }}
.mmb-p {{ font-size:15.5px; font-weight:700; font-variant-numeric:tabular-nums; width:78px; text-align:right; letter-spacing:-.2px; }}
.mmb-when {{ font-family:monospace; font-size:10px; color:{C['muted']}; width:60px; text-align:right; }}
.mmb-tier {{ font-size:9px; font-weight:700; letter-spacing:.03em; text-transform:uppercase; padding:1px 5px; border-radius:5px; border:1px solid; flex:0 0 auto; }}
.mmb-drawer {{ position:fixed; inset:0; z-index:70; pointer-events:none; }}
.mmb-scrim {{ position:absolute; inset:0; background:transparent; transition:background .2s; }}
.mmb-panel {{ position:absolute; top:0; right:0; height:100%; width:min(880px,96vw); background:{C['bg']}; border-left:1px solid {C['border']}; box-shadow:-22px 0 70px #00000030; overflow-y:auto; transform:translateX(101%); transition:transform .24s ease; padding:22px 26px 60px; font-size:14px; }}
.mmb-detail {{ display:none; }}
.mmb-x {{ position:sticky; top:0; float:right; z-index:2; width:34px; height:34px; display:flex; align-items:center; justify-content:center; font-size:24px; line-height:1; color:{C['text']}; background:{C['card2']}; border:1px solid {C['border']}; border-radius:50%; text-decoration:none; cursor:pointer; }}
.mmb-x:hover {{ background:{C['border']}; }}
#mmb-close:not(:checked) ~ .mmb-drawer {{ pointer-events:auto; }}
#mmb-close:not(:checked) ~ .mmb-drawer .mmb-scrim {{ background:#00000075; }}
#mmb-close:not(:checked) ~ .mmb-drawer .mmb-panel {{ transform:none; }}
/* ── phone (Jul-11): 2-up stat chips, tighter cards/tables; wide tables still scroll inside their card ── */
@media (max-width:760px) {{
.gradio-container {{ padding:0 6px !important; max-width:100% !important; }} /* reclaim side space on phones */
.pb-stat {{ min-width:0; flex:1 1 calc(50% - 10px); padding:8px 10px; }}
.pb-stat .v {{ font-size:17px; }}
.pb-card {{ padding:10px 12px; -webkit-overflow-scrolling:touch; }} /* momentum scroll for wide tables */
.pb-tbl th, .pb-tbl td {{ padding:5px 6px; font-size:12px; }}
.mmb-panel {{ padding:16px 14px 50px; }}
.mmb-when {{ font-size:11px; width:auto; }}
.mmb-mkt {{ font-size:11px; }}
.tip .tt {{ width:240px; }}
}}
"""
# force the LIGHT theme WITHOUT navigating. (Jul-12 fix: the old `?__theme=light` window.location.replace
# REDIRECT dropped the PRIVATE Space's auth token inside the MOBILE iframe -> blank "not showing" on phones,
# while desktop's looser cookie policy tolerated it. The CSS DARK-MODE NEUTRALIZER already forces the light
# palette; this just strips any `dark` class gradio adds post-mount, with ZERO page navigation.)
_FORCE_LIGHT_JS = """
() => {
try {
const light = () => {
document.documentElement.classList.remove('dark');
if (document.body) document.body.classList.remove('dark');
document.querySelectorAll('gradio-app,.gradio-container').forEach(function(el){ if (el.classList) el.classList.remove('dark'); });
};
light();
var t = setInterval(light, 250);
setTimeout(function(){ clearInterval(t); }, 4000);
} catch (e) {}
}
"""
# ── the GLOSSARY — one plain-language definition per metric/jargon; drives every (i) + the explainer tab ──
G = {
"dislocation": "The bot's trigger: a market whose YES price moved 5% or more over its last 15 trades. Every row in the live feed is one of these being scored.",
"P_rev": "REVERT probability. The model's estimate that this dislocation snaps back enough to profit — specifically that the trade's net exit return (after fees) exceeds +10%. Higher = better fade candidate.",
"P_adv": "ADVERSE probability. A second, independent model's estimate that the trade would end at ANY net loss. Lower = safer. Blank on older rows: the previous champion (round 7) rejected trades on its own score before this model was ever consulted.",
"w": "Sizing weight. w = (P_rev − P_adv) / 0.2418, capped at 3×. The bot trades ONLY when P_rev > P_adv, and bets more the wider the gap. 1.0 ≈ an average-conviction bet.",
"move": "The YES-price change over the last 15 trades that triggered this signal. +0.053 means YES jumped 5.3 cents; the bot considers fading it.",
"buy": "The faded side's price (cost per share, $0–$1) at the moment the signal was scored.",
"hrs_to_res": "Hours until the market resolves. Very short horizons behave differently (live events whipsaw).",
"gate_block": "Scored and REFUSED — the model(s) saw no edge. This is the bot saying 'no'. Most dislocations should end here.",
"maturity_skip": "Skipped BEFORE scoring: the market has NO known end date (hrs shows −1.0) or its stated end is already IN THE PAST (negative hours — e.g. a 'by July 7' market still trading past July 7 = the resolution window). The backtest only ever scored markets with time remaining, so trading these is untrained resolution risk. Verified vs the venue: these skips match Gamma's own current end dates — not a stale cache.",
"would_enter": "Passed every gate — the bot attempted a real order (posted a resting bid at the touch).",
"equity": "Current account value in USDC (read from the real balance API each cycle).",
"wallet equity": "TRUE account value = cash (ALL three stablecoin buckets: pUSD the venue trades in + USDC.e that merges/redeems pay out in + native USDC) + marks. Benchmarked vs total deposited: $1,018.78, CHAIN-CONFIRMED — exactly 4 deposits from the funding address (Feb-25 $99.15, Feb-27 $19.19 + $9.19, Mar-05 $891.25) and ZERO withdrawals ever; independently matches the venue-ledger reconstruction to the cent.",
"marks": "What your OPEN POSITIONS are worth right now at market prices (shares × current price, the venue's own valuation). Cash + marks = equity. Not realized — it moves with the markets until each position is sold, merged, or resolves.",
"cash (chain)": "The grey history line = CASH ONLY, rebuilt from every venue cash flow since Feb-25 (reconciles to the on-chain balance to the cent). It swings by design: deploying into positions pulls cash DOWN, resolutions/merges pay it BACK — value moving between pockets, not P&L. It is NOT an equity curve (position marks aren't in it).",
"drawdown": "How far equity has fallen from its all-time peak, in %. The durable kill-switch halts entries at −15%.",
"profit": "Equity vs the original deposit, in %.",
"deploy cap": "The maximum share of equity allowed at risk simultaneously. Profit-gated: it grows toward 50% when the bot is winning and shrinks toward 10% in drawdowns. The $ figure is the current budget.",
"idle cash": "Share of the portfolio sitting as uninvested USDC right now (real cash balance ÷ total equity). 100% = nothing deployed; dips = capital in positions. It can never go below 100% − deploy cap. History starts Jul-12 (the beat only began recording it then).",
"markets": "How many fadeable markets the live WebSocket is watching right now.",
"signals/hr": "Dislocations that passed ALL gates per hour this session. 0.0 on a calm tape is normal — the bot is selective by design.",
"max |move|": "The single biggest 15-trade move on any watched market right now, vs the 5% trigger. Tells you how close the tape is to producing a signal.",
"beat": "The dashboard publisher's heartbeat (every ~2 min). A stale beat means the REPORTING sidecar has an issue — not necessarily the bot; check the service pills.",
"health": "The one-glance verdict, computed each beat: ● OK = fresh beat + all services active + drawdown clear of the −15% kill · ▲ = needs a look (late beat, drawdown near the kill, capture sidecar down, or a fresh beat with EMPTY fields = the publisher's log parse broke) · ■ = the trader is down or no beat at all. The pill text says what to do.",
"book capture": "The order-book capture sidecar's last flush (snapshots written to the L2 history that labels future backtests). Missing chip = no recent flush line in its journal.",
"net edge": "Realized P&L as a % of traded notional per window — the compact 'is the strategy paying for itself' number. '(partial)' = the window reaches past the fetched activity history, so the figure covers only part of it.",
"gain importance": "Each feature's share of the deployed LGBM heads' total split gain — what the models actually LEAN ON globally (P_rev and P_adv shown separately; they need not agree).",
"contribs": "Per-signal attribution (SHAP-style pred_contrib): for one recent scored dislocation, the top features pushing THAT head's probability up (+) or down (−) at signal time. Green/red = direction of push, not good/bad.",
"market heartbeat": "The single biggest 15-trade move on any watched market right now, vs the 5% trigger (the red line). The leading gauge: a line kissing 0.05 = dislocations firing; ~0.01 = dead calm. Counts nothing — it's the tape's live energy.",
"dislocations scored (48h)": "How many ≥5% moves crossed the trigger and were judged by the model in the trailing 48 hours. A trailing window — stays high for ~2 days after a burst even once the tape goes quiet. Effectively all dislocations scored (the model participates in only ~6%).",
"services": "truflow-ws = the trading bot · truflow-fills = on-chain fill capture (wallet data) · truflow-book = order-book capture. All read-independently; only truflow-ws touches money.",
"fills capture": "The on-chain sidecar's total captured fills and its lag (seconds between a fill landing on-chain and us seeing it). Feeds future wallet/flow features.",
"would-participate rate": "Share of recently scored dislocations where P_rev > P_adv — i.e. how often the CURRENT champion would have traded. Backtest reference: ~12% of labeled signals participate.",
"WR reference": "The deployed strategy's backtest win rate at live scale: 62.3%. Judge the live win rate against it only after ~5+ completed exits (small samples mislead).",
"edge decay": "Watching whether the live tape still looks like the data the model was trained on: score-distribution drift, participation rate, and (once real fills exist) live win rate vs the 62.3% reference.",
"champion": "The deployed model version. mm-2headnet-v5-spreadtilt = two LGBM heads on net-of-fees labels + spread-tilt sizing; nominated at +5,047%/−10.2% max drawdown on the live-scale backtest.",
"unreal PnL": "Unrealized profit on an OPEN position: (current price − average entry) × shares, from the venue's own position API. Realizes when the position exits (or resolves).",
"redeemable": "The market has RESOLVED and this position can be redeemed for its payout — it should clear on the next auto-redeem sweep.",
"dust": "Below the venue 15-share minimum order, so it cannot be sold on the book. It exits only via merge (if the opposite side is also held), redemption at resolution, or a later same-market entry making the balance sellable.",
"status": "closed = fully exited (incl. dust-roll closes: realized on the matched size, sub-15-share residual rolled forward) · partial = some shares exited, the rest still held — the out column is the LAST exit fill, not a full exit · open = holding, no exits yet · rolled = a sub-15-share residual passed to the NEXT champion's episode (nothing realized here; its cost basis travels with it) · sell-only = an exit of inventory bought before this history window.",
"bought/sold": "Shares INTO the position (buys, incl. any residual carried over from a previous model's episode) / shares OUT (sells + redeems). The difference is what's still held — shown as 'holds N' and in Portfolio.",
"realized $": "Banked on the SOLD shares: sell proceeds minus their average entry cost. Partial episodes realize the sold part; the rest is unrealized.",
"unreal $": "The still-held shares marked at the current price (same source as Portfolio). '—' = held but no current price (e.g. resolved market).",
"total $": "realized + unrealized.",
"ret split": "Each % is against the episode's full entry cost, so realized% + unreal% = total%.",
"pred edge": "The model's edge estimate at entry: P_rev − P_adv. The sizing weight w is this gap divided by W_NORM. Compare it to the realized return to see whether predicted edge is converting into money. '—' = the entry predates the Jul-4 diagnostics fix (pre-fix logs could carry another market's numbers — never shown) or no signal log matches the entry time.",
}
def tip(label, key=None):
t = html.escape(G.get(key or label, ""))
return (f"{html.escape(str(label))}i"
f"{t}")
def _dl(path):
try: return hf_hub_download(DATA, path, repo_type="dataset", token=TOK, force_download=True)
except Exception: return None
def load_modules():
try:
fs = api.list_repo_files(DATA, repo_type="dataset", token=TOK)
mods = sorted(f.split("/")[1][:-5] for f in fs if f.startswith("status/") and f.endswith(".json"))
return [m for m in mods if m != "rei"] # REI removed (owner Jul-25: truflow only) — defensive vs a stray republish
except Exception:
return ["truflow"]
def load_status(m):
p = _dl(f"status/{m}.json")
try: return json.load(open(p)) if p else {}
except Exception: return {}
def load_beats(m):
p = _dl(f"beats/{m}_beats.csv")
if not p: return pd.DataFrame()
try:
b = pd.read_csv(p); b["dt"] = pd.to_datetime(b["ts"], unit="s"); return b
except Exception:
return pd.DataFrame()
def pill(txt, color): return f"{txt}"
def stat(key, val):
return (f"
{tip(key)}
{val}
")
def _bar(frac, color, w=None):
f = max(0.0, min(1.0, frac if isinstance(frac, (int, float)) else 0.0))
ws = f"width:{w}px" if w else ""
return f"
"
def header_html(st):
ts = st.get("beat_ts"); s = time.time() - float(ts) if ts else 9e9
beat_c = C["green"] if s < 300 else C["amber"] if s < 900 else C["red"]
beat_t = f"beat {int(s)}s ago" if s < 120 else f"beat {s/60:.0f}m ago" if s < 9e8 else "no beat"
svc = st.get("services", {})
e, t = st.get("equity", {}), st.get("tape", {})
eq, dd, prof = e.get("eq"), e.get("dd_pct"), e.get("profit_pct")
dep, cap = e.get("deposit"), e.get("cap_pct")
# ── the ANSWER pill (north-star: "am I OK, and if not what do I DO?") — computed verdict, color + glyph ──
bad = [k.replace("truflow-", "") for k, v in svc.items() if v != "active"]
retired = bool(st.get("retired_note")) # Jul-20: fade trader owner-retired — calm, not perma-red
bad_other = [b for b in bad if b != "ws"]
if s >= 900:
verdict, vc = "■ NO BEAT — publisher/box down: check truflow-dash + the box", C["red"]
elif "ws" in bad and not retired:
verdict, vc = "■ TRADER DOWN — restart truflow-ws", C["red"]
elif bad_other:
verdict, vc = "▲ capture degraded — " + ", ".join(bad_other) + " down", C["amber"]
elif "ws" in bad and retired:
verdict, vc = "● " + str(st.get("retired_note")), C["muted"]
elif s < 300 and eq is None:
# LOUD-EMPTY (Jul-11 law): fresh beat + empty headline fields = the publisher's parse broke — say so
verdict, vc = "▲ beat fresh but headline EMPTY — publisher parse broke (check log format)", C["amber"]
elif isinstance(dd, (int, float)) and dd <= -12:
verdict, vc = f"▲ drawdown {dd:.1f}% — entries halt at −15%", C["amber"]
elif s >= 300:
verdict, vc = "▲ beat late — reporting sidecar, not the bot; check truflow-dash", C["amber"]
else:
verdict, vc = "● OK — trading", C["green"]
pills = pill(verdict, vc) + pill(beat_t, beat_c) + "".join(
pill(f"{k.replace('truflow-','')}: {v}",
C["green"] if v == "active" else C["muted"] if (retired and k == "truflow-ws") else C["red"])
for k, v in svc.items())
# sidecar content-freshness chips (fills hydration lag / book flush) — verify-by-content made visible
sc = st.get("sidecars") or {}
fl = (sc.get("fills") or {}).get("lag_p95_s")
if fl is not None:
pills += pill(f"fills lag p95 {fl:.1f}s", C["green"] if fl <= 4 else C["amber"] if fl <= 10 else C["red"])
bs = (sc.get("book") or {}).get("last_flush_snapshots")
if bs is not None:
pills += pill(f"book flush {bs}", C["green"])
def chip(key, val, sub="", bar=""):
return (f"
{tip(key)}
{val}
"
+ (f"
{sub}
" if sub else "") + bar + "
")
chips = [chip("champion", html.escape(str(st.get("version") or "?").replace("mm-2headnet-", "")))]
# ── EQUITY: prefer the REAL on-chain wallet (cash + marks). The log-parsed `eq` is a FROZEN Jul-12
# snapshot once the fade trader retired — never show it as live (it flat-lined at $689 for 8 days).
wal = st.get("wallet") or {}
stale_eq = bool((st.get("equity") or {}).get("stale"))
if wal.get("total") is not None:
# ★ Jul-23 #63: TRUE equity = ALL cash buckets (pUSD spend + USDC.e merge/redeem income) + marks;
# benchmark = audited deposits when the publisher carries them, else the legacy log deposit.
_wdep = wal.get("deposits") if isinstance(wal.get("deposits"), (int, float)) else (
dep if isinstance(dep, (int, float)) else None)
dlt = (wal["total"] - _wdep) if _wdep else None
_sp = wal.get("cash_split") or {}
_cs = (f"cash ${wal.get('cash', 0):,.0f} (pUSD {_sp.get('pusd', 0):,.0f} · USDC.e {_sp.get('usdce', 0):,.0f})"
if _sp else f"cash ${wal.get('cash', 0):,.0f}")
chips.append(chip("wallet equity", f"${wal['total']:,.2f}",
(_cs + f" + marks ${wal.get('marks', 0):,.0f}"
+ (f" · {dlt:+,.0f} vs ${_wdep:,.0f} deposited" if dlt is not None else ""))))
if wal.get("upnl") is not None:
chips.append(chip("open P&L", f"${wal['upnl']:+,.2f}", f"{wal.get('n_pos', '?')} open positions"))
elif eq is not None and not stale_eq:
dlt = (eq - dep) if isinstance(dep, (int, float)) else None
chips.append(chip("equity", f"${eq:,.2f}",
f"{dlt:+,.2f} vs ${dep:,.0f} deposit" if dlt is not None else ""))
else:
chips.append(chip("wallet equity", "?", "on-chain read failed"))
if not stale_eq:
chips.append(chip("profit", f"{prof:+.1f}%" if isinstance(prof, (int, float)) else "?", "vs deposit"))
# The remaining chips are ALL parsed from truflow_ws.log — a frozen snapshot once the trader retired.
# Show them ONLY while the trader is live; when retired, one honest chip instead of six fake-live numbers.
if stale_eq:
chips.append(chip("retired-era stats", "hidden",
"drawdown / cap / markets / signals froze when truflow-ws stopped"))
else:
if isinstance(dd, (int, float)):
dc = C["green"] if abs(dd) < 8 else C["amber"] if abs(dd) < 12 else C["red"]
chips.append(chip("drawdown", f"{dd:.1f}%", "of −15% kill", _bar(abs(dd) / 15.0, dc)))
else:
chips.append(chip("drawdown", "?"))
if isinstance(cap, (int, float)):
chips.append(chip("deploy cap", f"{cap:.0f}%", f"${(eq or 0)*cap/100:,.0f} budget", _bar(cap / 50.0, C["blue"])))
else:
chips.append(chip("deploy cap", "?"))
mm = t.get("max_move")
chips += [chip("markets", t.get("markets", "?")),
chip("signals/hr", t.get("signals_per_hr", "?"), "0 on a calm tape is normal"),
chip("max |move|", f"{mm:.3f}" if mm is not None else "?",
f"trigger {t.get('thr', .05):.2f}",
_bar(mm / (t.get("thr") or .05), C["purple"]) if mm is not None else "")]
note = ""
if stale_eq:
note = (f"
"
"Equity above is the LIVE on-chain wallet (pUSD cash + open marks) and its chart starts "
"Jul-21. The other Trends series (markets, heartbeat, dislocations, idle) come from the "
"retired fade trader's log and END Jul-13 — they are history, not current state. "
"Live activity is on the MM tab.
" for lbl, key in heads)
rows = []
for e in evs[:120]:
is_tilt = e.get("gate_kind") == "tilt" or e.get("p_rev") is not None
p_rev = e.get("p_rev") if is_tilt else None
def f(x, fmt="{:.3f}"):
return fmt.format(x) if isinstance(x, (int, float)) else f"—"
# market NAME (publisher resolves it per beat — owner Jul-3 ask); cond-hash only as the fallback
mkt_name = e.get("market") or ((e.get("cond") or "")[:10] + "…")
rows.append("
"
f"
{html.escape((e.get('t') or '')[:19].replace('T', ' '))}
"
f"
{_badge_event(e.get('event'))}
"
f"
{html.escape(str(mkt_name)[:56])}
"
f"
{f(p_rev)}
{f(e.get('p_adv'))}
{f(e.get('gate_w'), '{:.2f}×')}
"
f"
{f(e.get('move'), '{:+.3f}')}
"
f"
{f(e.get('buy'))}
{f(e.get('hrs_to_res'), '{:.1f}h')}
")
return f"
{th}
{''.join(rows)}
"
# ── Portfolio + Trades round-trip rendering (restored Jul-6): the publisher ALREADY emits st["portfolio"]
# (venue's own open positions) and st["trades"] (entry→exit round-trips, grouped by the model that traded
# them, with the realized/unreal/total PnL trio + the model's edge at entry). The Jul-6 v3 light redesign
# had dropped both views (Trades showed only raw log lines); this restores them in the light palette. ──
def _money(x, fmt="{:+.2f}"):
if not isinstance(x, (int, float)): return f"—"
col = C["green"] if x > 0 else C["red"] if x < 0 else C["muted"]
return f"${fmt.format(x)}"
def _pnl_pct(x):
return (f" 0 else C['red'] if x < 0 else C['muted']}'>{x:+.1f}%"
if isinstance(x, (int, float)) else "—")
def _softbadge(text, bg, fg, title=""):
ti = f" title=\"{html.escape(title)}\"" if title else ""
return f"{html.escape(str(text))}"
def _model_short(m): return html.escape(str(m or "?").replace("mm-2headnet-", ""))
def portfolio_html(st):
ps = st.get("portfolio", [])
if not ps:
return "
No open positions — the bot holds nothing on the venue right now.
"
th = "".join(f"
{h}
" for h in
["market", "side", "shares", "avg px", "cur px", "value", tip("unreal PnL"), "PnL %", ""])
def _row(p):
def f(x, fmt="{:.3f}"): return fmt.format(x) if isinstance(x, (int, float)) else "—"
tag = ""
if p.get("redeemable"):
tag += _softbadge("redeemable", "#EFEBF7", C["purple"], G.get("redeemable", ""))
if p.get("dust"):
tag += " " + _softbadge("dust <15sh", "#FBF1DE", C["amber"], G.get("dust", ""))
return ("
"
f"
{html.escape((p.get('title') or (p.get('cond') or '')[:12])[:70])}
"
f"
{html.escape(str(p.get('outcome') or '—'))}
{f(p.get('shares'), '{:.2f}')}
"
f"
{f(p.get('avg_px'))}
{f(p.get('cur_px'))}
${f(p.get('value'), '{:.2f}')}
"
f"
{_money(p.get('pnl'))}
{_pnl_pct(p.get('pnl_pct'))}
{tag}
")
# GROUP BY MODEL (current champion first, then by group value, "(pre-history)" last)
cur = str(st.get("version") or "")
groups = {}
for p in ps:
groups.setdefault(str(p.get("model") or "(pre-history)"), []).append(p)
def _gkey(m):
return ((0 if m == cur else (2 if m == "(pre-history)" else 1)),
-sum(x.get("value") or 0 for x in groups[m]))
parts = []
for m in sorted(groups, key=_gkey):
gv = sum(p.get("value") or 0 for p in groups[m])
gp = sum(p.get("pnl") or 0 for p in groups[m] if isinstance(p.get("pnl"), (int, float)))
star = (" " + _softbadge("current champion", "#E6F2EA", C["green"])) if m == cur else ""
parts.append(f"
")
parts += [_row(p) for p in sorted(groups[m], key=lambda x: -(x.get("value") or 0))]
tot_v = sum(p.get("value") or 0 for p in ps)
tot_p = sum(p.get("pnl") or 0 for p in ps if isinstance(p.get("pnl"), (int, float)))
foot = (f"
")
# GROUP BY MODEL (same view as Portfolio) — current champion first, then by recency
cur = str(st.get("version") or "")
groups = {}
for t in tr:
groups.setdefault(str(t.get("model") or "?"), []).append(t)
def _gkey(m):
return ((0 if m == cur else 1),
-max((x.get("exit_ts") or x.get("entry_ts") or 0) for x in groups[m]))
parts = []
for m in sorted(groups, key=_gkey):
g = groups[m]
cl = [t for t in g if t.get("status") == "closed" and isinstance(t.get("pnl"), (int, float))]
gp = sum(t["pnl"] for t in g if isinstance(t.get("pnl"), (int, float)))
gwr = (100.0 * sum(1 for t in cl if t["pnl"] > 0) / len(cl)) if cl else None
star = (" " + _softbadge("current champion", "#E6F2EA", C["green"])) if m == cur else ""
parts.append(f"
"
f"{_model_short(m)}{star}"
f" · {len(g)} episode(s) · closed {len(cl)} · realized {_money(gp)}"
+ (f" · WR {gwr:.0f}%" if gwr is not None else "") + "
")
parts += [_row(t) for t in g]
closed = [t for t in tr if t.get("status") == "closed" and isinstance(t.get("pnl"), (int, float))]
tot = sum(t["pnl"] for t in tr if isinstance(t.get("pnl"), (int, float)))
tot_u = sum(t["pnl_u"] for t in tr if isinstance(t.get("pnl_u"), (int, float)))
wr = (100.0 * sum(1 for t in closed if t["pnl"] > 0) / len(closed)) if closed else None
wr_txt = (f" · {tip('WR', 'WR reference')} {wr:.0f}% |62% bt"
if wr is not None else "")
foot = (f"
")
# ── RESOLUTION-TAIL headline (owner Jul-13): the trade-to-resolution losses are otherwise invisible in the
# round-trip win-rate — surface them ANSWER-FIRST with their share of total realized (the §1/§4 standard).
_res = [t for t in tr if t.get("resolved") and isinstance(t.get("pnl"), (int, float))]
_rp = round(sum(t["pnl"] for t in _res), 2)
if _res:
_share = (f" — {abs(_rp) / abs(tot) * 100:.0f}% of realized" if tot else "")
head = (f"
"
f"■ {len(_res)} trade(s) rode to resolution: {_money(_rp)}{_share}"
f"
Positions that never scalped out and "
f"resolved to $0 — a full loss that round-trip win-rate can't see. The ⤵ resolution "
f"rows below. Fix: the round-13 relabel / no-hold-into-resolution.
")
else:
head = (f"
● No hold-to-resolution "
f"losses— every position scalped out before its "
f"market resolved.
")
return f"{head}
{th}
{''.join(parts)}
{foot}
"
def log_html(st):
tl = st.get("recent_trade_lines", [])[::-1]
if not tl:
return "
No money-path log lines in the recent window.
"
body = "".join(f"
{html.escape(l)}
" for l in tl)
return f"
{body}
"
def _style_ax(fig, ax):
# Tufte data-ink: white card ground, no plot fill, only the L-frame spines, no gridlines
fig.patch.set_facecolor(C["card"]); ax.set_facecolor("none")
ax.spines["top"].set_visible(False); ax.spines["right"].set_visible(False)
for s in ("left", "bottom"): ax.spines[s].set_color(C["border"]); ax.spines[s].set_linewidth(.8)
ax.tick_params(colors=C["muted"], labelsize=8, length=3, width=.6)
_t = ax.get_title(); ax.set_title("") # clear the centered title, re-place it left (they're separate slots)
ax.set_title(_t, loc="left", color=C["text"], fontsize=10.5, fontweight="600", pad=8)
ax.grid(False)
def _endpoint(ax, x, y, color, fmt="{:.0f}"):
if y is None or (hasattr(y, "__len__") and not len(y)): return
xv, yv = list(x)[-1], list(y)[-1]
ax.scatter([xv], [yv], s=16, color=color, zorder=5)
ax.annotate(fmt.format(yv), (xv, yv), textcoords="offset points", xytext=(6, 0),
va="center", fontsize=8.5, fontweight="600", color=color)
def charts(beats, deposit=None):
# close the PREVIOUS refresh generation's figures (they're already serialized by now) —
# the Timer re-fires every 60s and unclosed Agg figures leak (the ">20 figures" warning)
plt.close("all")
if beats.empty: return [None] * 5
out = []
# Jul-21: chart the REAL on-chain equity (`wallet_eq` = pUSD cash + open marks) whenever it exists — the
# log-parsed `eq` froze at $689 when the fade trader was retired and drew an 8-day flat line as if live.
eq_col = "wallet_eq" if ("wallet_eq" in beats.columns and beats["wallet_eq"].notna().any()) else "eq"
for col, title, extra, fmt, fill in [
(eq_col, "", None, "${:,.0f}", True),
("max_move", "", .05, "{:.3f}", False),
("gate_blocks_48h", "", None, "{:.0f}", False),
("markets", "", None, "{:.0f}", False),
("idle_pct", "", None, "{:.0f}%", False)]:
if col not in beats.columns or not beats[col].notna().any():
out.append(None); continue
# plot each series over ITS OWN non-null span — `wallet_eq` starts Jul-21 while the frame carries 8
# days of older rows, and plotting the NaN-padded frame renders an empty axis with one dot at the end
b = beats[beats[col].notna()]
if b.empty: out.append(None); continue
fig, ax = plt.subplots(figsize=(9, 2.4))
ax.plot(b["dt"], b[col], lw=1.4, color=C["blue"], solid_capstyle="round",
marker="o" if len(b) < 3 else None, ms=4)
if fill:
ax.fill_between(b["dt"], b[col], b[col].min(), color=C["blue"], alpha=.07)
if col == eq_col and col == "eq" and isinstance(deposit, (int, float)) and deposit > 0:
# benchmark line (§4: no bare chart): equity vs the deposit reference
ax.axhline(deposit, color=C["muted"], ls=(0, (4, 3)), lw=.9, alpha=.8)
ax.annotate("deposit", (list(b["dt"])[0], deposit), textcoords="offset points",
xytext=(2, 4), fontsize=8, color=C["muted"])
if col == "idle_pct":
# context: 100% = fully idle; the deploy-cap bounds how LOW idle can go (100 − cap)
ax.set_ylim(-4, 104)
ax.axhline(100, color=C["muted"], ls=(0, (4, 3)), lw=.8, alpha=.7)
ax.annotate("100% idle", (list(b["dt"])[0], 100), textcoords="offset points",
xytext=(2, 4), fontsize=8, color=C["muted"])
if extra:
ax.axhline(extra, color=C["red"], ls=(0, (4, 3)), lw=.9)
ax.annotate("5% trigger", (list(b["dt"])[0], extra), textcoords="offset points",
xytext=(2, 4), fontsize=8, color=C["red"])
_endpoint(ax, b["dt"], b[col], C["blue"], fmt)
ax.set_title(title); _style_ax(fig, ax); fig.tight_layout(); out.append(fig)
return out
def edge_html(st, beats):
evs = [e for e in st.get("recent_events", []) if e.get("event", "").startswith("gate_block")]
tilt = [e for e in evs if e.get("p_rev") is not None]
rows = []
def li(k, v): rows.append(f"
{tip(k)}
{v}
")
if tilt:
pr = [e["p_rev"] for e in tilt]; pa = [e.get("p_adv") for e in tilt if e.get("p_adv") is not None]
li("P_rev", f"mean {sum(pr)/len(pr):.3f} over {len(pr)} scored (current champion)")
if pa: li("P_adv", f"mean {sum(pa)/len(pa):.3f}")
if pa and len(pa) == len(pr):
pos = sum(1 for r, a in zip(pr, pa) if r > a)
li("would-participate rate", f"{pos}/{len(pr)} = {100*pos/max(len(pr),1):.0f}%")
else:
li("would-participate rate", "no dislocations scored by the CURRENT champion yet (all recent rows are legacy round-7) — populates on the next ≥5% move")
li("WR reference", "62.3% backtest win rate at live scale; live comparison activates after ~5 real exits")
li("edge decay", f"dispositions 48h: {json.dumps(st.get('dispositions_48h', {}))}")
fig = None
if not beats.empty and beats["signals_per_hr"].notna().any():
fig, ax = plt.subplots(figsize=(9, 2.4))
ax.plot(beats["dt"], beats["signals_per_hr"], lw=1.4, color=C["purple"], solid_capstyle="round")
ax.fill_between(beats["dt"], beats["signals_per_hr"], 0, color=C["purple"], alpha=.07)
_endpoint(ax, beats["dt"], beats["signals_per_hr"], C["purple"], "{:.1f}")
ax.set_title("Signals/hr — gate-passing dislocations per hour"); _style_ax(fig, ax); fig.tight_layout()
return f"
{''.join(rows)}
", fig
def glossary_html():
body = "".join(f"
{html.escape(k)}
"
f"
{html.escape(v)}
" for k, v in G.items())
return f"
{body}
"
def model_html(st):
"""Model tab (Jul-11 — the publisher has ALWAYS computed this payload; the Jul-6 redesign dropped the
render): per-window net-edge summary + what the deployed heads LEAN ON (global gain) + per-signal
SHAP-style attribution for the most recent scored dislocations."""
ms = (st.get("model_summary") or {}).get("rows") or []
fi = st.get("feature_importance") or {}
if not ms and not fi:
return "
No model payload in this beat yet.
"
parts = []
if ms:
th = "".join(f"
{h}
" for h in
["window", "version", "trips", "realized $", tip("net edge", "net edge")])
rws = ""
for r in ms:
part = (f" (partial)"
if r.get("partial") else "")
rws += ("
"
f"
{html.escape(str(r.get('window') or ''))}{part}
"
f"
{_model_short(r.get('version'))}
"
f"
{r.get('n', 0)}
{_money(r.get('pnl'))}
"
f"
{_pnl_pct(r.get('net_edge_pct'))}
")
parts.append(f"
"
f"
{th}
{rws}
")
heads = fi.get("heads") or {}
if heads:
def _head_col(hk, title, color):
pairs = (heads.get(hk) or [])[:12]
if not pairs:
return ""
mx = max((p[1] for p in pairs), default=1) or 1
rws = "".join(
f"
")
sigs = fi.get("signals") or []
if sigs:
blocks = ""
for sg in sigs[:8]:
nm = (sg.get("market") or sg.get("cond") or "")[:60]
def _f3(x): return f"{x:.3f}" if isinstance(x, (int, float)) else "—"
head = (f"
{html.escape(str(nm))}"
f" "
f"{html.escape((sg.get('t') or '')[:19].replace('T', ' '))}"
f" · {html.escape(str(sg.get('event') or ''))}"
f" · P_rev {_f3(sg.get('p_rev'))} · P_adv {_f3(sg.get('p_adv'))}
")
def _c(hk):
cs = sg.get("contrib_" + hk) or []
if not cs:
return ""
inner = " ".join(
f" 0 else C['red']}'>{html.escape(str(k))} {cc:+.3f}"
for k, v, cc in cs[:6] if isinstance(cc, (int, float)))
return (f"
")
return "".join(parts)
def integrity_html(mod):
"""INTEGRITY (owner Jul-10: 'trade revalidation against backtest logic should be recurring and reported in
the dashboard'): auto-ops publishes integrity/.json 2-hourly — decision-layer spot-parity (deployed
heads rescore the bot's own logged features bit-exact) + the per-trade forensics summary (every live
round-trip replayed against the champion's logic). Answer-first: CLEAN means live == backtest logic."""
p = _dl(f"integrity/{mod}.json")
try:
d = json.load(open(p)) if p else None
except Exception:
d = None
if not d:
return ("
No revalidation beat published yet — auto-ops writes "
"integrity/truflow.json every 2h (first beat lands on its next firing).
")
try:
age_m = (time.time() - pd.Timestamp(d.get("ts")).timestamp()) / 60
except Exception:
age_m = 9e9
fresh_c = C["green"] if age_m < 300 else C["amber"]
fx = d.get("forensics") or {}
par = d.get("parity") or {}
streak = int(d.get("forensics_err_streak") or 0)
err = bool(fx.get("error")) or bool(par.get("error")) or streak > 0
mk = str(par.get("maker") or "—")
try:
_ok, _tot = mk.split("/"); par_ok = (_tot != "0" and _ok == _tot)
except Exception:
par_ok = None
verdict = "CHECK" if (err or par_ok is False) else "CLEAN"
head = (pill(f"revalidation {verdict}", C["red"] if verdict == "CHECK" else C["green"]) + " "
+ pill(f"beat {int(age_m)}m ago" if age_m < 9e8 else "beat STALE", fresh_c))
rows = []
def li(k, v): rows.append(f"
{html.escape(k)}
{v}
")
li("decision parity (heads bit-exact on own logged feats)",
f"{html.escape(mk)} " + (pill("PASS", C["green"]) if par_ok else pill("check", C["amber"]) if par_ok is False else ""))
n = fx.get("n_trips")
if n is not None:
li("round-trips since champion cutover",
f"{n} — {fx.get('wins', 0)}W/{fx.get('losses', 0)}L ({fx.get('win_rate_pct', '—')}%)" if n else
"0 (armed — no closed trades yet)")
if fx.get("pnl") is not None:
_pc = C["green"] if fx["pnl"] >= 0 else C["red"]
li("realized P&L (champion window)", pill(f"${fx['pnl']:+.2f}", _pc))
if fx.get("cal_gap_pp") is not None:
li("calibration: model P_rev vs realized ≥3% reversion",
f"{100*(fx.get('model_mean_p') or 0):.0f}% vs {100*(fx.get('realized_rev_rate') or 0):.0f}% "
f"(gap {fx['cal_gap_pp']:+.0f}pp; +15m-tape approximation of the maker-fork label)")
fl = fx.get("flags") or {}
li("per-trade divergence flags", html.escape(json.dumps(fl)) if fl else "none")
elif fx.get("error"):
li("forensics leg", pill("ERROR", C["red"]) + f" {html.escape(str(fx.get('error')))}")
ch = d.get("champion") or {}
li("champion under revalidation",
html.escape(f"{ch.get('rev_dir', '?')} · cutover {str(ch.get('cutover_iso', ''))[:16]}Z · "
f"trained_to {ch.get('trained_to', '?')}"))
if streak:
li("revalidation error streak", pill(f"{streak} consecutive failures", C["red"]))
return (f"
{head}
"
f"
{''.join(rows)}
")
def _p(x): return f"{x:.2f}" if isinstance(x, (int, float)) else "—"
def _pct(x): return f"{round(x*100)}%" if isinstance(x, (int, float)) else "—"
# ── the STANDARD drawer section (Jul-6: ONE text renderer for every section — the AI outputs TEXT;
# the price chart is the only graphic). All values render through _fmt_pv (numeric → %, else str). ──
def _sec(t, body, accent=None):
return (f"
{t}
"
f"
{body}
")
def _fmt_pv(v):
if isinstance(v, (int, float)):
return f"{v*100:.1f}%" if 0 < v < 0.01 else _pct(v)
return html.escape(str(v))
def _kv_lines(d):
"""Any {key: value} dict → simple text lines 'key — value' (robust to key length + value type)."""
return "".join(f"
" for k, v in d.items())
# ── MM-BACKTESTS (kind=="backtests") rendering: dense newest-first run list + click-to-open right drawer.
# Each run's drawer shows per-cell equity / %inventory-to-total-value / drawdown inline-SVG charts + key risk
# figures. Data: status/mm_backtests.json (publish_mm_backtests_dash.py aggregates every hf_mm_portfolio run). ──
def _mmb_num(v, unit="", dec=2):
"""Format ONE value by its UNIT, never by guesswork. (The Jul-25 bug: the REI `_fmt_pv` helper coerced EVERY
numeric to a percentage, so HS=0.03 rendered '3%' and WCCAP_X=4 rendered '400%'. Units are explicit here.)"""
if v is None or v == "": return "—"
if isinstance(v, bool): return "on" if v else "off"
if isinstance(v, (list, tuple)):
return ", ".join(_mmb_num(x, unit, dec) for x in v) if v else "—"
if not isinstance(v, (int, float)): return html.escape(str(v))
if unit == "$": return f"${v:,.0f}" if abs(v) >= 100 else f"${v:,.2f}"
if unit == "$+": return f"${v:+,.0f}" if abs(v) >= 100 else f"${v:+,.2f}"
if unit == "%": return f"{v:.1f}%"
if unit == "%+": return f"{v:+.2f}%"
if unit == "n": return f"{v:,.0f}"
if unit == "c": return f"{v*100:.1f}¢" # a price-space distance (HS/DC) reads in cents
if unit == "s": return ("—" if v == 0 else (f"{v:,.0f}s" if abs(v) < 3600 else f"{v/3600:,.1f}h"))
if unit == "h": return f"{v:,.0f}h"
if unit == "d": return f"{v:,.0f}d"
return f"{v:,.4g}" # raw ratio/knob — NEVER a percentage
# Footing keys → how to render them. Anything unlisted falls through to the raw-number form (never a %).
_MMB_UNITS = {"CAPS": "$", "START": "$", "INVCAP_USD": "$", "GROSSCAP_USD": "$", "RESTINGCAP_USD": "$",
"MCAP_USD": "$", "MIN_ORDER_USD": "$", "EQUITY_FLOOR_USD": "$", "RISK_USD": "$",
"HS": "c", "SK": "c", "DC": "c", "DC_MIN": "c", "DC_MAX": "c", "LADDER_STEP": "c",
"RWD_TIGHT": "c", "BARBELL_S1": "c",
"markets": "n", "events": "n", "PER_MKT_NET_SH": "n", "QM_LIVE": "n", "QM": "n",
"MIN_ORDER_SH": "n", "MERGE_MIN_SH": "n", "QUOTE_SIZE": "n", "BARBELL_Z1": "n",
"REWARD_SHARE": "", "QFS": "", "WCCAP_X": "", "RVP": "", "CAPRW": "", "GSKEW": "", "THETAPX": "",
# ★ Jul-25 item 5: the FULL param set now ships in `footing`, so every key needs a unit or it falls
# through to the raw-number form. Seconds/shares/prices/dollars are all distinct here.
"RESOLVE": "", "RESOLVE_LAG_S": "s", "MAX_CIDS": "n", "DAYS_CAP": "n", "LV": "n",
"REQUOTE_S": "s", "MAX_ORDER_AGE_S": "s", "QUOTE_LAG_S": "s", "BOOK_STALE_S": "s",
"DC_WIN": "s", "RVP_WIN": "s", "RVP_REFRESH_S": "s", "REST_TTL_S": "s", "STATE_WIN": "s",
"EQUITY_FLOOR_CHECK_S": "s", "RUN_HOURS": "h", "RVP_MAX_TRADES": "n", "SVEL_K": "n",
"PCUT": "c", "FLOW_MID_SKEW": "c", "LIQ_PX": "c", "ST": "c", "STATE_QSH": "n",
"MAT_REF": "d", "QM_FRAC": "", "QM_FRACS": "", "RESTINGCAP_FRAC": "",
"ACCEPT_UPTIME": "", "ORDER_ACCEPT_SEED": "n", "TOXV": "", "EXIT_PRED_MIN": "",
# live-only block (from the policy manifest — NOT simulated)
"SETTLE_MAX_STALE_S": "s", "VENUE_BACKOFF_BASE_S": "s", "VENUE_BACKOFF_MAX_S": "s",
"WS_DEBOUNCE_S": "s", "WS_STALE_S": "s", "OP_GAP_S": "s"}
def _mmb_kv(d):
"""Footing/params → 'key value' chips with CORRECT units (replaces the percent-everything `_kv_lines`)."""
if not d: return ""
items = []
for k, v in d.items():
if v is None or v == "" or (isinstance(v, (list, tuple)) and not v): continue
items.append(f"
"
def _mmb_svg(vals, color, unit="$", h=76, zeroline=False):
"""One series, one hue, no chartjunk (Tufte): soft area + 2px line, direct min/max/last labels, no gridlines.
`vector-effect` keeps the stroke crisp under the non-uniform viewBox scale."""
vals = [float(v) for v in (vals or []) if v is not None]
if len(vals) < 2:
return f"
no series — legacy run, re-run for charts
"
w = 1000.0
lo, hi = min(vals), max(vals)
pad = (hi - lo) * 0.08 or (abs(hi) * 0.08 or 1.0)
ylo, yhi = lo - pad, hi + pad
rng = (yhi - ylo) or 1.0
n = len(vals); sx = w / (n - 1)
def _y(v): return round(h - (v - ylo) / rng * h, 2)
pts = " ".join(f"{round(i*sx,1)},{_y(v)}" for i, v in enumerate(vals))
area = f"0,{h} {pts} {round((n-1)*sx,1)},{h}"
z = ""
if zeroline and ylo < 0 < yhi:
zy = _y(0.0)
z = (f"")
last = vals[-1]
_fu = {"%": "%+", "n": "n"}.get(unit, "$")
fmt = (lambda x: _mmb_num(x, _fu))
return (
f"
")
def _mmb_metric_grid(m):
"""Hero pair (return + drawdown) then supporting metrics — size encodes importance (Few).
★ Jul-25 item 2: ONE return. The old grid showed `ret_spread_pct` AND `ret_total_pct` side by side; they are
IDENTICAL whenever RWD_COMPOUND=0 (no reward is in the return unless it is compounded), which read as a bug.
Now: the single canonical return + an explicit "rewards accrued but EXCLUDED $X" line when they were accrued
for reporting only."""
ret = m.get("return_pct", m.get("ret_total_pct")); mdd = m.get("mdd_pct")
rc = C['green'] if isinstance(ret, (int, float)) and ret > 0 else (C['red'] if isinstance(ret, (int, float)) else C['muted'])
hero = (f"
"
f"
Return
"
f"
"
f"{_mmb_num(ret,'%+')}
"
f"
Max drawdown
"
f"
"
f"{_mmb_num(mdd,'%+')}
"
f"
Stress MDD
"
f"
"
f"{_mmb_num(m.get('mdd_stress_pct'),'%+')}
")
# what IS and IS NOT inside that one number
_rin = m.get("reward_in_return"); _rex = m.get("reward_accrued_excluded_usd")
if _rin is not None:
_txt = ("return INCLUDES compounded pool rewards" if _rin else
(f"return EXCLUDES rewards — {_mmb_num(_rex,'$')} was accrued for reporting only (RWD_COMPOUND=0)"
if isinstance(_rex, (int, float)) and _rex else "no reward economics in this run"))
hero += (f"
{html.escape(_txt)}
")
# ★ SURVIVAL banner: a run that tripped its own equity floor stopped quoting — everything after the halt is just
# the frozen book resolving, so its months are NOT comparable to a run that quoted the whole window.
if m.get("equity_floor_halted"):
d2h, wd = m.get("days_to_halt"), m.get("window_days")
hero += (f"
⛔ HALTED by the equity floor after "
f"{_mmb_num(d2h,'n')} days"
+ (f" of a {_mmb_num(wd,'n')}-day window" if wd else "")
+ " — the bot stopped quoting; later months are the frozen book resolving, not trading.
")
rows = [("Peak util", "util_pct", "%"), ("Peak inv / value", "peak_inv_pct", "%"),
("Ret on deployed", "ret_on_deployed_pct", "%+"), ("P&L / traded", "pnl_pct_of_traded", "%+"),
("Fills", "fills", "n"), ("Merges", "merges", "n"),
("Peak committed", "peak_committed", "$"), ("Reward mkts", "n_rwd_mkts", "n"),
# ★ Jul-25: the two reads that say whether this is an EDGE verdict or a CAPITAL artifact
("Cash-blocked orders", "cash_blocked_pct", "%"), ("Markets settled", "n_settled", "n")]
cells = []
for lab, k, unit in rows:
v = m.get(k)
col = C['text']
if unit == "%+" and isinstance(v, (int, float)): col = C['green'] if v > 0 else C['red']
if k == "cash_blocked_pct" and isinstance(v, (int, float)): col = C['red'] if v > 50 else C['amber'] if v > 20 else C['text']
cells.append(f"
"
f"
{lab}
"
f"
{_mmb_num(v, unit)}
")
mt, tot = m.get("markets_touched"), m.get("markets_total")
cells.append(f"
"
f"
Markets traded
"
f"
"
f"{_mmb_num(mt,'n')} / {_mmb_num(tot,'n')}
")
grid = (f"
{''.join(cells)}
")
return hero + grid
def _mmb_decomp_html(ed):
"""Edge decomposition — where the return comes from. Bars diverge from a CENTER axis so sign is structural
(positive right / negative left), not color-only; the label carries identity."""
if not ed: return ""
parts = [("Reward", "reward"), ("Bid-ask spread", "spread"), ("Inventory → resolution", "inv_resolution")]
vals = [(lab, ed.get(k + "_pct"), ed.get(k + "_usd")) for lab, k in parts]
absmax = max((abs(p) for _, p, _ in vals if isinstance(p, (int, float))), default=0.0) or 1.0
rows = []
for lab, pv, uv in vals:
if pv is None: continue
half = min(50.0, abs(pv) / absmax * 50.0)
sc = C['green'] if pv > 0 else (C['red'] if pv < 0 else C['muted'])
bar = (f"")
rows.append(
f"
"
f"
{lab}
"
f"
"
f"{bar}
"
f"
"
f"{_mmb_num(pv,'%+')} {_mmb_num(uv,'$+')}
")
tot = ed.get("total_pct")
ok = ed.get("reconciled")
chip = ""
if ok is True:
chip = (f"✓ RECONCILES")
elif ok is False:
chip = (f"⚠ MISMATCH {_mmb_num(ed.get('reconcile_gap_pct'),'%+')}")
note = ed.get("reward_note") or ""
rc = ed.get("rwd_config") or {}
if ed.get("reward_reproducible") is False:
note = (note + " · ⚠ reward config NOT reproducible across runs (live Gamma at run time)").strip(" ·")
elif rc.get("applied"):
note = (note + f" · ✓ reward config from the FROZEN snapshot archive (sha {rc.get('snapshot_sha','')}, "
f"{rc.get('cids_covered')}/{rc.get('cids_total')} markets covered = "
f"{rc.get('coverage_pct')}%)").strip(" ·")
# only report snapshot coverage when the archive was ACTUALLY inspected — the default RWD_META carries
# coverage_pct=0.0, and rendering that reads as a measured "0% coverage" when nothing was measured at all.
if rc and not rc.get("applied") and rc.get("snapshots"):
note = (note + f" · snapshot archive would cover {rc.get('coverage_pct')}% of markets today").strip(" ·")
body = ("".join(rows)
+ f"
" if note else ""))
return _sec("Edge decomposition — where the return comes from", body, accent=C['blue'])
def _mmb_activity_html(a, m=None):
"""★ Jul-25 item 4a — ACTIVITY. A flat equity line is ambiguous: no opportunity, or no capital? This answers it
by drawing what the bot DID per day against what was AVAILABLE per day (markets live).
⚠ The dead-day count is measured ONLY over the days the bot was actually QUOTING. Counting post-halt days as
"markets live but zero fills" would read as starvation when the truth is "it was halted on day N" — the same
measurement-artifact-as-finding error as the retracted 'no book coverage in the middle months' claim."""
if not a or not (a.get("fills") or []): return ""
m = m or {}
fills = a.get("fills") or []; live = a.get("markets_live") or []; filled = a.get("markets_filled") or []
days = a.get("day") or list(range(len(fills)))
d2h = m.get("days_to_halt")
cut = (days[0] + d2h) if (d2h is not None and days) else float("inf")
idx = [i for i in range(len(fills)) if (days[i] if i < len(days) else i) <= cut]
n_after = len(fills) - len(idx)
dead = sum(1 for i in idx if not fills[i] and (live[i] if i < len(live) else 0))
hdr = (f"
"
f" len(idx) * 0.5 else C['text']}'>{dead:,} of "
f"{len(idx):,} quoting days had markets live but ZERO fills"
+ (f" · {n_after:,} further days were POST-HALT (not quoting — excluded)" if n_after else "")
+ f" · peak {max(live) if live else 0:,} markets live · "
f"peak {max(filled) if filled else 0:,} traded in a day
")
body = hdr + _mmb_chart("Fills per day", fills, C['blue'], "n") + \
_mmb_chart("Markets live per day (the opportunity set)", live, C['muted'], "n") + \
_mmb_chart("Markets traded per day (what we actually reached)", filled, C['green'], "n")
return _sec("Activity — is the bot trading, or starved?", body, accent=C['amber'])
def _mmb_resolve_html(rv):
"""★ Jul-25 item 0 — capital release at resolution. Mode 0 means the run was computed under the OLD sim, where
a resolved market's collateral was never returned; any number from it is capital-starved."""
if not rv: return ""
mode = rv.get("mode")
if mode == 0:
return (f"
⚠ RESOLVE=0 — collateral is NEVER released at resolution in "
f"this run (the pre-Jul-25 sim bug). Treat the return as computed under artificial capital "
f"starvation.
"
f"{html.escape(k)}"
f""
f"{_mmb_num(v, '$' if 'releas' in k else ('$+' if 'P&L' in k else ('s' if k=='lag' else 'n')))}
"
for k, v in chips.items() if v is not None)
note = html.escape(str(rv.get("note") or ""))
return _sec("Capital release at resolution",
f"
{items}
"
f"
{note}
", accent=C['green'])
def _mmb_coverage_html(cv):
"""★ Jul-25 item 3 — market coverage: what universe this number was actually measured on, including the cids
that were SILENTLY dropped (no tape / no books / no valid prints) before they were counted."""
if not cv: return ""
win = cv.get("window") or []
top = (f"
"
for k, v in drops.items() if v is not None)
rows = ""
for cat, r in (cv.get("by_category") or {}).items():
if not isinstance(r, dict): continue
rows += (f"
") if sp else ""
return _sec("Market coverage",
top + f"
{chips}
"
+ rows + spn, accent=C['blue'])
def mmb_cell_html(c):
m = c.get("metrics") or {}; s = c.get("series") or None
out = (f"
")
out += (f"
{html.escape(str(c.get('label','cell')))}
")
out += _mmb_metric_grid(m)
out += _mmb_resolve_html(c.get("resolve"))
out += _mmb_decomp_html(c.get("edge_decomp"))
if s:
out += _mmb_chart("Equity ($)", s.get('equity'), C['blue'], "$")
eqr, eq = s.get('equity_reward') or [], s.get('equity') or []
if eqr and eq and any(abs(a - b) > 1e-9 for a, b in zip(eqr, eq)):
out += _mmb_chart("Equity + rewards ($)", eqr, C['green'], "$")
out += _mmb_chart("Inventory as % of total value", s.get('inv_pct'), C['amber'], "%")
out += _mmb_chart("Drawdown (% of bank)", s.get('drawdown'), C['red'], "%", zeroline=True)
if s.get("downsample") == "time_uniform":
out += (f"
series sampled TIME-uniformly "
f"(the old index-uniform sampling hid sparse months)
")
else:
out += (f"
Legacy run — metrics only. "
f"Re-run to get equity / inventory / drawdown charts.
")
out += _mmb_activity_html(c.get("activity"), m)
out += _mmb_coverage_html(c.get("coverage"))
return out + "
"
def mmb_row(r, i):
v = r.get("headline") or {}; ret = v.get("return_pct", v.get("ret_total_pct")); mdd = v.get("mdd_pct")
dotc = {"green": C['green'], "amber": C['amber'], "red": C['red'], "muted": C['muted']}.get(r.get("verdict_color"), C['muted'])
retc = C['green'] if isinstance(ret, (int, float)) and ret > 0 else (C['red'] if isinstance(ret, (int, float)) and ret < 0 else C['muted'])
live = bool(r.get("live_policy_fidelity"))
fid, fc = ("LIVE", C['blue']) if live else ("RES", C['muted'])
# ★ the capital-starved marker must be visible IN THE LIST, not only after clicking into the drawer —
# otherwise a pre-fix run and a corrected one are indistinguishable while scanning.
starved = not any((c.get("resolve") or {}).get("mode", 0) >= 1 for c in (r.get("cells") or []))
st = (f""
f"$0") if starved else ""
charted = any(c.get("series") for c in (r.get("cells") or []))
ch = "" if charted else (f"◷")
return (f"")
def mmb_detail(r, i):
cells = "".join(mmb_cell_html(c) for c in (r.get("cells") or []))
foot = _mmb_kv(r.get("footing") or {}) # ★ unit-correct (NOT the percent-everything _kv_lines)
# ★ Jul-25 item 5: the params the LIVE trader runs that this sim does NOT model, shown separately so
# "simulated" and "live-only" can never be confused for one another.
live_only = _mmb_kv(r.get("footing_live_only") or {})
fdl = r.get("fidelity") or {}
blocked = fdl.get("blocked_exact_parity") or []
blk = ("".join(f"
{html.escape(str(x))}
" for x in blocked)) if blocked else ""
live = bool(r.get("live_policy_fidelity"))
fid, fc = ("LIVE-POLICY FIDELITY", C['blue']) if live else ("RESEARCH ENGINE", C['muted'])
meta = " · ".join(x for x in [html.escape(str(r.get('when', '') or '')),
f"policy {html.escape(str(r.get('policy_id')))}" if r.get('policy_id') else ""] if x)
return (f"
"
f""
f"
{html.escape(str(r.get('run_id','')))}
"
f"
"
f"{fid}"
f"{meta}
"
f"{cells}"
+ (_sec("Footing — every simulated parameter", foot) if foot else "")
+ (_sec("Live-only — run by the LIVE trader, NOT modelled by this sim", live_only, accent=C['amber'])
if live_only else "")
+ (_sec("Blocked from exact parity",
f"
{blk}
",
accent=C['muted']) if blk else "")
+ "
")
def mmb_list_html(st):
runs = st.get("runs") or []
if not runs:
return "
No MM backtests yet. Every hf_mm_portfolio.py run publishes here automatically.
"
radios = (""
+ "".join(f"" for i in range(len(runs))))
style = ""
rows = "".join(mmb_row(r, i) for i, r in enumerate(runs))
details = "".join(mmb_detail(r, i) for i, r in enumerate(runs))
drawer = f"
{details}
"
n_ch = sum(1 for r in runs if any(c.get("series") for c in (r.get("cells") or [])))
head = (f"
"
f"{len(runs)} runs · newest first · click a row for charts, risk figures & edge decomposition"
f"{n_ch} charted · {len(runs)-n_ch} metrics-only
")
return style + radios + head + f"
{rows}
" + drawer
def mmb_header(st):
"""Action-title header: the BASELINE's verdict + number, benchmarked against the rest of the slate."""
runs = st.get("runs") or []
# ★ Jul-25: pick the newest HONEST baseline — live-policy fidelity AND capital actually released
# (`resolve.mode >= 1`). The old substring match on 'livepolicy_v1' now selects the PRE-FIX run, which would
# headline a capital-starved number (−11.06%) as if it were the current baseline.
def _released(r):
return any((c.get("resolve") or {}).get("mode", 0) >= 1 for c in (r.get("cells") or []))
# ...and it must be the BASELINE config, not merely the newest arm: runs are sorted newest-first, so a plain
# "first released-capital live run" picks whichever ablation fired last (it was showing the LV=2 arm).
_ABL = ('diag', 'ctrl', 'stack', 'lv2', 'ablat', 'sweep')
def _ok(r):
return (r.get("live_policy_fidelity") and _released(r) and not r.get("legacy")
and not any(t in r.get('run_id', '').lower() for t in _ABL))
base = next((r for r in runs if _ok(r) and 'baseline' in r.get('run_id', '').lower()), None) \
or next((r for r in runs if _ok(r) and 'livepolicy' in r.get('run_id', '')), None) \
or next((r for r in runs if _ok(r)), None)
if base is None:
base = next((r for r in runs if 'livepolicy' in r.get('run_id', '')
or 'baseline' in r.get('run_id', '').lower()), (runs[0] if runs else {}))
starved = bool(base) and not _released(base)
bh = base.get("headline") or {}
ret, mdd = bh.get("return_pct", bh.get("ret_total_pct")), bh.get("mdd_pct")
if isinstance(ret, (int, float)) and ret < -2: verdict, vc, glyph = "Edge negative — no deployable champion", C['red'], "■"
elif isinstance(ret, (int, float)) and ret < 2: verdict, vc, glyph = "Marginal — not deployable", C['amber'], "▲"
elif isinstance(ret, (int, float)): verdict, vc, glyph = "Positive edge", C['green'], "●"
else: verdict, vc, glyph = "No baseline yet", C['muted'], "·"
_hret = lambda r: (r.get("headline") or {}).get("return_pct", (r.get("headline") or {}).get("ret_total_pct"))
# "best honest run" must ALSO have released capital — otherwise a pre-fix, capital-starved cell gets promoted
# as the benchmark (it was showing mm_flow_skew_m02 +6.55%, a run whose sim never returned collateral).
live = [r for r in runs if r.get("live_policy_fidelity") and _released(r) and 'diag' not in r.get('run_id', '')]
best = max((r for r in live if isinstance(_hret(r), (int, float))), key=_hret, default=None)
bench = ""
if best is not None and best.get("run_id") != base.get("run_id"):
bench = (f" · best honest run {html.escape(str(best['run_id']))} "
f"0 else C['red']}'>"
f"{_mmb_num(_hret(best),'%+')}")
return (f"
⚠ this baseline predates the capital-release fix — its sim never "
f"returned collateral at resolution, so the number is capital-starved
" if starved else "")
+ f"
"
f"{len(runs)} runs tracked · every backtest auto-publishes here{bench}
")
def mmb_refresh(module):
st = load_status(module) or {}
return mmb_header(st), mmb_list_html(st)
# ── MM SHADOW (kind="mm") — the two-sided maker shadow (the ACTIVE live system since Jul-15) ──
def _mm_chip(key, val, sub="", bar=""):
return (f"
{key}
{val}
"
+ (f"
{sub}
" if sub else "") + bar + "
")
def mm_header(st):
ts = st.get("beat_ts"); s = time.time() - float(ts) if ts else 9e9
beat_c = C["green"] if s < 300 else C["amber"] if s < 900 else C["red"]
beat_t = f"beat {int(s)}s ago" if s < 120 else f"beat {s/60:.0f}m ago" if s < 9e8 else "no beat"
headline = str(st.get("headline") or "▲ no headline — publisher degraded")
vc = C["green"] if headline.startswith("●") else C["amber"] if headline.startswith("▲") else C["red"]
if s >= 900:
headline, vc = "■ NO BEAT — truflow-dash publisher/box down", C["red"]
pills = pill(html.escape(headline), vc) + pill(beat_t, beat_c)
if st.get("kill_flag"):
pills += pill("KILL flag set", C["amber"])
if st.get("watchdog_cron") is False:
pills += pill("watchdog cron MISSING", C["red"])
f = st.get("fills") or {}; cfg = st.get("config") or {}
rg = st.get("regime") or {}; ps = st.get("port_stats") or {}
cap = cfg.get("inv_cap") or 100.0; unm = f.get("unmatched_usd")
we = st.get("wallet_eq") or {}; bank = st.get("bank") or 445.0
hero = []
if isinstance(we.get("total"), (int, float)):
dlt = we["total"] - bank
hero.append(_mm_chip("wallet equity", f"${we['total']:,.2f}",
f"cash ${we.get('cash', 0):,.0f} + marks ${we.get('marks', 0):,.0f} · {dlt:+,.0f} vs ${bank:,.0f} bank"))
else:
hero.append(_mm_chip("wallet equity", "?", "on-chain read failed"))
upnl = we.get("upnl"); ret = ps.get("ret_pct")
tilt = ps.get("avg_px_held"); tev = ps.get("top_ev_pct")
recov = ((ps.get("mrg_val") or 0) + (ps.get("red_val") or 0)) if ps else None
chips = hero + [
_mm_chip("open P&L", f"${upnl:+,.2f}" if isinstance(upnl, (int, float)) else "?",
f"{we.get('n_pos', '?')} pos" + (f" · {ret:+.0f}% on cost" if isinstance(ret, (int, float)) else "")),
_mm_chip("held tilt", f"{tilt:.2f}" if isinstance(tilt, (int, float)) else "?",
"sh-wtd cur px · <0.35 longshot-heavy",
_bar(min(1.0, (tilt or 0) / 1.0), C["amber"] if isinstance(tilt, (int, float)) and tilt < 0.35 else C["blue"]) if isinstance(tilt, (int, float)) else ""),
_mm_chip("top event", f"{tev:.0f}%" if isinstance(tev, (int, float)) else "?",
html.escape(str(ps.get("top_ev") or "concentration of marks")[:44]),
_bar(min(1.0, (tev or 0) / 100.0), C["amber"] if isinstance(tev, (int, float)) and tev > 40 else C["blue"]) if isinstance(tev, (int, float)) else ""),
_mm_chip("recoverable", f"${recov:,.0f}" if isinstance(recov, (int, float)) else "?",
f"merge ${ps.get('mrg_val', 0)} + redeem ${ps.get('red_val', 0)} → cash"),
_mm_chip("fills", f.get("n", "?"), f"${f.get('gross_usd', 0)} booked (ledger-true)"),
_mm_chip("boxes held", f.get("matched_pairs", "?"), f"matched pairs / {f.get('mkts_filled', 0)} mkts"),
_mm_chip("recycled", (st.get("merges") or {}).get("pairs", 0),
f"pairs merged to cash / {(st.get('merges') or {}).get('n', 0)} tx"),
_mm_chip("at-risk", f"${unm:.0f}" if isinstance(unm, (int, float)) else "?",
f"unmatched, of ${cap:.0f} cap",
_bar((unm or 0) / cap, C["amber"] if (unm or 0) > 0.7 * cap else C["blue"])),
_mm_chip("one-sided", f"{rg.get('n_onesided', '?')}/{rg.get('n_scored', '?')}",
"mkts vp≥0.8 → widened (RVP)"),
_mm_chip("champion", html.escape(str(st.get("champion") or "?")))]
return (f"
{pills}
"
f"
{''.join(chips)}
")
def mm_body_html(st):
cfg = st.get("config") or {}; mk = st.get("markets") or {}
rows = [("session file", st.get("session")), ("session hours", st.get("session_h")),
("markets quoted", mk.get("n")), ("pid", st.get("pid")),
("watchdog cron", st.get("watchdog_cron")), ("kill flag", st.get("kill_flag")),
("config", ", ".join(f"{k}={v}" for k, v in cfg.items())),
("selection funnel", json.dumps(mk.get("funnel")) if mk.get("funnel") else None),
("cap hits (session)", json.dumps(st.get("cap_hits")) if st.get("cap_hits") else "none"),
("venue-side cancels (order_gone)", st.get("order_gone")),
("errors", json.dumps(st.get("errors")) if st.get("errors") else "none"),
("depth range", f"{(st.get('regime') or {}).get('depth_min')} – {(st.get('regime') or {}).get('depth_max')}"),
("note", st.get("note"))]
body = "".join(f"
{html.escape(str(k))}"
f" — {html.escape(str(v))}
" for k, v in rows if v is not None)
return f"
{body}
"
def mm_glossary_html():
items = [("champion", "twosided-v36-dctrl-rvp on the WS-driven poster (Jul-22): 5c two-sided ladders, "
"reactive depth (DC=0.01) + tape one-sidedness widening (RVP=2), event-driven ~2s "
"requotes. $445 bank, 2% per-market caps ($8.90) — backtest +39.7%/10mo, MDD −5.1%."),
("boxes", "matched YES+NO pairs — locked $1 payout at resolution; the profit engine."),
("at-risk", "UNMATCHED share cost only (INV_CAP_MODE=net, Jul-20): matched boxes are locked value; "
"the $100 cap bounds the one-sided residual, a $400 gross backstop protects cash."),
("fills ledger-true", "BOOK_SETTLE: fills booked from the CLOB trade ledger per order id — an order "
"vanishing (e.g. the venue's gameStart mass-cancel) is NOT a fill."),
("one-sided / vp", "trailing 600s tape one-sidedness |Σusd·yf|/Σusd; vp≥0.8 → the RVP lever widens "
"that market's quotes (target ×clip(1−2(vp−0.5)))."),
("open P&L", "wallet mark-to-market of open positions (Data-API); resolution redemptions realize it."),
("Portfolio tab", "the ACTUAL wallet book — every position (incl. pre-session + dust), basis→mark, "
"per-position P&L, and flags. Book tab = this session's fills only; Portfolio = truth."),
("held tilt", "share-weighted CURRENT price of the held side. <~0.35 = longshot-heavy book (wrong side "
"of the favorite-longshot bias) → skew quotes toward favorites / stop adding cheap legs."),
("top event", "largest single EVENT's share of position marks — same-event legs are correlated, so a "
"big share = concentrated resolution risk → cap/skew that bucket."),
("recoverable", "value one action turns into cash: MERGE matched YES+NO pairs + REDEEM resolved "
"winners. Non-zero = idle capital sitting on the table."),
("watchdog", "cron */15 relaunches the poster on crash/24h boundary; KILL flag = owner stop.")]
return "
" + "".join(
f"
{html.escape(k)} — {html.escape(v)}
" for k, v in items) + "
"
def _mm_pnl_td(v, pct=None):
if not isinstance(v, (int, float)):
return "
—
"
col = C["green"] if v > 0.005 else C["red"] if v < -0.005 else C["muted"]
sfx = f" ({pct:+.0f}%)" if isinstance(pct, (int, float)) else ""
return f"
${v:+,.2f}{sfx}
"
def mm_portfolio_html(st):
"""★ Jul-22 (owner /goal): the ACTUAL portfolio — every wallet position with basis→mark and P&L."""
rows = st.get("positions")
if rows is None:
return (f"
▲ portfolio read FAILED this beat — "
f"Data-API unreachable from the box; positions unknown (wallet marks may also be stale).
")
if not rows:
return f"
No open positions — book is all cash.
"
def _flags(r):
fl = []
if r.get("red"): fl.append(f"redeem")
if r.get("mrg"): fl.append(f"merge")
if r.get("dust"): fl.append(f"dust")
if r.get("nr"): fl.append(f"negR")
return " ".join(fl)
def _px(r):
a, c = r.get("avg"), r.get("cur")
if not (isinstance(a, (int, float)) and isinstance(c, (int, float))):
return "—"
arrow_c = C["green"] if c > a else C["red"] if c < a else C["muted"]
return f"{a:.2f}→{c:.2f}"
body = "".join(
f"
{html.escape(str(r.get('t') or ''))}"
f" · {html.escape(str(r.get('oc') or ''))}
"
f"
{r.get('sh')}
{_px(r)}
"
f"
${r.get('val', 0):,.2f}
{_mm_pnl_td(r.get('pnl'), r.get('pct'))}"
f"
{_flags(r)}
{html.escape(str(r.get('end') or ''))}
"
for r in rows)
tot_v = sum(r.get("val") or 0 for r in rows); tot_p = sum(r.get("pnl") or 0 for r in rows)
ret = (st.get("port_stats") or {}).get("ret_pct")
foot = (f"