-
Live Trading
-
Coming soon, Meowster.
-
Find a profitable paper strategy first.
-
- โ Back to Paper Trading
-
+
+ {/* Header */}
+
+
+
+ {/* Kill Switch + Balance */}
+
+
+
+
Kalshi Balance
+
+ {live.balance != null ? `$${live.balance.toFixed(2)}` : 'โ'}
+
+ {live.portfolioValue != null && (
+
Portfolio: ${live.portfolioValue.toFixed(2)}
+ )}
+
+
+
+
+
+ = 0 ? '+' : ''}$${live.totalPnL?.toFixed(2) || '0.00'}`} color={live.totalPnL >= 0 ? GREEN : RED} dark />
+ = 50 ? GREEN : RED} dark />
+
+ 0 ? AMBER : null} dark />
+
+
+ {live.paused && (
+
+ โ ๏ธ TRADING PAUSED โ No new orders will be placed
+
+ )}
+
+
+ Per-trade cap: ${live.maxPerTrade?.toFixed(2) || '5.00'}
+ Daily limit: ${live.maxDailyLoss?.toFixed(2) || '20.00'}
+
+
+
+ {/* Market Card */}
+
+
+ {/* Strategy Toggles */}
+
+
+
โก Strategy Controls
+
+ {strategies.map((s, i) => {
+ const isEnabled = enabledSet.has(s.name);
+ const isToggling = toggling === s.name;
+ return (
+
+
+
+
+
{s.name}
+ {s.config && (
+
+ ${s.config.betSize || 1}/trade โข {s.config.cooldownMs ? `${(s.config.cooldownMs/1000).toFixed(0)}s cd` : ''}
+
+ )}
+
+
+
+
+ );
+ })}
+ {strategies.length === 0 && (
+
No strategies loaded yet.
+ )}
+
+
+ {/* Open Orders */}
+ {live.openOrders?.length > 0 && (
+
+
+ Open Orders ({live.openOrders.length})
+
+ {live.openOrders.map((o, i) => (
+
+ ))}
+
+ )}
+
+ {/* Kalshi Positions */}
+ {live.positions?.length > 0 && (
+
+
+ Kalshi Positions ({live.positions.length})
+
+ {live.positions.map((p, i) => (
+
+
+ {p.market_ticker || p.ticker}
+ {p.position_fp || p.position || 0} contracts
+
+ {p.realized_pnl_dollars && (
+
+ Realized PnL: = 0 ? 'text-green-400' : 'text-red-400'}>
+ ${Number(p.realized_pnl_dollars).toFixed(2)}
+
+
+ )}
+
+ ))}
+
+ )}
+
+ {/* Trade History */}
+
+
+ Trade History ({trades.length})
+
+ {trades.length === 0 ? (
+
No settled trades yet. Enable a strategy to start.
+ ) : (
+ trades.map((t, i) =>
)
+ )}
+
+
+
+ {/* Footer */}
+
+
+ Worker: {formatUptime(data?.workerUptime)}
+ {data?.lastUpdate ? new Date(data.lastUpdate).toLocaleTimeString() : 'never'}
+
);
}
+
+function MarketCard({ market }) {
+ if (!market) {
+ return (
+
+
No active market โ waiting...
+
+ );
+ }
+
+ const timeLeft = market.closeTime ? getTimeLeft(market.closeTime) : null;
+
+ return (
+
+
+
+
BTC Up or Down
+
15 min
+
+
+ {timeLeft && (
+ โฑ {timeLeft}
+ )}
+ โฟ
+
+
+
+
+
+ Up
+ {market.yesPct}%
+
+
+
+
+
+ Down
+ {market.noPct}%
+
+
+
+
+
+ ${(market.volume || 0).toLocaleString()} vol
+ {market.ticker}
+
+
+ );
+}
+
+function LiveOrderRow({ order, isOpen }) {
+ const won = order.result && order.side?.toLowerCase() === order.result?.toLowerCase();
+ const isNeutral = order.result === 'cancelled' || order.result === 'expired';
+ const pnlVal = order.pnl != null ? (typeof order.pnl === 'number' && Math.abs(order.pnl) > 50 ? order.pnl / 100 : order.pnl) : null;
+ const pnlColor = pnlVal == null ? 'text-gray-600' : pnlVal > 0 ? 'text-green-400' : pnlVal < 0 ? 'text-red-400' : 'text-gray-400';
+
+ return (
+
+
+
+ {isOpen ? (
+
+ ) : (
+ {isNeutral ? 'โ' : won ? 'โ
' : 'โ'}
+ )}
+ {order.side}
+ @ {order.priceCents || order.price}ยข
+ {order.contracts || 1}x
+
+
+ {pnlVal != null ? `${pnlVal >= 0 ? '+' : ''}$${pnlVal.toFixed(2)}` : 'open'}
+
+
+
+ {order.reason}
+ {order.strategy}
+
+ {order.result && !isOpen && (
+
+ Result: {order.result}
+
+ {order.settleTime ? new Date(order.settleTime).toLocaleTimeString() : order.createdAt ? new Date(order.createdAt).toLocaleTimeString() : ''}
+
+
+ )}
+
+ );
+}
+
+function StatBox({ label, value, color, dark }) {
+ return (
+
+ );
+}
+
+function getTimeLeft(closeTime) {
+ const diff = new Date(closeTime).getTime() - Date.now();
+ if (diff <= 0) return 'Closing...';
+ const mins = Math.floor(diff / 60000);
+ const secs = Math.floor((diff % 60000) / 1000);
+ return `${mins}:${secs.toString().padStart(2, '0')}`;
+}
+
+function formatUptime(seconds) {
+ if (!seconds) return '0s';
+ const h = Math.floor(seconds / 3600);
+ const m = Math.floor((seconds % 3600) / 60);
+ const s = Math.floor(seconds % 60);
+ if (h > 0) return `${h}h ${m}m`;
+ if (m > 0) return `${m}m ${s}s`;
+ return `${s}s`;
+}