diff --git a/index.html b/index.html
index d121d4a..359b925 100644
--- a/index.html
+++ b/index.html
@@ -107,10 +107,11 @@ h1,h2,h3,.brand-name{font-family:'Space Grotesk','Inter',sans-serif}
.pos-val{color:var(--green)}.neg-val{color:var(--red)}
/* ---------- charts ---------- */
-#chart,#chart2{width:100%;height:240px;display:block}
-.legend{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:14px}
-.leg{display:flex;align-items:center;gap:7px;font-size:12.5px;color:#cdd6e8}
-.legdot{width:10px;height:10px;border-radius:3px;display:inline-block}
+#chart,#chart2{width:100%;height:300px;display:block;margin-top:6px;overflow:visible}
+.legend{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:8px 12px;margin-top:14px}
+.leg{display:flex;align-items:center;gap:8px;font-size:12px;color:#cdd6e8;background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.06);border-radius:8px;padding:7px 9px;min-width:0}
+.leg b{margin-left:auto;font-family:'Space Grotesk',sans-serif}
+.legdot{width:9px;height:9px;border-radius:50%;display:inline-block;box-shadow:0 0 0 3px rgba(255,255,255,.06)}
.rangebar{display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.rangebtn{appearance:none;border:1px solid var(--border);background:rgba(255,255,255,.04);color:var(--muted);
font:700 11px 'Inter',sans-serif;padding:5px 8px;border-radius:8px;cursor:pointer}
@@ -223,6 +224,8 @@ a.market-title:hover{color:#fff;text-decoration:underline;text-decoration-color:
.btn{padding:9px 11px}
.section-title{font-size:19px}
.stats{grid-template-columns:1fr;gap:12px}
+ #chart,#chart2{height:280px}
+ .legend{grid-template-columns:1fr}
.agent-brief{grid-template-columns:1fr}
.pos{align-items:flex-start;gap:12px}
.pos .pq{max-width:none}
@@ -311,7 +314,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
-
+
Use the range buttons to zoom from one week to all history. New live points are added whenever you click "Run cycle"; the dashed line tracks the average agent return.
@@ -328,7 +331,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
-
+
Past week is a backtest. After that, each manual or daily run adds another return snapshot for every agent.
@@ -1262,6 +1265,25 @@ function chartTicks(times,maxTicks=5){
}
return ticks;
}
+function niceChartBounds(vals){
+ let min=Math.min(...vals,0),max=Math.max(...vals,0);
+ if(min===max){min-=1;max+=1;}
+ const span=max-min,pad=Math.max(0.5,span*0.12);
+ min-=pad;max+=pad;
+ const step=Math.max(0.5,Math.pow(10,Math.floor(Math.log10(max-min)))/2);
+ min=Math.floor(min/step)*step;max=Math.ceil(max/step)*step;
+ return {min,max};
+}
+function smoothPath(points){
+ if(points.length<2)return points.map((p,i)=>`${i?"L":"M"}${p.x},${p.y}`).join(" ");
+ let d=`M${points[0].x},${points[0].y}`;
+ for(let i=1;i
r.id===chartRange())||CHART_RANGES[0];
if(!range.days)return times;
@@ -1278,7 +1300,7 @@ function drawCombo(svgId,legendId){
const allTimes=rangeFilteredTimes([...new Set(series.flatMap(s=>s.snaps.map(snapTime)))].sort((a,b)=>a-b));
const svg=$(svgId); if(!svg)return;
if(!allTimes.length){svg.innerHTML="";if($(legendId))$(legendId).innerHTML=`No history yet — click "Run cycle". `;return;}
- const W=600,H=240,padL=42,padR=18,padT=18,padB=38; const vals=[0];
+ const W=720,H=300,padL=58,padR=28,padT=34,padB=50; const vals=[0];
const lines=series.map(s=>{
let last=0,idx=0;
const pts=allTimes.map(t=>{
@@ -1292,37 +1314,42 @@ function drawCombo(svgId,legendId){
});
const avgPts=allTimes.map((_,i)=>+(lines.reduce((sum,l)=>sum+l.pts[i],0)/Math.max(1,lines.length)).toFixed(2));
vals.push(...avgPts);
- const min=Math.min(...vals,0),max=Math.max(...vals,0),span=(max-min)||1;
+ const bounds=niceChartBounds(vals),min=bounds.min,max=bounds.max,span=(max-min)||1;
const x=i=>allTimes.length===1?(padL+(W-padR))/2:padL+(i/(allTimes.length-1))*(W-padL-padR);
const y=v=>H-padB-((v-min)/span)*(H-padT-padB);
- const yTicks=[...new Set([min,(min+max)/2,max].map(v=>+v.toFixed(1)))];
+ const yTicks=Array.from({length:5},(_,i)=>+(min+(span*i/4)).toFixed(1));
const zeroY=y(0).toFixed(1);
let inner=`
-
-
+
+
+
+
+
`;
- inner+=` `;
+ inner+=` `;
for(const v of yTicks){
const yy=y(v).toFixed(1);
- inner+=` `;
- inner+=`${fmtPct(v)} `;
+ inner+=` `;
+ inner+=`${fmtPct(v)} `;
}
- inner+=` `;
+ inner+=` `;
for(const tick of chartTicks(allTimes,5)){
const xx=x(tick.i).toFixed(1);
- inner+=` `;
- inner+=`${chartDateLabel(tick.t,true)} `;
+ inner+=` `;
+ inner+=`${chartDateLabel(tick.t,true)} `;
}
for(const ln of lines){
- const d=ln.pts.map((v,i)=>`${i===0?"M":"L"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
- const dot=allTimes.length===1?` `:"";
- inner+=` ${dot}`;
+ const points=ln.pts.map((v,i)=>({x:x(i).toFixed(1),y:y(v).toFixed(1)}));
+ const d=smoothPath(points);
+ const last=points[points.length-1];
+ inner+=` `;
+ inner+=` `;
}
- const avgD=avgPts.map((v,i)=>`${i===0?"M":"L"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
- inner+=` `;
- inner+=`${chartDateLabel(allTimes[0])} `;
- inner+=`${chartDateLabel(allTimes[allTimes.length-1])} `;
+ const avgPoints=avgPts.map((v,i)=>({x:x(i).toFixed(1),y:y(v).toFixed(1)}));
+ inner+=` `;
+ inner+=`Return % `;
+ inner+=`${chartDateLabel(allTimes[0])} - ${chartDateLabel(allTimes[allTimes.length-1])} `;
svg.innerHTML=inner;
if($(legendId)){
const b=board();const avg=b.reduce((s,r)=>s+r.ret,0)/b.length;