fsanyoto's picture
MM-BACKTESTS: badge capital-starved runs IN THE LIST, not only in the drawer
69f882b verified
Raw
History Blame Contribute Delete
112 kB
"""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"<span class='tip'>{html.escape(str(label))}<span class='pb-i'>i</span>"
f"<span class='tt'>{t}</span></span>")
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"<span class='pb-pill' style='background:{color}'>{txt}</span>"
def stat(key, val):
return (f"<div class='pb-stat'><div class='k'>{tip(key)}</div><div class='v'>{val}</div></div>")
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"<div class='pb-bar' style='{ws}'><i style='width:{f*100:.0f}%;background:{color}'></i></div>"
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"<div class='pb-stat'><div class='k'>{tip(key)}</div><div class='v'>{val}</div>"
+ (f"<div class='sub'>{sub}</div>" if sub else "") + bar + "</div>")
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"<div class='pb-card' style='margin-top:10px;color:{C['muted']};font-size:12px'>"
"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 <b>MM</b> tab.</div>")
return (f"<div class='pb-card'>{tip('health', 'health')} &nbsp; {pills}</div>"
f"<div class='pb-row' style='margin-top:10px'>{''.join(chips)}</div>{note}")
def _badge_event(ev):
# soft tinted badges (light bg + saturated ink) β€” reads clean on the light ground, no inky chips
tint = {"would_enter": ("#E6F2EA", C["green"]), "gate_block": ("#EFEDE7", C["muted"]),
"gate_block_adv": ("#FBF1DE", C["amber"]), "gate_unavailable_block": ("#F7E4E0", C["red"]),
"maturity_skip": ("#EFEBF7", C["purple"])}.get(ev, ("#EFEDE7", C["muted"]))
return (f"<span class='pb-badge' style='background:{tint[0]};color:{tint[1]}'>"
f"{html.escape(str(ev))}</span>")
def feed_html(st):
evs = st.get("recent_events", [])[::-1]
if not evs:
return "<div class='pb-card'>No scored dislocations yet under the current session β€” the tape hasn't produced a β‰₯5% move.</div>"
# owner Jul-7: the round-7 "legacy pred ret" column is DELETED forever (dead era, dead column)
heads = [("time", "beat"), ("decision", "gate_block"), ("market", "dislocation"),
("P_rev", "P_rev"), ("P_adv", "P_adv"), ("w", "w"),
("move", "move"), ("buy", "buy"), ("hrs left", "hrs_to_res")]
th = "".join(f"<th>{tip(lbl, key)}</th>" 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"<span style='color:{C['border']}'>β€”</span>"
# 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("<tr>"
f"<td>{html.escape((e.get('t') or '')[:19].replace('T', ' '))}</td>"
f"<td>{_badge_event(e.get('event'))}</td>"
f"<td style='max-width:260px;overflow:hidden;text-overflow:ellipsis' title=\"{html.escape(e.get('market') or e.get('cond') or '')}\">{html.escape(str(mkt_name)[:56])}</td>"
f"<td>{f(p_rev)}</td><td>{f(e.get('p_adv'))}</td><td>{f(e.get('gate_w'), '{:.2f}Γ—')}</td>"
f"<td>{f(e.get('move'), '{:+.3f}')}</td>"
f"<td>{f(e.get('buy'))}</td><td>{f(e.get('hrs_to_res'), '{:.1f}h')}</td></tr>")
return f"<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>{th}</tr>{''.join(rows)}</table></div>"
# ── 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"<span style='color:{C['border']}'>β€”</span>"
col = C["green"] if x > 0 else C["red"] if x < 0 else C["muted"]
return f"<span style='color:{col};font-weight:600'>${fmt.format(x)}</span>"
def _pnl_pct(x):
return (f"<span style='color:{C['green'] if x > 0 else C['red'] if x < 0 else C['muted']}'>{x:+.1f}%</span>"
if isinstance(x, (int, float)) else "β€”")
def _softbadge(text, bg, fg, title=""):
ti = f" title=\"{html.escape(title)}\"" if title else ""
return f"<span class='pb-badge' style='background:{bg};color:{fg}'{ti}>{html.escape(str(text))}</span>"
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 "<div class='pb-card'>No open positions β€” the bot holds nothing on the venue right now.</div>"
th = "".join(f"<th>{h}</th>" 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 ("<tr>"
f"<td style='max-width:320px;overflow:hidden;text-overflow:ellipsis' title=\"{html.escape(p.get('title') or '')}\">{html.escape((p.get('title') or (p.get('cond') or '')[:12])[:70])}</td>"
f"<td>{html.escape(str(p.get('outcome') or 'β€”'))}</td><td>{f(p.get('shares'), '{:.2f}')}</td>"
f"<td>{f(p.get('avg_px'))}</td><td>{f(p.get('cur_px'))}</td><td>${f(p.get('value'), '{:.2f}')}</td>"
f"<td>{_money(p.get('pnl'))}</td><td>{_pnl_pct(p.get('pnl_pct'))}</td><td>{tag}</td></tr>")
# 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"<tr><td colspan='9' style='background:{C['card2']};color:{C['muted']};font-size:12px;"
f"padding:7px 9px;border-top:1px solid {C['border']}'>"
f"<b style='color:{C['text']}'>{_model_short(m)}</b>{star}"
f" Β· {len(groups[m])} position(s) Β· value ${gv:,.2f} Β· unreal {_money(gp)}</td></tr>")
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"<div style='color:{C['muted']};font-size:12.5px;margin:8px 2px'>{len(ps)} position(s) Β· "
f"value ${tot_v:,.2f} Β· unreal {_money(tot_p)}</div>")
return f"<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>{th}</tr>{''.join(parts)}</table>{foot}</div>"
def trades_html(st):
tr = st.get("trades", [])
if not tr:
return ("<div class='pb-card'>No entry→exit round-trips in the fetched window yet. Scored-but-refused "
"dislocations show in the Live feed; raw money-path lines in Log.</div>")
th = "".join(f"<th>{h}</th>" for h in
["in (UTC)", "out (UTC)", "market", "side", tip("status"), tip("bought/sold"),
"entry vwap", "exit vwap", tip("realized $"), tip("unreal $"), tip("total $"),
tip("r %", "ret split"), tip("u %", "ret split"), tip("t %", "ret split"),
tip("P_rev"), tip("P_adv"), tip("w"), tip("pred edge")])
tint = {"closed": ("#EFEDE7", C["muted"]), "open": ("#E6F2EA", C["green"]),
"partial": ("#FBF1DE", C["amber"]), "rolled": ("#EAF0F6", C["blue"]),
"sell-only": ("#EFEBF7", C["purple"])}
def _row(t):
def f(x, fmt="{:.3f}"): return fmt.format(x) if isinstance(x, (int, float)) else "β€”"
stat = t.get("status")
bg, fg = tint.get(stat, ("#EFEDE7", C["muted"]))
sh_note = ""
if isinstance(t.get("carry_sh"), (int, float)):
sh_note += (f"<span style='color:{C['muted']};font-size:10.5px' title='shares carried in from the previous "
f"model episode at its cost basis'> ({t['carry_sh']:.0f} carried)</span>")
if isinstance(t.get("dust_fwd"), (int, float)):
sh_note += (f"<span style='color:{C['muted']};font-size:10.5px' title='sub-venue-min residual carried "
f"forward into the next model episode'> ({t['dust_fwd']:.0f} fwd)</span>")
if stat in ("partial", "open"):
_held = round((t.get("sh_in") or 0) - (t.get("sh_out") or 0), 1)
if _held > 0:
sh_note += f"<span style='color:{C['muted']};font-size:10.5px'> Β· holds {_held:g}</span>"
return ("<tr>"
f"<td>{html.escape(t.get('entry_t') or 'β€”')}</td><td>{html.escape(t.get('exit_t') or 'β€”')}</td>"
f"<td style='max-width:280px;overflow:hidden;text-overflow:ellipsis' title=\"{html.escape(t.get('market') or '')}\">{html.escape((t.get('market') or (t.get('cond') or '')[:12])[:60])}</td>"
f"<td>{html.escape(str(t.get('outcome') or 'β€”'))}</td>"
f"<td>{_softbadge(stat, bg, fg)}"
+ (f"<span style='color:{C['red']};font-size:10px;font-weight:600' title='held to binary resolution and lost (never scalped out) β€” a full loss invisible to round-trip win-rate'> ‡ resolution</span>" if t.get('resolved') else "")
+ "</td>"
f"<td>{f(t.get('sh_in'), '{:.1f}')}/{f(t.get('sh_out'), '{:.1f}')}{sh_note}</td>"
f"<td>{f(t.get('entry_vwap'))}</td><td>{f(t.get('exit_vwap'))}</td>"
f"<td>{_money(t.get('pnl'))}</td><td>{_money(t.get('pnl_u'))}</td><td>{_money(t.get('pnl_t'))}</td>"
f"<td>{_pnl_pct(t.get('ret_r'))}</td><td>{_pnl_pct(t.get('ret_u'))}</td><td>{_pnl_pct(t.get('ret_t'))}</td>"
f"<td>{f(t.get('p_rev'))}</td><td>{f(t.get('p_adv'))}</td><td>{f(t.get('w'), '{:.2f}Γ—')}</td>"
f"<td>{f(t.get('pred_edge'))}</td></tr>")
# 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"<tr><td colspan='18' style='background:{C['card2']};color:{C['muted']};font-size:12px;"
f"padding:7px 9px;border-top:1px solid {C['border']}'>"
f"<b style='color:{C['text']}'>{_model_short(m)}</b>{star}"
f" Β· {len(g)} episode(s) Β· closed {len(cl)} Β· realized {_money(gp)}"
+ (f" Β· WR {gwr:.0f}%" if gwr is not None else "") + "</td></tr>")
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}% <span style='color:{C['muted']}'>|62% bt</span>"
if wr is not None else "")
foot = (f"<div style='color:{C['muted']};font-size:12.5px;margin:8px 2px'>closed {len(closed)} Β· "
f"realized {_money(tot)} Β· unreal {_money(tot_u)} Β· total {_money(round(tot + tot_u, 2))}{wr_txt}</div>")
# ── 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"<div class='pb-card' style='border-left:3px solid {C['red']};margin-bottom:10px'>"
f"<b style='color:{C['red']}'>β–  {len(_res)} trade(s) rode to resolution: {_money(_rp)}{_share}</b>"
f"<div style='color:{C['muted']};font-size:12px;margin-top:3px'>Positions that never scalped out and "
f"resolved to $0 β€” a full loss that round-trip win-rate can't see. The <b style='color:{C['red']}'>‡ resolution</b> "
f"rows below. Fix: the round-13 relabel / no-hold-into-resolution.</div></div>")
else:
head = (f"<div class='pb-card' style='margin-bottom:10px'><b style='color:{C['green']}'>● No hold-to-resolution "
f"losses</b> <span style='color:{C['muted']};font-size:12px'>β€” every position scalped out before its "
f"market resolved.</span></div>")
return f"{head}<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>{th}</tr>{''.join(parts)}</table>{foot}</div>"
def log_html(st):
tl = st.get("recent_trade_lines", [])[::-1]
if not tl:
return "<div class='pb-card'>No money-path log lines in the recent window.</div>"
body = "".join(f"<div style='font-family:monospace;font-size:12.5px;padding:4px 0;border-bottom:1px solid "
f"{C['card2']}'>{html.escape(l)}</div>" for l in tl)
return f"<div class='pb-card'>{body}</div>"
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"<tr><td style='width:280px'>{tip(k)}</td><td>{v}</td></tr>")
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"<div class='pb-card'><table class='pb-tbl'>{''.join(rows)}</table></div>", fig
def glossary_html():
body = "".join(f"<tr><td style='width:200px;font-weight:600'>{html.escape(k)}</td>"
f"<td style='white-space:normal'>{html.escape(v)}</td></tr>" for k, v in G.items())
return f"<div class='pb-card'><table class='pb-tbl'>{body}</table></div>"
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 "<div class='pb-card'>No model payload in this beat yet.</div>"
parts = []
if ms:
th = "".join(f"<th>{h}</th>" for h in
["window", "version", "trips", "realized $", tip("net edge", "net edge")])
rws = ""
for r in ms:
part = (f" <span style='color:{C['muted']};font-size:10.5px'>(partial)</span>"
if r.get("partial") else "")
rws += ("<tr>"
f"<td>{html.escape(str(r.get('window') or ''))}{part}</td>"
f"<td style='color:{C['muted']};font-size:12px'>{_model_short(r.get('version'))}</td>"
f"<td>{r.get('n', 0)}</td><td>{_money(r.get('pnl'))}</td>"
f"<td>{_pnl_pct(r.get('net_edge_pct'))}</td></tr>")
parts.append(f"<div class='pb-card' style='overflow-x:auto;margin-bottom:12px'>"
f"<table class='pb-tbl'><tr>{th}</tr>{rws}</table></div>")
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"<div style='display:flex;align-items:center;gap:8px;padding:2px 0'>"
f"<span style='font-family:monospace;font-size:11.5px;width:150px;overflow:hidden;"
f"text-overflow:ellipsis' title='{html.escape(str(k))}'>{html.escape(str(k))}</span>"
f"<div class='pb-bar' style='flex:1;margin-top:0'><i style='width:{100*v/mx:.0f}%;background:{color}'></i></div>"
f"<span style='font-family:monospace;font-size:11px;color:{C['muted']};width:44px;"
f"text-align:right'>{v:.1f}%</span></div>" for k, v in pairs)
return (f"<div style='flex:1;min-width:260px'><div style='font-size:11px;text-transform:uppercase;"
f"letter-spacing:.4px;color:{C['muted']};margin-bottom:5px'>{title}</div>{rws}</div>")
parts.append(f"<div class='pb-card' style='margin-bottom:12px'><div style='margin-bottom:8px'>"
f"{tip('gain importance')} <span style='color:{C['muted']};font-size:11.5px'>"
f"{html.escape(str(fi.get('version') or ''))} Β· {fi.get('n_feats', '?')} feats</span></div>"
f"<div style='display:flex;gap:22px;flex-wrap:wrap'>"
f"{_head_col('rev', 'P_rev head', C['blue'])}{_head_col('adv', 'P_adv head', C['amber'])}</div></div>")
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"<div style='font-size:12.5px;margin-bottom:3px'><b>{html.escape(str(nm))}</b>"
f" <span style='color:{C['muted']};font-family:monospace;font-size:11px'>"
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'))}</span></div>")
def _c(hk):
cs = sg.get("contrib_" + hk) or []
if not cs:
return ""
inner = " ".join(
f"<span style='font-family:monospace;font-size:10.5px;"
f"color:{C['green'] if (cc or 0) > 0 else C['red']}'>{html.escape(str(k))} {cc:+.3f}</span>"
for k, v, cc in cs[:6] if isinstance(cc, (int, float)))
return (f"<div style='margin:1px 0'><span style='color:{C['muted']};font-size:10.5px;"
f"font-family:monospace'>{hk}</span> {inner}</div>")
blocks += f"<div style='padding:7px 0;border-bottom:1px solid {C['card2']}'>{head}{_c('rev')}{_c('adv')}</div>"
parts.append(f"<div class='pb-card'><div style='margin-bottom:6px'>{tip('contribs')}</div>{blocks}</div>")
if fi.get("error"):
parts.append(f"<div class='pb-card' style='color:{C['red']};font-size:12.5px'>"
f"importance error: {html.escape(str(fi['error']))}</div>")
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/<mod>.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 ("<div class='pb-card'>No revalidation beat published yet β€” auto-ops writes "
"<code>integrity/truflow.json</code> every 2h (first beat lands on its next firing).</div>")
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"<tr><td style='width:300px'>{html.escape(k)}</td><td>{v}</td></tr>")
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"<div class='pb-card'><div style='margin-bottom:8px'>{head}</div>"
f"<table class='pb-tbl'>{''.join(rows)}</table></div>")
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"<div style='margin-top:16px'><div style='font-size:11px;text-transform:uppercase;letter-spacing:.4px;"
f"color:{accent or C['muted']};{'font-weight:700;' if accent else ''}margin-bottom:6px'>{t}</div>"
f"<div style='font-size:14px;line-height:1.6'>{body}</div></div>")
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"<div style='padding:2px 0'><span style='color:{C['muted']}'>"
f"{html.escape(str(k).replace('_', ' '))}</span> β€” "
f"<b style='font-variant-numeric:tabular-nums'>{_fmt_pv(v)}</b></div>" 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"<div style='display:flex;justify-content:space-between;gap:10px;padding:4px 9px;"
f"background:{C['card2']};border-radius:7px;font-size:11.5px'>"
f"<span style='color:{C['muted']}'>{html.escape(str(k))}</span>"
f"<b style='font-variant-numeric:tabular-nums;color:{C['text']}'>{_mmb_num(v, _MMB_UNITS.get(k, ''))}</b></div>")
return f"<div style='display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:6px'>{''.join(items)}</div>"
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"<div style='color:{C['muted']};font-size:12px;padding:8px 0'>no series β€” legacy run, re-run for charts</div>"
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"<line x1='0' y1='{zy}' x2='{w}' y2='{zy}' stroke='{C['border']}' stroke-width='1' "
f"stroke-dasharray='4 4' vector-effect='non-scaling-stroke'/>")
last = vals[-1]
_fu = {"%": "%+", "n": "n"}.get(unit, "$")
fmt = (lambda x: _mmb_num(x, _fu))
return (
f"<div style='position:relative'>"
f"<svg viewBox='0 0 {int(w)} {h}' preserveAspectRatio='none' role='img' "
f"style='width:100%;height:{h}px;display:block;overflow:visible'>"
f"<title>{len(vals)} points Β· min {fmt(lo)} Β· max {fmt(hi)} Β· last {fmt(last)}</title>"
f"{z}<polygon points='{area}' fill='{color}' opacity='0.09'/>"
f"<polyline points='{pts}' fill='none' stroke='{color}' stroke-width='2' stroke-linejoin='round' "
f"stroke-linecap='round' vector-effect='non-scaling-stroke'/></svg>"
f"<div style='display:flex;justify-content:space-between;font-size:10.5px;color:{C['muted']};"
f"margin-top:3px;font-variant-numeric:tabular-nums'>"
f"<span>min {fmt(lo)}</span><span>max {fmt(hi)}</span>"
f"<span style='color:{color};font-weight:700'>last {fmt(last)}</span></div></div>")
def _mmb_chart(title, vals, color, unit="$", zeroline=False):
return (f"<div style='margin-top:14px'>"
f"<div style='font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:{C['muted']};"
f"margin-bottom:5px'>{title}</div>{_mmb_svg(vals, color, unit, zeroline=zeroline)}</div>")
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"<div style='display:flex;gap:22px;align-items:baseline;flex-wrap:wrap;margin:10px 0 4px'>"
f"<div><div style='font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;color:{C['muted']}'>Return</div>"
f"<div style='font-size:30px;font-weight:740;line-height:1.1;color:{rc};font-variant-numeric:tabular-nums'>"
f"{_mmb_num(ret,'%+')}</div></div>"
f"<div><div style='font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;color:{C['muted']}'>Max drawdown</div>"
f"<div style='font-size:22px;font-weight:700;line-height:1.1;color:{C['text']};font-variant-numeric:tabular-nums'>"
f"{_mmb_num(mdd,'%+')}</div></div>"
f"<div><div style='font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;color:{C['muted']}'>Stress MDD</div>"
f"<div style='font-size:22px;font-weight:700;line-height:1.1;color:{C['muted']};font-variant-numeric:tabular-nums'>"
f"{_mmb_num(m.get('mdd_stress_pct'),'%+')}</div></div></div>")
# 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"<div style='font-size:11px;color:{C['muted']};margin:-2px 0 6px'>{html.escape(_txt)}</div>")
# β˜… 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"<div style='margin:2px 0 8px;padding:8px 11px;border:1px solid {C['red']};border-radius:9px;"
f"font-size:11.5px;color:{C['red']}'>β›” HALTED by the equity floor after "
f"<b>{_mmb_num(d2h,'n')} days</b>"
+ (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.</div>")
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"<div style='padding:7px 10px;background:{C['card2']};border-radius:9px'>"
f"<div style='font-size:9.5px;text-transform:uppercase;letter-spacing:.35px;color:{C['muted']}'>{lab}</div>"
f"<div style='font-size:15px;font-weight:670;font-variant-numeric:tabular-nums;color:{col};"
f"margin-top:1px'>{_mmb_num(v, unit)}</div></div>")
mt, tot = m.get("markets_touched"), m.get("markets_total")
cells.append(f"<div style='padding:7px 10px;background:{C['card2']};border-radius:9px'>"
f"<div style='font-size:9.5px;text-transform:uppercase;letter-spacing:.35px;color:{C['muted']}'>Markets traded</div>"
f"<div style='font-size:15px;font-weight:670;font-variant-numeric:tabular-nums;margin-top:1px'>"
f"{_mmb_num(mt,'n')}<span style='color:{C['muted']};font-weight:500'> / {_mmb_num(tot,'n')}</span></div></div>")
grid = (f"<div style='display:grid;grid-template-columns:repeat(auto-fit,minmax(124px,1fr));gap:7px;"
f"margin-top:8px'>{''.join(cells)}</div>")
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"<span style='position:absolute;top:0;bottom:0;background:{sc};border-radius:3px;"
+ (f"left:50%;width:{half:.1f}%" if pv >= 0 else f"right:50%;width:{half:.1f}%") + ";'></span>")
rows.append(
f"<div style='display:grid;grid-template-columns:minmax(96px,132px) 1fr minmax(104px,132px);"
f"align-items:center;gap:10px;margin:6px 0'>"
f"<div style='font-size:12px;color:{C['muted']}'>{lab}</div>"
f"<div style='position:relative;height:15px;background:{C['card2']};border-radius:4px'>"
f"<span style='position:absolute;left:50%;top:-2px;bottom:-2px;width:1px;background:{C['border']}'></span>{bar}</div>"
f"<div style='text-align:right;font-size:12.5px;font-weight:660;color:{sc};font-variant-numeric:tabular-nums'>"
f"{_mmb_num(pv,'%+')} <span style='color:{C['muted']};font-weight:500'>{_mmb_num(uv,'$+')}</span></div></div>")
tot = ed.get("total_pct")
ok = ed.get("reconciled")
chip = ""
if ok is True:
chip = (f"<span style='font-size:10px;font-weight:700;color:{C['green']};border:1px solid {C['green']};"
f"border-radius:5px;padding:1px 6px;margin-left:7px'>βœ“ RECONCILES</span>")
elif ok is False:
chip = (f"<span style='font-size:10px;font-weight:700;color:{C['red']};border:1px solid {C['red']};"
f"border-radius:5px;padding:1px 6px;margin-left:7px'>⚠ MISMATCH {_mmb_num(ed.get('reconcile_gap_pct'),'%+')}</span>")
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"<div style='margin-top:9px;padding-top:8px;border-top:1px solid {C['card2']};font-size:13px'>"
f"Total <b style='color:{C['green'] if isinstance(tot,(int,float)) and tot>0 else C['red']};"
f"font-variant-numeric:tabular-nums'>{_mmb_num(tot,'%+')}</b>{chip}</div>"
+ (f"<div style='font-size:10.5px;color:{C['muted']};margin-top:4px'>{html.escape(str(note))}</div>" 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"<div style='font-size:12px;color:{C['muted']};margin-bottom:2px'>"
f"<b style='color:{C['red'] if idx and dead > len(idx) * 0.5 else C['text']}'>{dead:,}</b> of "
f"{len(idx):,} <b>quoting</b> days had markets live but <b>ZERO fills</b>"
+ (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</div>")
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"<div style='margin-top:12px;padding:9px 11px;border:1px solid {C['red']};border-radius:9px;"
f"font-size:11.5px;color:{C['red']}'>⚠ 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.</div>")
chips = {"settled": rv.get("n_settled"), "of markets": rv.get("n_markets"),
"released": rv.get("released_usd"), "settle P&L": rv.get("settle_pnl_usd"),
"endDate known": rv.get("n_end_ts_known"), "lag": rv.get("lag_s")}
items = "".join(f"<div style='display:flex;justify-content:space-between;gap:10px;padding:4px 9px;"
f"background:{C['card2']};border-radius:7px;font-size:11.5px'>"
f"<span style='color:{C['muted']}'>{html.escape(k)}</span>"
f"<b style='font-variant-numeric:tabular-nums'>"
f"{_mmb_num(v, '$' if 'releas' in k else ('$+' if 'P&L' in k else ('s' if k=='lag' else 'n')))}</b></div>"
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"<div style='display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:6px'>{items}</div>"
f"<div style='font-size:10.5px;color:{C['muted']};margin-top:5px'>{note}</div>", 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"<div style='font-size:12px;color:{C['muted']};margin-bottom:6px'>"
f"{html.escape(str(win[0] if win else 'β€”'))} β†’ {html.escape(str(win[1] if len(win) > 1 else 'β€”'))} Β· "
f"<b style='color:{C['text']}'>{_mmb_num(cv.get('markets_traded'),'n')}</b> traded / "
f"{_mmb_num(cv.get('markets_in_sim'),'n')} simulated / {_mmb_num(cv.get('cids_requested'),'n')} requested</div>")
drops = {"no tape": cv.get("dropped_no_tape"), "no books": cv.get("dropped_no_books"),
"no valid prints": cv.get("dropped_no_valid_prints"),
"book day-files": cv.get("book_dayfiles_total"), "median day-files/mkt": cv.get("book_dayfiles_per_market_median"),
"prints": cv.get("prints")}
chips = "".join(f"<div style='display:flex;justify-content:space-between;gap:10px;padding:4px 9px;"
f"background:{C['card2']};border-radius:7px;font-size:11.5px'>"
f"<span style='color:{C['muted']}'>{html.escape(k)}</span>"
f"<b style='font-variant-numeric:tabular-nums'>{_mmb_num(v,'n')}</b></div>"
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"<div style='display:grid;grid-template-columns:1fr 74px 74px 90px;gap:8px;font-size:11.5px;"
f"padding:3px 0;border-top:1px solid {C['card2']};font-variant-numeric:tabular-nums'>"
f"<span>{html.escape(str(cat))}</span><span style='text-align:right'>{_mmb_num(r.get('markets'),'n')}</span>"
f"<span style='text-align:right;color:{C['green']}'>{_mmb_num(r.get('traded'),'n')}</span>"
f"<span style='text-align:right;color:{C['muted']}'>{_mmb_num(r.get('book_dayfiles'),'n')}</span></div>")
if rows:
rows = (f"<div style='margin-top:9px'><div style='display:grid;grid-template-columns:1fr 74px 74px 90px;gap:8px;"
f"font-size:9.5px;text-transform:uppercase;letter-spacing:.35px;color:{C['muted']}'>"
f"<span>category</span><span style='text-align:right'>mkts</span>"
f"<span style='text-align:right'>traded</span><span style='text-align:right'>book days</span></div>{rows}</div>")
sp = cv.get("sports_note")
spn = (f"<div style='font-size:10.5px;color:{C['amber']};margin-top:6px'>⚠ {html.escape(str(sp))}</div>") if sp else ""
return _sec("Market coverage",
top + f"<div style='display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:6px'>{chips}</div>"
+ rows + spn, accent=C['blue'])
def mmb_cell_html(c):
m = c.get("metrics") or {}; s = c.get("series") or None
out = (f"<div style='margin-top:16px;padding:14px 16px;background:{C['card']};border:1px solid {C['border']};"
f"border-radius:12px'>")
out += (f"<div style='font-size:12px;font-weight:700;letter-spacing:.3px;color:{C['muted']};"
f"text-transform:uppercase'>{html.escape(str(c.get('label','cell')))}</div>")
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"<div style='font-size:10px;color:{C['muted']};margin-top:4px'>series sampled TIME-uniformly "
f"(the old index-uniform sampling hid sparse months)</div>")
else:
out += (f"<div style='margin-top:12px;font-size:12px;color:{C['muted']}'>Legacy run β€” metrics only. "
f"Re-run to get equity / inventory / drawdown charts.</div>")
out += _mmb_activity_html(c.get("activity"), m)
out += _mmb_coverage_html(c.get("coverage"))
return out + "</div>"
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"<span class='mmb-tier' style='color:{C['red']};border-color:{C['red']}' "
f"title='capital was NEVER released at resolution in this run - the number is capital-starved'>"
f"$0</span>") if starved else ""
charted = any(c.get("series") for c in (r.get("cells") or []))
ch = "" if charted else (f"<span class='mmb-tier' style='color:{C['muted']};border-color:{C['border']}' "
f"title='legacy run β€” metrics only'>β—·</span>")
return (f"<label class='mmb-row' for='mmb-{i}'>"
f"<span class='mmb-dot' style='background:{dotc}'></span>"
f"<span class='mmb-tier' style='color:{fc};border-color:{fc}'>{fid}</span>{st}{ch}"
f"<span class='mmb-q' title='{html.escape(str(r.get('run_id','')))}'>{html.escape(str(r.get('run_id','')))}</span>"
f"<span class='mmb-p' style='color:{retc}'>{_mmb_num(ret,'%+')}</span>"
f"<span class='mmb-mkt'>MDD {_mmb_num(mdd,'%+')}</span>"
f"<span class='mmb-when'>{html.escape(str(r.get('when','β€”')))}</span></label>")
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"<li style='margin:2px 0'>{html.escape(str(x))}</li>" 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"<div class='mmb-detail' data-i='{i}'>"
f"<label class='mmb-x' for='mmb-close'>Γ—</label>"
f"<div style='font-family:monospace;font-size:18px;font-weight:720;letter-spacing:-.2px;"
f"word-break:break-all;padding-right:44px'>{html.escape(str(r.get('run_id','')))}</div>"
f"<div style='display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap'>"
f"<span style='font-size:9.5px;font-weight:700;letter-spacing:.4px;color:{fc};border:1px solid {fc};"
f"border-radius:5px;padding:2px 7px'>{fid}</span>"
f"<span style='color:{C['muted']};font-size:11.5px'>{meta}</span></div>"
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"<ul style='margin:0;padding-left:18px;font-size:11.5px;color:{C['muted']}'>{blk}</ul>",
accent=C['muted']) if blk else "")
+ "</div>")
def mmb_list_html(st):
runs = st.get("runs") or []
if not runs:
return "<div class='pb-card'>No MM backtests yet. Every hf_mm_portfolio.py run publishes here automatically.</div>"
radios = ("<input class='mmb-r' type='radio' name='mmbid' id='mmb-close' checked>"
+ "".join(f"<input class='mmb-r' type='radio' name='mmbid' id='mmb-{i}'>" for i in range(len(runs))))
style = "<style>" + "".join("#mmb-%d:checked ~ .mmb-drawer [data-i='%d']{display:block}" % (i, i) 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"<div class='mmb-drawer'><label class='mmb-scrim' for='mmb-close'></label><div class='mmb-panel'>{details}</div></div>"
n_ch = sum(1 for r in runs if any(c.get("series") for c in (r.get("cells") or [])))
head = (f"<div style='display:flex;justify-content:space-between;align-items:baseline;gap:10px;"
f"margin:0 2px 8px;font-size:11px;color:{C['muted']};flex-wrap:wrap'>"
f"<span>{len(runs)} runs Β· newest first Β· click a row for charts, risk figures &amp; edge decomposition</span>"
f"<span>{n_ch} charted Β· {len(runs)-n_ch} metrics-only</span></div>")
return style + radios + head + f"<div class='mmb-list'>{rows}</div>" + 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 <b style='color:{C['text']}'>{html.escape(str(best['run_id']))}</b> "
f"<b style='color:{C['green'] if _hret(best)>0 else C['red']}'>"
f"{_mmb_num(_hret(best),'%+')}</b>")
return (f"<div class='pb-card'>"
f"<div style='font-size:10.5px;text-transform:uppercase;letter-spacing:.45px;color:{C['muted']}'>"
f"Baseline Β· <span style='font-family:monospace;text-transform:none'>{html.escape(str(base.get('run_id','β€”')))}</span></div>"
f"<div style='display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-top:4px'>"
f"<div style='font-size:34px;font-weight:770;line-height:1.05;color:{vc};font-variant-numeric:tabular-nums'>"
f"{_mmb_num(ret,'%+')}</div>"
f"<div style='font-size:14px;font-weight:640;color:{vc}'>{glyph} {verdict}</div>"
f"<div style='font-size:12.5px;color:{C['muted']};font-variant-numeric:tabular-nums'>"
f"MDD {_mmb_num(mdd,'%+')}</div></div>"
+ (f"<div style='margin-top:7px;padding:7px 10px;border:1px solid {C['red']};border-radius:8px;"
f"font-size:11px;color:{C['red']}'>⚠ this baseline predates the capital-release fix β€” its sim never "
f"returned collateral at resolution, so the number is capital-starved</div>" if starved else "")
+ f"<div style='font-size:11.5px;color:{C['muted']};margin-top:5px'>"
f"{len(runs)} runs tracked Β· every backtest auto-publishes here{bench}</div></div>")
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"<div class='pb-stat'><div class='k'>{key}</div><div class='v'>{val}</div>"
+ (f"<div class='sub'>{sub}</div>" if sub else "") + bar + "</div>")
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"<div class='pb-card'>{pills}</div>"
f"<div class='pb-row' style='margin-top:10px'>{''.join(chips)}</div>")
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"<div style='margin:3px 0'><span style='color:{C['muted']}'>{html.escape(str(k))}</span>"
f" β€” {html.escape(str(v))}</div>" for k, v in rows if v is not None)
return f"<div class='pb-card'>{body}</div>"
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 "<div class='pb-card'>" + "".join(
f"<div style='margin:6px 0'><b>{html.escape(k)}</b> β€” {html.escape(v)}</div>" for k, v in items) + "</div>"
def _mm_pnl_td(v, pct=None):
if not isinstance(v, (int, float)):
return "<td>β€”</td>"
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"<td style='color:{col};white-space:nowrap'>${v:+,.2f}{sfx}</td>"
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"<div class='pb-card' style='color:{C['amber']}'>β–² portfolio read FAILED this beat β€” "
f"Data-API unreachable from the box; positions unknown (wallet marks may also be stale).</div>")
if not rows:
return f"<div class='pb-card' style='color:{C['muted']}'>No open positions β€” book is all cash.</div>"
def _flags(r):
fl = []
if r.get("red"): fl.append(f"<span style='color:{C['green']}'>redeem</span>")
if r.get("mrg"): fl.append(f"<span style='color:{C['blue']}'>merge</span>")
if r.get("dust"): fl.append(f"<span style='color:{C['muted']}'>dust</span>")
if r.get("nr"): fl.append(f"<span style='color:{C['muted']}'>negR</span>")
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}<span style='color:{arrow_c}'>β†’{c:.2f}</span>"
body = "".join(
f"<tr><td style='max-width:340px'>{html.escape(str(r.get('t') or ''))}"
f" <span style='color:{C['muted']}'>Β· {html.escape(str(r.get('oc') or ''))}</span></td>"
f"<td>{r.get('sh')}</td><td style='white-space:nowrap'>{_px(r)}</td>"
f"<td>${r.get('val', 0):,.2f}</td>{_mm_pnl_td(r.get('pnl'), r.get('pct'))}"
f"<td>{_flags(r)}</td><td style='color:{C['muted']};white-space:nowrap'>{html.escape(str(r.get('end') or ''))}</td></tr>"
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"<tr style='font-weight:640;border-top:1px solid {C['muted']}33'><td>Ξ£ {len(rows)} positions</td>"
f"<td></td><td></td><td>${tot_v:,.2f}</td>{_mm_pnl_td(tot_p, ret)}<td></td><td></td></tr>")
return ("<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>"
"<th>market · side</th><th>sh</th><th>px avg→cur</th><th>value</th><th>P&L</th><th>flags</th><th>ends</th></tr>"
+ body + foot + "</table>"
f"<div style='color:{C['muted']};margin-top:6px;font-size:12px'>whole wallet incl. pre-session inventory "
f"Β· marks = Data-API curPrice Β· flags: redeem = resolved, claim $ now Β· merge = YES+NO pair β†’ $1 cash Β· "
f"dust = below 15-sh venue min (unsellable) Β· negR = negative-risk event</div></div>")
def mm_fills_html(st):
rows = st.get("fills_recent") or []
if not rows:
return f"<div class='pb-card' style='color:{C['muted']}'>No fills yet this session β€” maker fills arrive on flow, not on a clock.</div>"
def _mk(r):
t = str(r.get("title") or "")
return html.escape(t) if t else f"<span class='mono'>{html.escape(str(r.get('cid')))}</span>"
def _usd(v):
return f"${v:.2f}" if isinstance(v, (int, float)) else f"${v}"
def _sh(v):
return f"{v:.1f}" if isinstance(v, (int, float)) else str(v)
body = "".join(f"<tr><td>{html.escape(str(r.get('t')))}</td><td style='max-width:300px'>{_mk(r)}</td>"
f"<td>{html.escape(str(r.get('side')))}</td><td>{r.get('px')}</td><td>{_sh(r.get('sh'))}</td>"
f"<td>{_usd(r.get('usd'))}</td></tr>" for r in rows)
return ("<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>"
"<th>time (UTC)</th><th>market</th><th>side</th><th>fill px</th><th>shares</th><th>$</th></tr>"
+ body + "</table></div>")
def mm_book_html(st):
rows = st.get("book") or []
if not rows:
return f"<div class='pb-card' style='color:{C['muted']}'>Book flat β€” no session inventory held.</div>"
def _mk(r):
t = str(r.get("title") or "")
return html.escape(t) if t else f"<span class='mono'>{html.escape(str(r.get('cid')))}</span>"
body = "".join(f"<tr><td style='max-width:320px'>{_mk(r)}</td>"
f"<td>{r.get('net'):+.1f}</td><td>{r.get('y')}</td><td>{r.get('no')}</td>"
f"<td>${r.get('cost')}</td>"
f"<td>{'$%.2f' % r.get('wval') if isinstance(r.get('wval'), (int, float)) else 'β€”'}</td>"
f"{_mm_pnl_td(r.get('wpnl'))}</tr>" for r in rows)
return ("<div class='pb-card' style='overflow-x:auto'><table class='pb-tbl'><tr>"
"<th>market</th><th>net (YES-eq sh)</th><th>YES sh</th><th>NO sh</th><th>session cost</th>"
"<th>wallet value</th><th>wallet P&L</th></tr>" + body + "</table>"
f"<div style='color:{C['muted']};margin-top:6px;font-size:12px'>session inventory (this poster run) Β· "
f"wallet value/P&L are whole-wallet for that market (incl. pre-session legs)</div></div>")
def mm_charts(st):
"""Relevant trends (owner Jul-22): wallet equity vs bank Β· open P&L Β· at-risk vs cap. From beats/mm_beats.csv."""
plt.close("all")
try:
df = pd.read_csv(_dl("beats/mm_beats.csv"), engine="python", on_bad_lines="skip")
except Exception:
return None
if df is None or not len(df): return None
ts = pd.to_datetime(pd.to_numeric(df["ts"], errors="coerce"), unit="s")
bank = (st or {}).get("bank") or 445.0
fig, axes = plt.subplots(3, 1, figsize=(9, 6.4), sharex=True)
wt = pd.to_numeric(df.get("wallet_total"), errors="coerce") if "wallet_total" in df.columns else None
a = axes[0]
if wt is not None and wt.notna().any():
# β˜… Jul-23 #63: overlay the CHAIN-RECONSTRUCTED true-cash history (beats/equity_history.csv from the
# equity-audit job) β€” the beats series only knows true equity from the fix onward; the chain knows it all.
try:
_hp = _dl("beats/equity_history.csv")
if _hp:
_h = pd.read_csv(_hp)
_hts = pd.to_datetime(_h["date"])
_hc = pd.to_numeric(_h.get("cash_total"), errors="coerce")
if _hc.notna().any():
a.plot(_hts, _hc, color=C["muted"], lw=1.0, ls=(0, (2, 2)), alpha=.8)
a.annotate("cash only (chain) β€” not equity", (list(_hts)[0], list(_hc)[0]),
textcoords="offset points", xytext=(4, 6), fontsize=8, color=C["muted"])
except Exception:
pass
a.plot(ts, wt, color=C["blue"], lw=1.6)
_we = (st or {}).get("wallet_eq") or {}
_base = _we.get("deposits") if isinstance(_we.get("deposits"), (int, float)) else bank
a.axhline(_base, color=C["muted"], lw=0.8, ls="--")
a.annotate("deposited" if _we.get("deposits") else "bank", (list(ts)[0], _base),
textcoords="offset points", xytext=(4, 4), fontsize=8, color=C["muted"])
_endpoint(a, ts, wt, C["blue"], "{:.0f}")
if "marks" in df.columns: # Jul-22: cash-vs-marks split β€” how much equity sits in open positions
mk = pd.to_numeric(df.get("marks"), errors="coerce")
if mk.notna().any():
mm_ = mk.notna()
a.plot(ts[mm_], mk[mm_], color=C["amber"], lw=1.0)
_endpoint(a, ts[mm_], mk[mm_], C["amber"], "marks {:.0f}")
a.set_title(f"Wallet equity ($) vs ${bank:.0f} bank Β· thin = position marks", loc="left", fontsize=9)
else:
a.set_title("Wallet equity β€” series starts at the next beats", loc="left", fontsize=9)
b = axes[1]
cp = pd.to_numeric(df.get("cash_pnl"), errors="coerce")
b.plot(ts, cp, color=C["green"], lw=1.4); b.axhline(0, color=C["muted"], lw=0.8)
_endpoint(b, ts, cp, C["green"], "{:+.1f}")
b.set_title("Open P&L ($, current book unrealized)", loc="left", fontsize=9)
c = axes[2]
un = pd.to_numeric(df.get("unmatched_usd"), errors="coerce")
c.plot(ts, un, color=C["amber"], lw=1.4)
c.axhline(100, color=C["muted"], lw=0.8, ls="--")
_endpoint(c, ts, un, C["amber"], "{:.0f}")
c.set_title("At-risk unmatched ($) vs $100 cap", loc="left", fontsize=9)
for ax in axes: _style_ax(fig, ax)
fig.tight_layout()
return fig
def mm_refresh(module):
st = load_status(module)
return (mm_header(st), mm_portfolio_html(st), trades_html(st), mm_charts(st),
mm_fills_html(st), mm_book_html(st), mm_body_html(st))
def refresh(module):
st = load_status(module); beats = load_beats(module)
ch = charts(beats, (st.get("equity") or {}).get("deposit")) or [None] * 5
em_html, em_fig = edge_html(st, beats)
return (header_html(st), feed_html(st), trades_html(st), portfolio_html(st),
log_html(st), ch[0], ch[1], ch[2], ch[3], ch[4], em_html, em_fig,
integrity_html(module), model_html(st))
MODULES = load_modules()
_KINDS = {m: (load_status(m) or {}).get("kind", "trader") for m in MODULES}
_THEME = gr.themes.Base(
font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"],
font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "ui-monospace", "Consolas", "monospace"])
with gr.Blocks(title="ATLAS", theme=_THEME, css=CSS, js=_FORCE_LIGHT_JS) as demo:
gr.HTML(f"<h1 style='color:{C['text']};margin:4px 0 10px;font-weight:640;letter-spacing:-.01em'>ATLAS</h1>")
for mod in MODULES:
with gr.Tab(mod.upper()):
if _KINDS.get(mod) == "backtests": # ── MM-BACKTESTS (standardized backtest results) ──
_st0 = load_status(mod)
bhead = gr.HTML(mmb_header(_st0))
blist = gr.HTML(mmb_list_html(_st0))
bouts = [bhead, blist]
demo.load(mmb_refresh, inputs=[gr.State(mod)], outputs=bouts)
gr.Timer(60).tick(mmb_refresh, inputs=[gr.State(mod)], outputs=bouts)
elif _KINDS.get(mod) == "mm": # ── the MM bot (the TruFlow tab as of Jul-22) ──
_m0 = load_status(mod)
mhead = gr.HTML(mm_header(_m0))
with gr.Tab("Portfolio"): # β˜… Jul-22 owner /goal: the ACTUAL book, first
mport = gr.HTML(mm_portfolio_html(_m0))
with gr.Tab("Trades"): # round-trip episodes (restored Jul-22 β€” never drop it)
mtr = gr.HTML(trades_html(_m0))
with gr.Tab("Trends"):
mfig = gr.Plot(mm_charts(_m0))
with gr.Tab("Fills"):
mfl = gr.HTML(mm_fills_html(_m0))
with gr.Tab("Book"):
mbk = gr.HTML(mm_book_html(_m0))
with gr.Tab("Status"):
mbody = gr.HTML(mm_body_html(_m0))
with gr.Tab("Glossary"):
gr.HTML(mm_glossary_html())
mouts = [mhead, mport, mtr, mfig, mfl, mbk, mbody]
demo.load(mm_refresh, inputs=[gr.State(mod)], outputs=mouts)
gr.Timer(60).tick(mm_refresh, inputs=[gr.State(mod)], outputs=mouts)
else: # ── TRUFLOW (trader) ──
# STARTUP SNAPSHOT (Jul-11, parity with the Rei branch): seed every component so a dead
# queue/SSE stream degrades to this snapshot instead of a blank tab (the Jul-6 503 class).
try:
_r0 = refresh(mod)
except Exception:
_r0 = (None,) * 14
head = gr.HTML(_r0[0])
# owner Jul-7: Trends FIRST; chart titles SHORT with (i) tooltips (feedback-ui-labels-short)
with gr.Tab("Trends"):
gr.HTML(f"<div style='margin:6px 2px 0'>{tip('Equity', 'equity')}</div>")
p1 = gr.Plot(_r0[5])
gr.HTML(f"<div style='margin:6px 2px 0'>{tip('Idle cash', 'idle cash')}</div>")
p5 = gr.Plot(_r0[9])
gr.HTML(f"<div style='margin:6px 2px 0'>{tip('Markets', 'markets')}</div>")
p4 = gr.Plot(_r0[8])
gr.HTML(f"<div style='margin:6px 2px 0'>{tip('Heartbeat', 'market heartbeat')}</div>")
p2 = gr.Plot(_r0[6])
gr.HTML(f"<div style='margin:6px 2px 0'>{tip('Dislocations 48h', 'dislocations scored (48h)')}</div>")
p3 = gr.Plot(_r0[7])
with gr.Tab("Live feed"):
ev = gr.HTML(_r0[1])
with gr.Tab("Trades"):
tr = gr.HTML(_r0[2])
with gr.Tab("Portfolio"):
pf = gr.HTML(_r0[3])
with gr.Tab("Model"):
mdl = gr.HTML(_r0[13])
with gr.Tab("Log"):
lg = gr.HTML(_r0[4])
with gr.Tab("Edge monitor"):
em = gr.HTML(_r0[10]); ep = gr.Plot(_r0[11])
with gr.Tab("Integrity"):
ig = gr.HTML(_r0[12] or integrity_html(mod))
with gr.Tab("Glossary"):
gr.HTML(glossary_html())
outs = [head, ev, tr, pf, lg, p1, p2, p3, p4, p5, em, ep, ig, mdl]
demo.load(refresh, inputs=[gr.State(mod)], outputs=outs)
gr.Timer(60).tick(refresh, inputs=[gr.State(mod)], outputs=outs)
gr.HTML(f"<div style='color:{C['muted']};font-size:12px;margin-top:8px'>Read-only β€” the bots always take "
f"precedence. Publisher beats ~2 min; page refreshes every 60s. Hover any dotted label for an explainer.</div>")
_auth = (os.environ.get("DASH_USER", "farhan"), os.environ["DASH_PASS"]) if os.environ.get("DASH_PASS") else None
demo.launch(auth=_auth, ssr_mode=False)