Per-strategy equity curves + $100K paper capital

Paper trader now tracks individual equity history per strategy
(strategy_equity dict with deque per strategy). Metrics file
exports per-strategy data for dashboard rendering.

Dashboard paper chart upgraded to 7 overlaid area series:
- Each strategy gets its own colored curve (green, blue, purple, etc.)
- 300px height for better visibility of multiple lines
- Color palette distinguishes strategies at a glance

$100K total capital: $10K per strategy × 7 + $30K reserve.

Exeria Charts evaluated: excellent library (Benzinga award winner,
Canvas/WebGL, exchange connectors) but requires npm+bundler —
not suitable for single-file dashboard. Lightweight-charts
remains the right choice for our architecture.
This commit is contained in:
ramseshk
2026-08-04 04:37:27 +00:00
parent 7a5fdf2f8d
commit 1ece7ec7c6
2 changed files with 33 additions and 4 deletions
+28 -4
View File
@@ -100,7 +100,7 @@ footer{text-align:center;padding:20px;font-size:10px;color:#3f3f46}footer a{colo
<!-- PAPER -->
<div class="panel" id="pnl-paper">
<div class="stats" id="paper-stats"></div>
<div class="card"><h3>Equity Curve <span class="desc">real-time · Hyperliquid Mainnet (simulated fills)</span></h3><div class="chart-wrap" id="paper-chart"></div></div>
<div class="card"><h3>Equity Curve <span class="desc">per-strategy · Hyperliquid Mainnet (simulated)</span></h3><div class="chart-wrap" id="paper-chart" style="height:300px"></div></div>
<div class="grid" id="paper-grid"></div>
<div class="card"><h3>Trade Log</h3><div class="tbl-scroll"><table><thead><tr><th>Time</th><th>Strategy</th><th>Side</th><th>Size</th><th>Price</th><th>Fee</th><th>PnL</th></tr></thead><tbody id="paper-tb"></tbody></table></div></div>
</div>
@@ -117,7 +117,20 @@ footer{text-align:center;padding:20px;font-size:10px;color:#3f3f46}footer a{colo
var tab='live',lastData=null,lastPaper=null;
function mkChart(el,w,h){var c=LightweightCharts.createChart(el,{layout:{background:{color:'transparent'},textColor:'#8b8b96'},grid:{vertLines:{color:'rgba(255,255,255,0.03)'},horzLines:{color:'rgba(255,255,255,0.03)'}},rightPriceScale:{borderColor:'rgba(255,255,255,0.06)'},timeScale:{borderColor:'rgba(255,255,255,0.06)',timeVisible:true},crosshair:{mode:0},width:w,height:h});return c}
var eqChart=mkChart(document.getElementById('eq-chart'),0,0);var eqSer=eqChart.addAreaSeries({lineColor:'#3b82f6',topColor:'rgba(59,130,246,0.15)',bottomColor:'rgba(59,130,246,0.02)',lineWidth:2});
var paperChart=mkChart(document.getElementById('paper-chart'),0,0);var paperSer=paperChart.addAreaSeries({lineColor:'#a855f7',topColor:'rgba(168,85,247,0.12)',bottomColor:'rgba(168,85,247,0.02)',lineWidth:2});
var paperChart=mkChart(document.getElementById('paper-chart'),0,0);
// Per-strategy equity series (7 strategies, 7 colors)
var STRAT_COLORS = ['#22c55e','#3b82f6','#a855f7','#f59e0b','#ef4444','#06b6d4','#ec4899'];
var paperStrataSeries = {};
function getStratSeries(name){
if(!paperStrataSeries[name]){
var idx = Object.keys(paperStrataSeries).length;
var color = STRAT_COLORS[idx % STRAT_COLORS.length];
paperStrataSeries[name] = paperChart.addAreaSeries({
lineColor: color, topColor: color+'26', bottomColor: color+'05', lineWidth: 1.5
});
}
return paperStrataSeries[name];
}
var btChart=mkChart(document.getElementById('bt-chart'),0,0);var btSer=btChart.addAreaSeries({lineColor:'#a855f7',topColor:'rgba(168,85,247,0.12)',bottomColor:'rgba(168,85,247,0.02)',lineWidth:2});
function fitCharts(){
@@ -196,8 +209,19 @@ function renLive(d){
function renPaper(d){
if(!d)return;
var pnl=d.total_pnl||0;document.getElementById('stpnl').textContent=(pnl>=0?'+':'')+'$'+Math.abs(pnl).toFixed(2);document.getElementById('stpnl').className='pnl '+(pnl>=0?'up':'dn');
document.getElementById('stpct').textContent='Mainnet Paper · Equity: $'+((d.total_equity||5000)).toFixed(2)+' · BTC: $'+(d.btc_price||0).toLocaleString('en-US',{maximumFractionDigits:0});
renGrid('paper-grid',d.strategies||{},d.base_equity||5000,d.reserve||1000,'paper-stats','paper-tb',paperChart,paperSer,d.equity_history||[],d.trades||[]);
document.getElementById('stpct').textContent='Mainnet Paper · Equity: $'+(d.total_equity||100000).toFixed(0)+' · BTC: $'+(d.btc_price||0).toLocaleString('en-US',{maximumFractionDigits:0});
renGrid('paper-grid',d.strategies||{},d.base_equity||100000,d.reserve||30000,'paper-stats','paper-tb',paperChart,null,d.equity_history||[],d.trades||[]);
// Per-strategy equity curves
var seq = d.strategy_equity || {};
var keyz = Object.keys(seq);
for(var i=0;i<keyz.length;i++){
var name=keyz[i],pts=seq[name],ser=getStratSeries(name);
if(pts&&pts.length>0){
var arr=[];for(var j=0;j<pts.length;j++) if(pts[j]&&pts[j].t) arr.push({time:pts[j].t,value:pts[j].v});
ser.setData(arr);
}
}
paperChart.timeScale().fitContent();
}
function toggleStrat(sid){var el=document.getElementById('strat-'+sid);if(!el)return;el.classList.toggle('open');setTimeout(fitCharts,200)}