Skip to content

mostlyright.markets.economy_trades

Kalshi venue price-history for SETTLED economy markets.

candles(...) retrieves Kalshi OHLC candlesticks for a settled economics market. It is the venue-history companion to mostlyright.economy.research_economy: where research_economy produces the leakage-safe settlement pairs, this returns the traded price panel for a settled economy contract.

How deep the public API reaches, as measured. The fetch routes through fetch_candlesticks_any_tier(), which asks the live /series/{s}/markets/{m}/candlesticks endpoint first and falls back to the /historical tier when the live tier answers 404. Measured on 30 July 2026, the historical tier paged a weather series’ settled markets back to November 2025 and served hourly candles for a market that far back, so the public API reaches substantially further than a live-tier-only reading suggests. That is a measurement with a date on it, not a promise: a venue can change retention without notice, and how far back any one series goes is a property of that series. A window the venue cannot serve returns an ordinary empty frame carrying the full column set.

A window below the resolved indicator’s first-contract floor raises DataAvailabilityError. That floor is a data-availability CONTRACT about when an indicator’s contracts first existed, not a claim about API depth, and it is unchanged.

df.attrs["tier"] records which tier served the frame ("kalshi" or "kalshi.historical"). The source COLUMN and df.attrs["source"] stay "kalshi", because this frame’s column contract is pinned.

Price and scalar parsing is delegated to mostlyright.markets._normalize, the one module that owns the venue’s unit vocabulary, so the tier-specific key spellings are read in exactly one place and a tier/payload mismatch raises instead of silently scaling a price. This frame keeps its own pinned units: prices in CENTS, volume and open interest as integers.

This module lives in mostlyright.markets (not economy) because it drives the Kalshi venue client – the workspace dependency runs one way, markets -> economy, so it may reuse both the markets Kalshi client and the economy floor/routing tables.

FunctionDescription
candles(ticker, *, interval, from_time, to_time)OHLC candles for a settled economy market ticker between from_time and to_time.

mostlyright.markets.economy_trades.candles(ticker, , interval, from_time, to_time)

Section titled “mostlyright.markets.economy_trades.candles(ticker, , interval, from_time, to_time)”

OHLC candles for a settled economy market ticker between from_time and to_time.

  • Parameters:

    • ticker (str) – Full Kalshi economy market ticker (e.g. "KXCPI-26JUL-T3.2"). The series root (KXCPI) is resolved to its economy indicator for the first-contract floor check.
    • interval (str) – Candle granularity – one of INTERVALS keys.
    • from_time (datetime) – tz-aware UTC datetimes bounding the window.
    • to_time (datetime) – tz-aware UTC datetimes bounding the window.
  • Return type: DataFrame

  • Returns: pd.DataFrame with columns ticker, end_time_utc, open, high, low, close, volume, open_interest, source. Prices are in CENTS; end_time_utc is the period END, as the venue stamps it. ticker is a leading identity column and source is always "kalshi".

    df.attrs["tier"] names the tier that actually served the rows ("kalshi" or "kalshi.historical"). A window the venue cannot serve returns an ordinary empty frame with the same columns, the same stamp, and the same tier / interval attrs – a zero-row answer still came from a tier, and a reader that branches on those attrs must not have to special-case the empty frame.

  • Raises:

    • TypeErrorfrom_time/to_time not tz-aware datetimes.
    • ValueErrorfrom_time >= to_time OR interval not in INTERVALS.
    • DataAvailabilityError – the window is below the resolved indicator’s first-contract floor (a data-availability contract violation).
    • SchemaValidationError – a served candle does not speak its own tier’s key vocabulary – refusing to guess beats emitting a price scaled by 100.