diff --git a/index.html b/index.html index 5b57dfa..abdc185 100644 --- a/index.html +++ b/index.html @@ -155,6 +155,14 @@ h1,h2,h3,.brand-name{font-family:'Space Grotesk','Inter',sans-serif} .loading-ring{width:34px;height:34px;border-radius:50%;border:3px solid rgba(255,255,255,.12);border-top-color:var(--accent);animation:spin .9s linear infinite} .empty-copy{max-width:420px;color:var(--muted);font-size:13.5px} @keyframes spin{to{transform:rotate(360deg)}} +.report-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(255px,1fr));gap:14px} +.report{background:rgba(255,255,255,.04);border:1px solid var(--border);border-radius:15px;padding:16px;border-top:3px solid var(--accent)} +.report-title{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px} +.report-name{font-family:'Space Grotesk';font-weight:700} +.report-rank{font-size:11px;color:var(--muted);border:1px solid var(--border);border-radius:999px;padding:3px 8px;white-space:nowrap} +.report p{margin:0 0 9px;color:#cdd6e8;font-size:13px;line-height:1.5} +.report p:last-child{margin-bottom:0} +.report b{color:var(--text)} /* ---------- suggestions ---------- */ .filterbar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:8px} @@ -346,6 +354,10 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color

Activity Log

+
+

Daily Agent Reports

+
+
@@ -1168,6 +1180,42 @@ function renderPortfolioTab(){ } renderPositions(p.positions); renderHistory((p.history||[]).slice(-50).reverse()); + renderAgentReports(); +} +function agentCompetitionPlan(cfg,row,rank,leader){ + if(rank===1)return "Plan: defend the lead, keep sizing disciplined, and let risk controls protect gains instead of forcing new trades."; + if(cfg.kind==="copycat")return `Plan: keep shadowing ${leader.c.name}, then rotate automatically if another in-house strategy takes the crown.`; + if(cfg.kind==="whale")return "Plan: stay close to the copied trader's largest live positions while using the stop-loss and gain-stop rules to avoid blindly riding every swing."; + if(cfg.id==="value")return "Plan: close the gap by waiting for the cleanest model-versus-market mispricings and avoiding crowded trades without enough edge."; + if(cfg.id==="momentum")return "Plan: attack fast-moving markets where fresh volume confirms attention, hoping speed beats slower value strategies."; + if(cfg.id==="favorite")return "Plan: grind upward through high-probability favorites, aiming to outlast more volatile agents during choppy markets."; + if(cfg.id==="longshot")return "Plan: keep risk small but search for one underpriced outsider that can reprice sharply and leapfrog the leaderboard."; + if(cfg.id==="diversifier")return "Plan: spread bets broadly, reduce single-market damage, and try to win through consistency rather than one heroic call."; + return "Plan: keep following its rulebook and use fresh market data to pressure the leaderboard."; +} +function reportPositionLine(p){ + if(!p.positions.length)return "No open positions yet, so today's focus is finding entries that fit the strategy."; + const best=[...p.positions].sort((a,b)=>(b.unrealized_pnl||0)-(a.unrealized_pnl||0))[0]; + const worst=[...p.positions].sort((a,b)=>(a.unrealized_pnl||0)-(b.unrealized_pnl||0))[0]; + if(best===worst)return `Current focus: ${best.question.slice(0,58)}${best.question.length>58?"...":""}, marked ${best.unrealized_pnl>=0?"+":""}${fmtUSD(best.unrealized_pnl||0)}.`; + return `Best mark: ${best.question.slice(0,42)}${best.question.length>42?"...":""} (${best.unrealized_pnl>=0?"+":""}${fmtUSD(best.unrealized_pnl||0)}). Watch item: ${worst.question.slice(0,42)}${worst.question.length>42?"...":""} (${fmtUSD(worst.unrealized_pnl||0)}).`; +} +function renderAgentReports(){ + const root=$("agentReports"); if(!root)return; + const b=board(); const st=loadState(); const leader=b[0]; + if($("reportDate"))$("reportDate").textContent=`${st.last_run?new Date(st.last_run).toLocaleString():todayStr()}`; + root.innerHTML=b.map((row,i)=>{ + const rank=i+1, ret=fmtPct(row.ret), open=row.p.positions.length; + const thesis=agentPlainBlurb(row.c,st); + const plan=agentCompetitionPlan(row.c,row,rank,leader); + const line=reportPositionLine(row.p); + return `
+
${row.c.emoji} ${row.c.name}
#${rank} ยท ${ret}
+

Strategy: ${esc(thesis)}

+

Status: ${open} open position${open===1?"":"s"} with ${fmtUSD(row.eq)} equity. ${esc(line)}

+

${esc(plan)}

+
`; + }).join(""); } function renderPositions(positions){ const root=$("positions");if(!root)return;