← back to Bertha
Ken: market data refinements and portfolio query fixes
df73f40b2ae8b77ec97d74bfaeb8a29054adeb55 · 2026-02-16 07:22:44 +0000 · DW Commit Agent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Files touched
Diff
commit df73f40b2ae8b77ec97d74bfaeb8a29054adeb55
Author: DW Commit Agent <claude@dw-agents.com>
Date: Mon Feb 16 07:22:44 2026 +0000
Ken: market data refinements and portfolio query fixes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
kalshi-dash/server.js | 44 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 41 insertions(+), 3 deletions(-)
diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index bf22f5b..bb8baa3 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -1916,10 +1916,13 @@ const routes = {
// 5. Portfolio P&L (current state)
try {
- const { rows } = await kenQ(`SELECT p.name, p.strategy, p.balance_cents, p.trades_won, p.trades_lost, p.win_rate,
- p.total_invested_cents, p.daily_budget_cents, p.budget_remaining, p.trades_today, p.streak
+ const { rows } = await kenQ(`SELECT p.name, p.strategy, p.balance_cents, p.trades_won, p.trades_lost,
+ p.total_invested_cents, p.daily_budget_cents, p.streak,
+ CASE WHEN (p.trades_won + p.trades_lost) > 0
+ THEN ROUND(p.trades_won * 100.0 / (p.trades_won + p.trades_lost))
+ ELSE 0 END AS win_rate
FROM ken_portfolios p ORDER BY p.balance_cents DESC`);
- out.portfolios = rows;
+ out.portfolios = rows.map(r => ({ ...r, balance_cents: parseInt(r.balance_cents), win_rate: parseInt(r.win_rate) }));
} catch { out.portfolios = []; }
// 6. Active markets count and top movers
@@ -2533,6 +2536,41 @@ function MarketDataTab() {
})}
</div>
</div>
+
+ {/* Portfolio Leaderboard */}
+ {(mkt.portfolios || []).length > 0 && <div className="mkt-card" style={{gridColumn:'span 2'}}>
+ <div className="mkt-card-header">
+ <span className="mkt-card-title" style={{color:'var(--pink)'}}>Portfolio Leaderboard</span>
+ <span className="mkt-card-badge" style={{background:'rgba(255,105,180,.15)',color:'var(--pink)'}}>{(mkt.portfolios||[]).length} portfolios</span>
+ </div>
+ <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(200px,1fr))',gap:8}}>
+ {(mkt.portfolios || []).map((p, i) => {
+ const stratColors = {aggressive:'#ef4444',conservative:'#3b82f6',weather:'#06b6d4',momentum:'#f59e0b',contrarian:'#8b5cf6',ai_enhanced:'#ec4899',mc_validated:'#a855f7',scalper:'#eab308',patient:'#22c55e',random:'#64748b'};
+ const stratEmojis = {aggressive:'🔥',conservative:'🏛️',weather:'⛈️',momentum:'🚀',contrarian:'🔄',ai_enhanced:'🧠',mc_validated:'🎲',scalper:'⚡',patient:'🐢',random:'🎰'};
+ const c = stratColors[p.strategy] || 'var(--muted)';
+ const pnl = parseInt(p.balance_cents) || 0;
+ return (<div key={i} style={{padding:'10px 14px',background:'rgba(255,255,255,.02)',border:'1px solid var(--border)',borderRadius:10,transition:'all .2s',borderLeftColor:c,borderLeftWidth:3}}>
+ <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:4}}>
+ <span style={{fontSize:18}}>{stratEmojis[p.strategy]||'📊'}</span>
+ <div>
+ <div style={{fontSize:12,fontWeight:700,color:c}}>{p.name}</div>
+ <div style={{fontSize:9,color:'var(--muted)',textTransform:'uppercase'}}>{p.strategy}</div>
+ </div>
+ <div style={{marginLeft:'auto',textAlign:'right'}}>
+ <div style={{fontSize:16,fontWeight:800,color:pnl>=0?'var(--green)':'var(--red)',fontVariantNumeric:'tabular-nums'}}>
+ {pnl>=0?'+':''}{(pnl/100).toFixed(2)}
+ </div>
+ </div>
+ </div>
+ <div style={{display:'flex',gap:4,fontSize:9}}>
+ <span style={{padding:'1px 6px',borderRadius:3,background:'rgba(34,197,94,.1)',color:'var(--green)'}}>W:{p.trades_won}</span>
+ <span style={{padding:'1px 6px',borderRadius:3,background:'rgba(239,68,68,.1)',color:'var(--red)'}}>L:{p.trades_lost}</span>
+ <span style={{padding:'1px 6px',borderRadius:3,background:'rgba(255,255,255,.04)',color:'var(--muted)'}}>WR:{p.win_rate}%</span>
+ </div>
+ </div>);
+ })}
+ </div>
+ </div>}
</div>
</div>);
}
← 1d9f769 chore(alshi-dash): update 1 file (.js) [+361/-4]
·
back to Bertha
·
chore(alshi-dash): update 1 file (.js) [+82/-47] e39a225 →