Skip to main content
Kalshi is a CFTC-regulated prediction market in the United States. Horizon supports the Kalshi REST API with bearer token authentication and automatic retry on 401.

Quick Setup

hz.run(
    name="kalshi_mm",
    exchange=hz.Kalshi(api_key="..."),
    mode="live",
    ...
)

Credentials

hz.Kalshi(api_key="your_api_key")

Kalshi Configuration

@dataclass
class Kalshi:
    email: str | None = None
    password: str | None = None
    api_key: str | None = None
    api_url: str = "https://trading-api.kalshi.com/trade-api/v2"
FieldDefaultDescription
emailNoneKalshi account email
passwordNoneKalshi account password
api_keyNoneKalshi API key (preferred)
api_urlhttps://trading-api.kalshi.com/trade-api/v2API base URL

Demo Environment

Kalshi provides a demo environment for testing:
hz.Kalshi(
    api_key="...",
    api_url="https://demo-api.kalshi.co/trade-api/v2",
)
Use the demo environment to test your strategy with real market data but fake money. You can also override the URL via the KALSHI_API_URL environment variable.

Ticker Mapping

Kalshi markets use tickers (e.g., KXBTC-25FEB16) instead of slugs. When mode="live", Horizon automatically sets the ticker from the market ID:
# Market ID is used as the ticker (uppercased)
hz.run(markets=["KXBTC-25FEB16"], ...)
Or set it explicitly:
market = hz.Market(
    id="btc-100k",
    ticker="KXBTC-25FEB16",
    exchange="kalshi",
)

Side Mapping

Kalshi uses two separate concepts for order direction:
ConceptValuesDescription
actionbuy / sellWhether you’re buying or selling (OrderSide)
sideyes / noWhich outcome you’re trading (Side)
This means “buy yes”, “sell yes”, “buy no”, and “sell no” are all valid combinations.

Authentication

Kalshi uses bearer token authentication:
  1. On first request, the client authenticates with API key (or email/password)
  2. Receives a bearer token
  3. Token is included in subsequent requests via Authorization: Bearer <token>
  4. On 401 response, the client automatically re-authenticates and retries (loop-based, not recursive)

Fill Polling

Kalshi fills are polled from the /portfolio/fills endpoint. Each cycle:
  1. Queries recent fills with tracked order IDs
  2. Deduplicates against previously seen fill IDs
  3. Maps Kalshi’s price format (cents) and timestamps to Horizon’s format

Feature Support Matrix

FeaturePolymarketKalshi
Trading (orders/fills)YesYes
Orderbook feedYes (WS)Yes (REST)
Market discoveryYesYes
Cross-exchange arbitrageYesYes
LLM forecastingYesYes
Resolution analysisYesYes
Resolution snipingYesYes
Oracle ensembleFull (6 signals)Partial (3 signals)
Flow analysisYesNo (no on-chain data)
Whale trackingYesNo
Copy tradingYesNo
Wallet intelligenceYesNo
The oracle ensemble runs all 6 signal extractors on Kalshi, but signals that depend on Polymarket on-chain data (smart money flow, microstructure, holder concentration) return neutral (0.5). The remaining signals (momentum, volume profile, temporal patterns) also return neutral since Kalshi has no public trade-level data. LLM forecasting and resolution analysis work fully on both exchanges.

Intelligence Suite with Kalshi

All intelligence tools accept an exchange parameter:
# Resolution analysis
analysis = hz.analyze_resolution("KXBTC100K", exchange="kalshi")

# LLM scan
edges = hz.llm_scan(exchange="kalshi")

# Oracle forecast
forecast = hz.forecast_market("KXBTC100K", exchange="kalshi")

# Edge scanning
edges = hz.scan_edges(exchange="kalshi")

MCP Server

MCP tools also accept the exchange parameter:
  • analyze_resolution(market_id, exchange="kalshi")
  • llm_scan(exchange="kalshi")
  • sniper_scan(exchange="kalshi")
  • oracle_forecast(market_id, exchange="kalshi")
  • oracle_edges(exchange="kalshi")