Skip to main content

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 (volume or created_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 V2 DELETE /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. After market_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_cost on fills (trade fee + rounding − rebate). venue.trade() may omit finalized fees (average_fee_paid only when fill_count > 0, returned as fees not fee_amount). Use venue.history for fee/cash accounting. Prices snapped to each market’s price_ranges (often 0.01). Qty min 0.01 contracts, truncated to 2 dp.
Neither venue in this integration supports Kalshi-style perpetual futures / margin.

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 fundingPOLYMARKET_PAPER. There is no Kalshi paper.
  • USD in a CFTC venue, cash already on KalshiKALSHI.
  • On-chain PUSD / Polygon walletPOLYMARKET + WALLET_POL.
  • Settle a resolved positionredeem on Polymarket; wait for automatic settlement on Kalshi.