← back to Ken
Ken: near-term + real-book filter (Steve) — scan now only trades markets closing within 120 days with a two-sided book; real-trade path also requires yes_ask/yes_bid (not stale last_price) + near-term. Stops winners building track records on far-future longshots (2028-2045) that have no live order book to bet real money against.
b2c914b30f3598dda676ac1a1872740eab49c16e · 2026-08-03 10:57:49 -0700 · steve@designerwallcoverings.com
Files touched
Diff
commit b2c914b30f3598dda676ac1a1872740eab49c16e
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Mon Aug 3 10:57:49 2026 -0700
Ken: near-term + real-book filter (Steve) — scan now only trades markets closing within 120 days with a two-sided book; real-trade path also requires yes_ask/yes_bid (not stale last_price) + near-term. Stops winners building track records on far-future longshots (2028-2045) that have no live order book to bet real money against.
---
kalshi-dash/server.js | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index aa3edf9..48fbe4a 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -7537,8 +7537,13 @@ async function getWinnerConsensusSignals() {
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;
+ // Real bets need a real two-sided book (an ask to buy against), not just a stale last_price.
+ yesPrice = m.yes_ask || m.yes_bid || null;
if (m.status && m.status !== 'active') continue; // skip closed/settled markets
+ // NEAR-TERM guard: never place real money on a far-future market (2028-2045 longshots have
+ // no live liquidity). Match the scan's 120-day window.
+ const ct = m.close_time ? new Date(m.close_time).getTime() : 0;
+ if (!(ct > Date.now() && (ct - Date.now()) < 120 * 24 * 60 * 60 * 1000)) continue;
} catch { continue; } // ticker not tradeable right now → skip (never guess a price)
if (!yesPrice || yesPrice <= 5 || yesPrice >= 95) continue;
out.push({
@@ -7907,8 +7912,18 @@ async function autonomousScan() {
const volumeIdeas = [];
// Sort by 24h volume to find what's hot
+ // NEAR-TERM + LIQUID gate (2026-08-03, Steve): only trade markets with a real two-sided book
+ // AND closing within ~120 days. Without the close-date gate, winners built their track record on
+ // far-future longshots (2028-2045 events) that have NO live order book when it's time to place a
+ // real bet — the exact reason getWinnerConsensusSignals kept returning "no tradeable consensus".
+ const NEAR_TERM_MS = 120 * 24 * 60 * 60 * 1000;
+ const nowMs = Date.now();
const activeMarkets = allMarkets
- .filter(m => m.yes_bid > 0 && m.yes_ask > 0 && m.yes_ask < 100 && m.last_price > 0)
+ .filter(m => {
+ if (!(m.yes_bid > 0 && m.yes_ask > 0 && m.yes_ask < 100 && m.last_price > 0)) return false;
+ const ct = m.close_time ? new Date(m.close_time).getTime() : 0;
+ return ct > nowMs && (ct - nowMs) < NEAR_TERM_MS; // near-term, not already closed
+ })
.sort((a, b) => b.volume_24h - a.volume_24h);
// Cache for 5-minute signal pipeline
← 2976075 Ken: MIN_RESOLVED 100->50 (Steve, 2026-08-03) — let real tra
·
back to Ken
·
Ken: carry close_time into allMarkets — the near-term filter afc629c →