Spaces:
Sleeping
Sleeping
| """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')} {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 & 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) | |