[object Object]

← back to Ken

Ken: migrate live buy order to Kalshi v2 create-order (POST /portfolio/events/orders)

b2420a9fee63cea7937c428370ad85322d64cd33 · 2026-08-03 10:32:18 -0700 · Steve Abrams

v1 POST /portfolio/orders now 410s (deprecated_v1_order_endpoint) — no real order could place. v2 single YES-book: bid=buy YES, ask=sell YES(=buy NO), price=YES price in dollars, +required self_trade_prevention_type + client_order_id idempotency key. Fixes zero-fills on the live $50 run. Exit sells (TP/SL) left on v1 as a flagged follow-up; positions still resolve at settlement.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit b2420a9fee63cea7937c428370ad85322d64cd33
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 10:32:18 2026 -0700

    Ken: migrate live buy order to Kalshi v2 create-order (POST /portfolio/events/orders)
    
    v1 POST /portfolio/orders now 410s (deprecated_v1_order_endpoint) — no real order could place. v2 single YES-book: bid=buy YES, ask=sell YES(=buy NO), price=YES price in dollars, +required self_trade_prevention_type + client_order_id idempotency key. Fixes zero-fills on the live $50 run. Exit sells (TP/SL) left on v1 as a flagged follow-up; positions still resolve at settlement.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 kalshi-dash/server.js | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/kalshi-dash/server.js b/kalshi-dash/server.js
index 0427969..3766cd3 100644
--- a/kalshi-dash/server.js
+++ b/kalshi-dash/server.js
@@ -7734,18 +7734,23 @@ async function autoTrader(signals) {
 
       try {
         const side = sig.side === 'NO' ? 'no' : 'yes';
-        const order = await kalshiFetch('POST', '/portfolio/orders', {
+        // v2 create-order — Kalshi retired v1 POST /portfolio/orders (410 deprecated_v1_order_endpoint).
+        // Single YES-book model: bid = buy YES, ask = sell YES (economically ≡ buy NO). `price` is the
+        // YES price in DOLLARS (string). priceCents (=sig.entry_price) is the cost of the CHOSEN side
+        // (YES→yes_price, NO→no_price), so the YES price = priceCents for YES, (100-priceCents) for NO.
+        const v2Side = side === 'yes' ? 'bid' : 'ask';
+        const yesPriceCents = side === 'yes' ? priceCents : (100 - priceCents);
+        const order = await kalshiFetch('POST', '/portfolio/events/orders', {
           ticker: sig.ticker,
-          side: side,
-          action: 'buy',
-          type: 'limit',
-          count: count,
-          yes_price: side === 'yes' ? priceCents : undefined,
-          no_price: side === 'no' ? (100 - priceCents) : undefined,
-          time_in_force: 'gtc',
+          side: v2Side,
+          count: count.toFixed(2),
+          price: (yesPriceCents / 100).toFixed(2),
+          time_in_force: 'good_till_canceled',
+          self_trade_prevention_type: 'taker_at_cross',
+          client_order_id: crypto.randomUUID(),
         });
 
-        const orderId = order.order?.order_id || `ken_${Date.now()}`;
+        const orderId = order.order_id || order.order?.order_id || `ken_${Date.now()}`;
         await kenQ(`INSERT INTO ken_trades (ticker, event_ticker, title, side, action, price_cents, count, cost_cents, order_id, signal_type, confidence, reasoning, status)
           VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, 'open')`,
           [sig.ticker, sig.event_ticker || '', sig.market || '', side, 'buy', priceCents, count, totalCost,

← 259b896 Ken: reconcile-canary self-alerts to CNCP parking-lot on div  ·  back to Ken  ·  Ken: MIN_RESOLVED 100->50 (Steve, 2026-08-03) — let real tra 2976075 →