Exchange
kalshi
Severity
MEDIUM
What Our Normalizer Expects
core/src/exchanges/kalshi/normalizer.ts reads only YES-side prices (yes_ask_dollars, yes_bid_dollars) and derives the NO price as 1 - yesPrice. The NO-side spread is lost.
// normalizer.ts ~lines 53-54
const yesBid = parseFloat(raw.yes_bid_dollars ?? ...);
const yesAsk = parseFloat(raw.yes_ask_dollars ?? ...);
// noPrice = 1 - yesPrice (computed, not from API)
What The Live API Returns
The live /markets endpoint exposes explicit NO-side bid and ask prices that the normalizer never reads:
markets[].yes_ask_dollars: str ← extracted
markets[].yes_bid_dollars: str ← extracted
markets[].no_ask_dollars: str ← NEW, not extracted
markets[].no_bid_dollars: str ← NEW, not extracted
Endpoint tested: GET https://api.elections.kalshi.com/trade-api/v2/markets?limit=1
Impact
MEDIUM: In a binary market, YES and NO prices should sum to ~1, but in practice there is a spread between them. By computing noPrice = 1 - yesPrice rather than reading the actual no_ask_dollars/no_bid_dollars, the normalizer loses the NO-side spread. This can misrepresent executable prices for NO orders and degrades the accuracy of the order book display for NO contracts.
Suggested Fix
Extract the NO-side prices directly from the API response:
noAsk: parseFloat(raw.no_ask_dollars ?? '0'),
noBid: parseFloat(raw.no_bid_dollars ?? '0'),
Also add no_ask_dollars?: string and no_bid_dollars?: string to KalshiRawMarket.
Found by automated response shape drift audit
Exchange
kalshi
Severity
MEDIUM
What Our Normalizer Expects
core/src/exchanges/kalshi/normalizer.tsreads only YES-side prices (yes_ask_dollars,yes_bid_dollars) and derives the NO price as1 - yesPrice. The NO-side spread is lost.What The Live API Returns
The live
/marketsendpoint exposes explicit NO-side bid and ask prices that the normalizer never reads:Endpoint tested:
GET https://api.elections.kalshi.com/trade-api/v2/markets?limit=1Impact
MEDIUM: In a binary market, YES and NO prices should sum to ~1, but in practice there is a spread between them. By computing
noPrice = 1 - yesPricerather than reading the actualno_ask_dollars/no_bid_dollars, the normalizer loses the NO-side spread. This can misrepresent executable prices for NO orders and degrades the accuracy of the order book display for NO contracts.Suggested Fix
Extract the NO-side prices directly from the API response:
Also add
no_ask_dollars?: stringandno_bid_dollars?: stringtoKalshiRawMarket.Found by automated response shape drift audit