diff --git a/dashboard/static/index.html b/dashboard/static/index.html
index 8eb9334..15df692 100644
--- a/dashboard/static/index.html
+++ b/dashboard/static/index.html
@@ -61,6 +61,7 @@ body{background:var(--bg);color:var(--hi);font-family:var(--f);min-height:100vh;
.close-btn{background:none;border:1px solid var(--ln);color:var(--hi);padding:6px 14px;border-radius:6px;cursor:pointer;font-size:12px;font-family:var(--f);transition:all .15s}
.close-btn:hover{background:var(--hr)}
.detail-body{padding:20px}
+.main-chart{width:100%;height:220px;margin:8px 0 0;border-radius:var(--ra);overflow:hidden;background:rgba(0,0,0,.25)}
.detail-body .chart-wrap{width:100%;height:280px;margin-bottom:16px;border-radius:var(--ra);overflow:hidden}
.detail-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:16px}
.detail-section{margin-bottom:20px}
@@ -124,10 +125,12 @@ footer a{color:#3f3f4a;text-decoration:none}footer a:hover{color:var(--tx)}
@@ -197,6 +200,36 @@ var STRAT_COLORS=['#22c55e','#3b82f6','#a855f7','#f59e0b','#ef4444','#06b6d4','#
// ═══════════ Chart for detail view ═══════════
var detChart=null, detSer=null;
+
+// ═══════════ Main area charts ═══════════
+var chartLive=null, serLive=null, chartPaper=null, serPaper=null;
+function initMainCharts(){
+ [{el:'chart-live',ch:'chartLive',sr:'serLive'},{el:'chart-paper',ch:'chartPaper',sr:'serPaper'}].forEach(function(c){
+ var el=document.getElementById(c.el);if(!el)return;
+ el.style.width='100%';el.style.height='220px';
+ window[c.ch]=LightweightCharts.createChart(el,{
+ layout:{background:{color:'transparent'},textColor:'#a0a0b0'},
+ grid:{vertLines:{color:'rgba(255,255,255,.02)'},horzLines:{color:'rgba(255,255,255,.03)'}},
+ rightPriceScale:{borderColor:'rgba(255,255,255,.08)',autoScale:true},
+ timeScale:{borderColor:'rgba(255,255,255,.08)',timeVisible:false},
+ crosshair:{mode:0},width:el.offsetWidth,height:220
+ });
+ window[c.sr]=window[c.ch].addAreaSeries({lineColor:'#3b82f6',topColor:'rgba(59,130,246,.15)',bottomColor:'rgba(59,130,246,.02)',lineWidth:2});
+ });
+}
+function pushEquity(chart,ser,data){
+ if(!chart||!ser||!data||!data.length)return;
+ var pts=[];
+ for(var i=0;i
1e12)t=Math.floor(t/1000);
+ pts.push({time:t,value:v});
+ }
+ }
+ if(pts.length>0){ser.setData(pts);chart.timeScale().fitContent()}
+}
function initDetChart(){
var el=document.getElementById('det-chart');
if(!el)return;
@@ -385,8 +418,8 @@ function connect(){
wsPaper.onmessage=function(e){try{lastPaper=JSON.parse(e.data)}catch(ex){return};if(currentTab==='paper')renPaper(lastPaper)};
}
-function renLive(d){if(!d)return;var p=d.total_pnl||0;document.getElementById('stpnl').textContent=(p>=0?'+':'')+'$'+Math.abs(p).toFixed(2);document.getElementById('stpnl').className='pnl '+(p>=0?'up':'dn');document.getElementById('stpct').textContent='Testnet · Equity: $'+((d.base_equity||898)+p).toFixed(2);renCards('live-sgrid',d.strategies||{},d.base_equity||898,'live','live-stats')}
-function renPaper(d){if(!d)return;var p=d.total_pnl||0;document.getElementById('stpnl').textContent=(p>=0?'+':'')+'$'+Math.abs(p).toFixed(2);document.getElementById('stpnl').className='pnl '+(p>=0?'up':'dn');document.getElementById('stpct').textContent='Paper · '+d.total_equity+' · Regime: '+(d.regime||'—');renCards('paper-sgrid',d.strategies||{},d.base_equity||100000,'paper','paper-stats')}
+function renLive(d){if(!d)return;var p=d.total_pnl||0;document.getElementById('stpnl').textContent=(p>=0?'+':'')+'$'+Math.abs(p).toFixed(2);document.getElementById('stpnl').className='pnl '+(p>=0?'up':'dn');document.getElementById('stpct').textContent='Testnet · Equity: $'+((d.base_equity||898)+p).toFixed(2);renCards("live-sgrid",d.strategies||{},d.base_equity||898,"live","live-stats");if(d.equity_history&&chartLive)pushEquity(chartLive,serLive,d.equity_history)}
+function renPaper(d){if(!d)return;var p=d.total_pnl||0;document.getElementById('stpnl').textContent=(p>=0?'+':'')+'$'+Math.abs(p).toFixed(2);document.getElementById('stpnl').className='pnl '+(p>=0?'up':'dn');document.getElementById('stpct').textContent='Paper · '+d.total_equity+' · Regime: '+(d.regime||'—');renCards("paper-sgrid",d.strategies||{},d.base_equity||100000,"paper","paper-stats");if(d.equity_history&&chartPaper)pushEquity(chartPaper,serPaper,d.equity_history)}
// ═══════════ Backtests ═══════════
var lastBT={}, lastBTList=[];
@@ -411,7 +444,7 @@ function loadHistBT(){
for(var i=0;i'+s+'
30d '+b.coin+' · Mainnet
REAL DATA'+(pnl>=0?'+':'')+pnl.toFixed(2)+'%
Sharpe: '+b.sharpe.toFixed(2)+'DD: '+(b.max_dd*100).toFixed(2)+'%Win: '+Math.round(b.win_rate*100)+'%
';
+ h+='No historical backtests. Run: python backtests/historical_runner.py --coin BTC --strategy all
';
})
@@ -433,7 +466,7 @@ function openHistDetail(strat){
}
// ═══════════ Init ═══════════
-initDetChart();connect();loadBT();
+initDetChart();initMainCharts();connect();loadBT();loadHistBT();
// ═══════════ Risk Analytics ═══════════
function toggleRisk(){
var p=document.getElementById('risk-panel'),b=document.getElementById('risk-btn');