Skip to content

mostlyright.markets.kalshi_trades

Kalshi trade-history public surface — Phase 9 (TRADES-01..03).

Three read-only entry points over the public Kalshi REST API:

  • candles() — OHLCV bars at a chosen interval.
  • fills() — historical trade prints, paginated by cursor.
  • orderbook() — current book snapshot.

All three return pandas.DataFrame with a source="kalshi" column preserved per row so downstream pd.concat / merge keep source-identity intact (the v0.1.0 invariant).

No authentication required; no Kalshi API key needed. Calls go to the documented public endpoints under api.elections.kalshi.com.

Lives at flat module name mostlyright.markets.kalshi_trades (rather than a hypothetical mostlyright.markets.kalshi.trades subpackage) because the existing mostlyright.markets.catalog.kalshi_* modules already use the catalog/ namespace for contract metadata; trades data is a separate flat module to avoid restructuring the catalog package layout. Phase 10 may revisit the namespace if a top-level mostlyright.markets.kalshi aggregate becomes desirable.

INTERVALSSupported candle intervals → seconds.
candles(ticker, *, interval, from_, to[, …])OHLCV candles for ticker between from_ and to.
fills(ticker, *[, since, until, client, …])Historical fills for ticker, paginated until cursor exhausts.
orderbook(ticker, *[, depth, client, …])Current orderbook snapshot for ticker.

mostlyright.markets.kalshi_trades.INTERVALS : dict[str, int] = {‘1d’: 86400, ‘1h’: 3600, ‘1m’: 60}

Section titled “mostlyright.markets.kalshi_trades.INTERVALS : dict[str, int] = {‘1d’: 86400, ‘1h’: 3600, ‘1m’: 60}”

Supported candle intervals → seconds. Kalshi documents 1-minute, 1-hour, and 1-day candles; the seconds → minutes conversion at the call site reflects Kalshi’s period_interval being in minutes.

mostlyright.markets.kalshi_trades.candles(ticker, , interval, from_, to, client=None, sleep_between=None)

Section titled “mostlyright.markets.kalshi_trades.candles(ticker, , interval, from_, to, client=None, sleep_between=None)”

OHLCV candles for ticker between from_ and to.

  • Parameters:
    • ticker (str) – Full Kalshi market ticker (e.g. "KXHIGHNY-25MAY26-T79").
    • interval (str) – Candle granularity — one of INTERVALS keys ("1m", "1h", "1d").
    • from – tz-aware UTC datetimes bounding the window.
    • to (datetime) – tz-aware UTC datetimes bounding the window.
    • client (Client | None) – Optional shared httpx.Client.
    • sleep_between (float | None) – Per-request polite-sleep override (tests pass 0).
    • from_ (datetime)
  • Returns:
    • ts (datetime UTC): end-of-period timestamp.
    • open / high / low / close (float | None): OHLC in cents (0.0-100.0, subpenny precision preserved). Conversion from the Kalshi FixedPointDollars wire format (e.g. "0.5600") is cents = float(api_string) * 100 per the canonical packages/core/.../specs/candle.json contract.
    • volume (int | None): contracts traded in the bucket.
    • open_interest (int | None): contracts outstanding at bucket end.
    • source (str): always "kalshi".
  • Return type: pd.DataFrame with columns
  • Raises:

mostlyright.markets.kalshi_trades.fills(ticker, , since=None, until=None, client=None, sleep_between=None, max_pages=10000)

Section titled “mostlyright.markets.kalshi_trades.fills(ticker, , since=None, until=None, client=None, sleep_between=None, max_pages=10000)”

Historical fills for ticker, paginated until cursor exhausts.

  • Parameters:
    • ticker (str) – Full Kalshi market ticker.
    • since (datetime | None) – Optional tz-aware UTC datetime bounds.
    • until (datetime | None) – Optional tz-aware UTC datetime bounds.
    • client (Client | None) – Optional shared httpx.Client.
    • sleep_between (float | None) – Per-request polite-sleep override.
    • max_pages (int) – Safety cap on cursor pagination (defaults to 10k pages = 10M trades). Raises RuntimeError if exceeded.
  • Returns:
    • trade_id (str | None)
    • ts (datetime UTC | None)
    • yes_price / no_price (float | None): cents (0.0-100.0, subpenny precision). Converted from Kalshi’s yes_price_dollars/no_price_dollars FixedPointDollars strings via cents = float(s) * 100.
    • count (int | None): contracts in this fill. Read from count_fp (Kalshi’s FixedPoint integer string) and converted to int.
    • taker_side (str | None): "yes" / "no" / None. Read from Kalshi’s taker_outcome_side.
    • source (str): always "kalshi".
  • Return type: DataFrame with columns
  • Raises:
    • TypeErrorsince / until not tz-aware datetimes when set.
    • ValueErrorsince >= until when both set.

mostlyright.markets.kalshi_trades.orderbook(ticker, , depth=50, client=None, sleep_between=None)

Section titled “mostlyright.markets.kalshi_trades.orderbook(ticker, , depth=50, client=None, sleep_between=None)”

Current orderbook snapshot for ticker.

  • Parameters:

    • ticker (str) – Full Kalshi market ticker.
    • depth (int) – Number of price levels per side (default 50; Kalshi documented max varies — capped at 1000 in the client).
    • client (Client | None) – Optional shared httpx.Client.
    • sleep_between (float | None) – Per-request polite-sleep override.
  • Returns:

    • side (str): "yes" or "no".
    • price (float | None): price in cents (0.0-100.0). Converted from Kalshi’s orderbook_fp.{yes_dollars,no_dollars} levels (each level is [price_dollar_string, count_fp_string]) via cents = float(price_dollar_string) * 100.
    • size (int | None): contracts at this level (parsed from count_fp_string).
    • source (str): always "kalshi".

    Snapshot timestamp lives in df.attrs["snapshot_at"] (no per-row column because every row has the same wall-clock instant).

  • Return type: DataFrame, one row per (side, price level)