[object Object]

← back to Bertha

chore(alshi-dash): update 1 file (.js) [+16/-13]

8e9ef184ff9c08eb658156ef4fc01ccd64483dfd · 2026-02-27 08:04:00 +0000 · DW Commit Agent

Files touched

Diff

commit 8e9ef184ff9c08eb658156ef4fc01ccd64483dfd
Author: DW Commit Agent <commit-agent@dw-agents.com>
Date:   Fri Feb 27 08:04:00 2026 +0000

    chore(alshi-dash): update 1 file (.js) [+16/-13]
---
 kalshi-dash/server.js | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index 971a86e..b11b5fe 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -1646,13 +1646,21 @@ const routes = {
         `, [pf.id]);
         pf.trades_today = parseInt(today[0]?.trades_today) || 0;
         pf.spent_today = parseInt(today[0]?.spent_today) || 0;
-        pf.budget_remaining = pf.daily_budget_cents - pf.spent_today;
+        pf.budget_remaining = Math.max(0, pf.balance_cents); // Remaining = whatever balance is left
 
         // Win rate
         const totalResolved = pf.trades_won + pf.trades_lost + pf.trades_expired;
         pf.win_rate = totalResolved > 0 ? Math.round(pf.trades_won / totalResolved * 100) : 0;
         pf.total_resolved = totalResolved;
+        pf.is_bankrupt = pf.balance_cents <= 0;
       }
+      // Sort: active portfolios by ROI (best first), bankrupt portfolios at bottom
+      portfolios.sort((a, b) => {
+        if (a.is_bankrupt !== b.is_bankrupt) return a.is_bankrupt ? 1 : -1;
+        const aROI = a.total_invested_cents > 0 ? (a.total_returned_cents - a.total_invested_cents) / a.total_invested_cents : 0;
+        const bROI = b.total_invested_cents > 0 ? (b.total_returned_cents - b.total_invested_cents) / b.total_invested_cents : 0;
+        return bROI - aROI;
+      });
       json(res, portfolios);
     } catch(e) { json(res, { error: e.message }, 500); }
   },
@@ -7720,15 +7728,8 @@ async function autoPortfolioTrade(signal) {
       const strategy = PORTFOLIO_STRATEGIES[pf.strategy];
       if (!strategy) continue;
 
-      // Check daily budget: how much did this portfolio spend today?
-      const { rows: todaySpend } = await kenQ(`
-        SELECT COALESCE(SUM(cost_cents), 0) as spent
-        FROM ken_portfolio_trades
-        WHERE portfolio_id = $1 AND created_at::date = CURRENT_DATE AND status = 'open'
-      `, [pf.id]);
-      const spentToday = parseInt(todaySpend[0]?.spent) || 0;
-
-      if (spentToday >= pf.daily_budget_cents) continue; // Budget exhausted
+      // Check balance: bankrupt portfolios can't trade (balance = 0 → move to bottom)
+      if (pf.balance_cents <= 0) continue; // BANKRUPT — no more trades
 
       // Check if strategy accepts this signal
       const sigData = {
@@ -7767,7 +7768,7 @@ async function autoPortfolioTrade(signal) {
       const clampedPrice = Math.max(5, Math.min(95, entryPrice));
       const cost = clampedPrice * contracts;
 
-      if (spentToday + cost > pf.daily_budget_cents) continue; // Would exceed budget
+      if (cost > pf.balance_cents) continue; // Not enough balance for this trade
 
       await kenQ(`
         INSERT INTO ken_portfolio_trades (portfolio_id, signal_id, market_id, market_title, direction, entry_price_cents, contracts, cost_cents, reasoning, confidence, ai_enhanced, mc_consistent)
@@ -7776,8 +7777,9 @@ async function autoPortfolioTrade(signal) {
           sigData.direction, clampedPrice, contracts, cost, (sigData.reasoning || '').substring(0, 500),
           conf, sigData.ai_enhanced, sigData.mc_consistent]);
 
-      // Update portfolio stats
-      await kenQ(`UPDATE ken_portfolios SET total_invested_cents = total_invested_cents + $1, last_trade_at = NOW() WHERE id = $2`, [cost, pf.id]);
+      // Deduct from balance + update stats
+      await kenQ(`UPDATE ken_portfolios SET balance_cents = balance_cents - $1, total_invested_cents = total_invested_cents + $1, last_trade_at = NOW() WHERE id = $2`, [cost, pf.id]);
+      pf.balance_cents -= cost; // Update in-memory too for subsequent iterations
 
       console.log(`[Ken/Portfolio] ${pf.name} (${pf.strategy}): ${sigData.direction} ${(signal.marketId || signal.market_id || '').substring(0, 30)} @ ${clampedPrice}¢ x${contracts} = $${(cost/100).toFixed(2)}`);
     }
@@ -7865,6 +7867,7 @@ async function resolvePortfolioTrades() {
       const expInc = status === 'expired' ? 1 : 0;
       await kenQ(`
         UPDATE ken_portfolios SET
+          balance_cents = balance_cents + $1,
           total_returned_cents = total_returned_cents + $1,
           trades_won = trades_won + $2,
           trades_lost = trades_lost + $3,

← a460d1b chore(kalshi-dash): update 1 file (.js) [+22]  ·  back to Bertha  ·  chore(alshi-dash): update 1 file (.js) [+249/-6] d107bf6 →