Polymarket vs Kalshi
How the two prediction-market venues differ in Scalar Field: chat discovery, scalarlib data functions,venue.* / strategy.* trading, funding, and settlement.
Both are first-class venues. Chat writes Python in execute_code, screens markets, then trades with venue.trade(...). The loop is the same; the APIs, symbols, cash, and fill models are not.
Quick contrast
Chat
Neither venue has a built-in market list in the prompt. The agent must look up docs, then call a screener.
Unified helper (both catalogs):
searchPredictionMarkets(query, venue="polymarket"|"kalshi"). Event tags apply to Polymarket only.
When speaking to the user about Kalshi, describe YES vs NO in plain language. Do not mention internal ticker encodings.
Market discovery (screeners)
Shared
query,closed,min_volume,min_price/max_price(0–1),start_date/end_date(YYYY-MM-DD),sort_by(volumeorcreated_at),limit,offset- No Kalshi/Polymarket login required
screenPolymarkets only
Returns (among others):
market_id, market_question, market_outcomes, market_outcome_prices, token_ids (list, one CLOB token per outcome), winning_outcome_index, market_accepting_orders, event_title.
closed=True is not the same as resolved. Use winning_outcome_index (set only when settled).
screenKalshiMarkets only
Every row also carries
close_time (expiration) and created_time (when listed). Catalog tables additionally store open_time, updated_time, and settled_time; those are not returned by the screener today.
Returns (among others): ticker, title, symbol (YES trade handle), symbol_no (NO trade handle), yes_bid / yes_ask / no_bid / no_ask, last_price, volume, open_interest, close_time, created_time, price_ranges, event_title.
With query, results come from Kalshi’s /v1/search/series (relevance-ranked, one page). Without query, from GET /markets (one page; volume sort is within that page).
screenKalshiEvents
Kalshi-only. Lists events (event_ticker, title, category, status, close_time), optionally with nested markets. Polymarket folds event fields into screenPolymarkets (event_id, event_title, event_slug).
Event status query values are "open", "closed", "settled", or omit/None for any. Other values, including "active" and "finalized", raise ValueError before the request. The filter matches events that have at least one child market in that state. Event-row status is often null.
Data functions
Market data is public on both. Polymarket has a larger analytics surface because trades and positions are on-chain.
Kalshi candles try
/series/{series}/markets/{ticker}/candlesticks first, then GET /historical/markets/{ticker}/candlesticks for archived settled markets.
Trading (venue.*)
Same entry points: venue.account, venue.positions, venue.balances, venue.history, venue.trade, venue.cancel, strategy.execute / strategy.place_limit.
Symbols
Order types and fills
During the Thursday ET pause, placement fails (
TRADING_PAUSED); cancels still work. Kalshi limit TIF is hardwired to GTC (not caller-selectable); market orders are synthesized IOC.
venue.account / cash
Low Polymarket buying power → chat should emit
deposit_request with venue POLYMARKET. Kalshi funding is not a Scalar deposit card — tell the user to fund at Kalshi.
History
Kalshi live APIs drop orders/fills older than ~3 months; Scalar merges
/historical/* so portfolio history is not truncated. Public getKalshiTrades / getKalshiCandles fail over to Kalshi’s historical market-data endpoints.
Kalshi trade rows use complement encoding: closing YES at $0.43 can print as side=sell, outcome=NO, price=0.57, amount=0.57. Gross cash is qty × (1 − recorded_price) on that shape — amount is quoted notional, not proceeds. Full formulas: Trading on Kalshi.
Cancel / replace
Cancel / replace
Both support cancel of resting limits. Kalshi uses V2DELETE /portfolio/events/orders/{id}. Unknown or already-cancelled Kalshi orders can fail with a raw HTTP 410 from a legacy V1 fallback — that is not CANCEL_NOT_SUPPORTED. Kalshi replace_order is cancel-and-replace (new broker id). Stops are unsupported on both.
Settlement
Polymarket. Aftermarket_end_date, the market stops accepting orders. A closed market may still be awaiting resolution (winning_outcome_index is None). Winning tokens are not paid until venue.trade("redeem", token_id, ...). Selling a resolved market fails with MARKET_RESOLVED_USE_REDEEM. redeem is Polymarket-only (REDEEM_NOT_SUPPORTED on Kalshi).
Kalshi. Winning contracts pay $1 automatically. No redeem call. Settled positions show up in venue.history(category="settlement"). venue.trade on a closed/settled/finalized market fails with a ValueError (… is {status} and cannot be traded). Strategy layer may surface that as MARKET_CLOSED.
Connect and credentials
Paper Polymarket needs no connect.
Strategies (strategy.*)
Fees and ticks
- Polymarket: Platform fee plus taker fee;
fee_bps/fee_amount(and taker fields) on the trade response when active. Limit prices usually on a 0.001 grid; live CLOB may reject off-tick (PRICE_NOT_ON_TICK). - Kalshi: Exchange
fee_coston fills (trade fee + rounding − rebate).venue.trade()may omit finalized fees (average_fee_paidonly whenfill_count > 0, returned asfeesnotfee_amount). Usevenue.historyfor fee/cash accounting. Prices snapped to each market’sprice_ranges(often 0.01). Qty min 0.01 contracts, truncated to 2 dp.
Frontend vs chat
The Markets explorer (GET /polymarket/markets and GET /kalshi/markets) and chat do not share a UI. Both screens eventually call the same catalog functions (screenPolymarkets / screenKalshiMarkets). Chat never opens those pages; it only runs scalarlib in the notebook kernel.
What to use when
- Search a topic, then trade a probability — same pattern on both; pick the venue the user named (or both via
searchPredictionMarkets). - Copy a wallet / whale flow / leaderboard — Polymarket only.
- OHLC finer than 1h except 1m — Polymarket (
5min/15min/30min). Kalshi is 1m / 1h / 1d. - Practice without funding —
POLYMARKET_PAPER. There is no Kalshi paper. - USD in a CFTC venue, cash already on Kalshi —
KALSHI. - On-chain PUSD / Polygon wallet —
POLYMARKET+WALLET_POL. - Settle a resolved position —
redeemon Polymarket; wait for automatic settlement on Kalshi.