[object Object]

← back to Ken

Ken v2 GO-LIVE wiring: live orders follow profitable-winner consensus w/ live-price fetch; NOT the weather engine (TK-10166)

b9768ef24385067041f02faa9b3112355ab2f214 · 2026-08-03 08:58:54 -0700 · Steve Abrams

Files touched

Diff

commit b9768ef24385067041f02faa9b3112355ab2f214
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 08:58:54 2026 -0700

    Ken v2 GO-LIVE wiring: live orders follow profitable-winner consensus w/ live-price fetch; NOT the weather engine (TK-10166)
---
 kalshi-dash/server.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index bd37d74..d2a2692 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -7478,6 +7478,59 @@ async function getTraderState() {
   }
 }
 
+// ── Ken v2 LIVE SIGNAL (Steve, 2026-08-03, TK-10166) ──────────────────────────
+// Real orders follow the PROFITABLE faux-portfolio winners' unanimous consensus —
+// NOT the synthetic-weather engine. A market qualifies only when >= MIN_AGREE of the
+// portfolios that are BOTH >=60% win-rate AND net-profitable over >=20 resolved trades
+// currently hold the SAME direction. entry_price is refreshed to the LIVE Kalshi YES
+// price so the trader's yes/no price math is correct (paper stores NO-cost, not YES).
+async function getWinnerConsensusSignals() {
+  const MIN_RESOLVED = 20, WIN_GATE = 0.60, MIN_AGREE = 2, MAX_MARKETS = 8;
+  try {
+    const { rows } = await kenQ(`
+      WITH winners AS (
+        SELECT p.id, p.name FROM ken_portfolios p JOIN ken_daily_pnl d ON d.portfolio_id = p.id
+        GROUP BY p.id, p.name
+        HAVING SUM(d.wins)+SUM(d.losses) >= ${MIN_RESOLVED}
+           AND SUM(d.wins)::float/NULLIF(SUM(d.wins)+SUM(d.losses),0) >= ${WIN_GATE}
+           AND SUM(d.daily_pnl_cents) > 0)
+      SELECT t.market_id AS ticker, t.market_title, t.direction,
+             count(DISTINCT t.portfolio_id) AS agree,
+             string_agg(DISTINCT w.name, '/') AS who
+      FROM ken_portfolio_trades t JOIN winners w ON w.id = t.portfolio_id
+      WHERE t.status='open'
+      GROUP BY t.market_id, t.market_title, t.direction
+      HAVING count(DISTINCT t.portfolio_id) >= ${MIN_AGREE}
+      ORDER BY agree DESC LIMIT ${MAX_MARKETS}`);
+
+    const out = [];
+    for (const r of rows) {
+      const side = r.direction === 'BUY_NO' ? 'NO' : 'YES';
+      // Refresh to the LIVE market price (YES price) so order math is correct.
+      let yesPrice = null;
+      try {
+        const md = await kalshiPublicFetch('GET', `/markets/${encodeURIComponent(r.ticker)}`);
+        const m = md.market || md;
+        yesPrice = m.yes_ask || m.yes_bid || m.last_price || null;
+        if (m.status && m.status !== 'active') continue; // skip closed/settled markets
+      } catch { continue; } // ticker not tradeable right now → skip (never guess a price)
+      if (!yesPrice || yesPrice <= 5 || yesPrice >= 95) continue;
+      out.push({
+        ticker: r.ticker, event_ticker: '', market: r.market_title, side,
+        entry_price: yesPrice,                                   // YES price in cents (live)
+        confidence: Math.min(95, 60 + Number(r.agree) * 12),     // >=2 agree -> >=84
+        sources: (r.who || '').split('/').filter(Boolean),       // winner names (>=2)
+        signal_type: 'follow_winners',
+        reason: `${r.agree} profitable winners (${r.who}) agree ${side} @ live ${yesPrice}¢`,
+      });
+    }
+    return out;
+  } catch (e) {
+    console.log('[Ken] follow-winners signal error:', e.message);
+    return [];
+  }
+}
+
 async function autoTrader(signals) {
   if (!TRADE_CONFIG.enabled) return;
 
@@ -7496,6 +7549,14 @@ async function autoTrader(signals) {
       return; // safe/paper — market data + paper trading only, no real-money orders
     }
 
+    // Ken v2 (TK-10166): LIVE orders follow the profitable faux-portfolio winners,
+    // NOT the weather-scan signals passed in. Replace the signal source here.
+    signals = await getWinnerConsensusSignals();
+    if (!signals.length) {
+      console.log('[Ken] TRADER: no profitable-winner consensus right now — no real trades this cycle.');
+      // fall through: still run exit checks on any open real positions below.
+    }
+
     const state = await getTraderState();
 
     // Daily loss limit check

← ae4735c auto-save: 2026-08-03T08:52:19 (1 files) — kalshi-dash/.giti  ·  back to Ken  ·  Ken: fix resolver 270x portfolio over-credit — settle idempo e7e3c8c →