[object Object]

← back to Ken

auto-save: 2026-08-03T07:51:47 (1 files) — kalshi-dash/server.js

5e77ebc8c9927a5d2b4929bfc4d7e0055c8c8cf4 · 2026-08-03 07:52:03 -0700 · Steve Abrams

Files touched

Diff

commit 5e77ebc8c9927a5d2b4929bfc4d7e0055c8c8cf4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 07:52:03 2026 -0700

    auto-save: 2026-08-03T07:51:47 (1 files) — kalshi-dash/server.js
---
 kalshi-dash/server.js | 52 +++++++++++++++++++++++++++++----------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index e7f1ee4..bd37d74 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -8870,31 +8870,39 @@ async function resolvePortfolioTrades() {
         WHERE ticker = $1 ORDER BY captured_at DESC LIMIT 1
       `, [trade.market_id]);
 
-      if (snaps.length === 0) continue;
-      const currentPrice = parseInt(snaps[0].last_price);
       const ageMinutes = (Date.now() - new Date(trade.created_at).getTime()) / 60000;
-
-      let pnl = 0;
-      if (trade.direction === 'BUY_YES') {
-        pnl = (currentPrice - trade.entry_price_cents) * trade.contracts;
+      let currentPrice, pnl = 0, status = null;
+
+      if (snaps.length === 0) {
+        // No price snapshot for this market. Previously this `continue`d forever,
+        // freezing the position and never crediting the stake back. Instead, age it
+        // out NEUTRALLY after 2h: exit at entry price → zero P&L, stake returned.
+        if (ageMinutes < 120) continue; // still young — wait for a price to appear
+        currentPrice = trade.entry_price_cents;
+        pnl = 0;
+        status = 'expired';
       } else {
-        pnl = (trade.entry_price_cents - currentPrice) * trade.contracts;
-      }
+        currentPrice = parseInt(snaps[0].last_price);
+        if (trade.direction === 'BUY_YES') {
+          pnl = (currentPrice - trade.entry_price_cents) * trade.contracts;
+        } else {
+          pnl = (trade.entry_price_cents - currentPrice) * trade.contracts;
+        }
 
-      // Hyper-trade exit rules:
-      // 1. Take profit: +3¢ per contract (minimum 5 min hold)
-      // 2. Stop loss: -5¢ per contract (minimum 5 min hold)
-      // 3. Age out: close after 2 hours regardless
-      let status = null;
-      const profitPerContract = pnl / Math.max(1, trade.contracts);
-
-      if (ageMinutes >= 5 && profitPerContract >= 3) {
-        status = 'won'; // Take profit
-      } else if (ageMinutes >= 5 && profitPerContract <= -5) {
-        status = 'lost'; // Stop loss
-      } else if (ageMinutes >= 120) {
-        // Age out after 2 hours — mark based on current P&L
-        status = pnl > 0 ? 'won' : pnl < 0 ? 'lost' : 'expired';
+        // Hyper-trade exit rules:
+        // 1. Take profit: +3¢ per contract (minimum 5 min hold)
+        // 2. Stop loss: -5¢ per contract (minimum 5 min hold)
+        // 3. Age out: close after 2 hours regardless
+        const profitPerContract = pnl / Math.max(1, trade.contracts);
+
+        if (ageMinutes >= 5 && profitPerContract >= 3) {
+          status = 'won'; // Take profit
+        } else if (ageMinutes >= 5 && profitPerContract <= -5) {
+          status = 'lost'; // Stop loss
+        } else if (ageMinutes >= 120) {
+          // Age out after 2 hours — mark based on current P&L
+          status = pnl > 0 ? 'won' : pnl < 0 ? 'lost' : 'expired';
+        }
       }
 
       if (!status) continue; // Hold position

← 05c7572 Ken: FIX resolver never settling — trades inserted with empt  ·  back to Ken  ·  Ken v2 follow-the-winners signal: durable win-record source 5735837 →