Skip to content

Guides

Markets

The markets domain connects a contract to the data that actually settles it. Kalshi weather markets use NWS CLI targets; Polymarket weather markets use WU / NOAA-WRH daily extremes.

Ticker parsing is public and inspectable:

from mostlyright.markets import kalshi
parsed = kalshi.parse_ticker("KXHIGHNY-25MAY26-T79")
print(parsed.station, parsed.measure)

Threshold and range comparisons are inclusive. Malformed or unsupported tickers raise KalshiTickerError.

To inspect the contract calendar without composing observation features:

days = kalshi.settlement_days(
"KXHIGHNY-25MAY26-T79",
"2025-05-20",
"2025-05-26",
)

settlement_days() is the 2.0 name. The old contracts() name is gone.

Polymarket’s entity is the event id. Discover and settle with the direct venue calls:

from mostlyright.markets import polymarket
events = polymarket.discover()
event_id = events.iloc[0]["event_id"]
result = polymarket.settle(event_id)

The 1.x names polymarket_discover() and polymarket_settle() are gone.

Station resolution remains explicit:

  • load_polymarket_city_stations() exposes the published city/measure mapping.
  • resolve_station_for_event() resolves an event to the station used for settlement.
  • guarded unsupported markets raise DeferredMarketError rather than resolving to a knowingly wrong station.
  • settling before a trustworthy record exists raises TooEarlyToSettleError.

above settles YES when observed >= strike; below when observed <= strike; between is inclusive at both endpoints. Negative temperatures are parsed deliberately so a separator hyphen is not mistaken for or stripped from a minus sign.

Malformed strike text raises PolymarketStrikeError.

The venue helpers include small predefined supervised-learning recipes. For Kalshi NHIGH/NLOW:

from mostlyright.markets import kalshi
kalshi_example = kalshi.training_table(
"KXHIGHNY-25MAY26-T79",
"2025-05-20",
"2025-05-26",
outcome=True,
)

The result contains the same daily_summary_* target and observed_* features as weather.training_table(label="cli"). With outcome=True, it also contains label_outcome (1, 0, or missing when the settlement label is missing).

For Polymarket:

from mostlyright.markets import polymarket
polymarket_example = polymarket.training_table(
"<event_id>",
"2025-05-20",
"2025-05-26",
outcome=True,
)

This recipe uses the daily_extremes target in whole-degree Celsius. If a historical model used CLI values for a Polymarket weather market, changing to this venue-correct target is a retraining event.

outcome=True needs the event description to parse the strike and validate its resolution source. Supply a previously loaded event payload with event= when you need the call to remain offline.

Settlement training tables do not silently add live trades. The low-level Kalshi and Polymarket weather trade implementations are private in 2.0.

The public method for settled economy-market trades is markets.economy_trades.candles():

from mostlyright.markets import economy_trades
from datetime import datetime, timezone
candles = economy_trades.candles(
"KXCPI-26JUL-T3.2",
interval="1h",
from_time=datetime(2026, 5, 1, tzinfo=timezone.utc),
to_time=datetime(2026, 5, 31, tzinfo=timezone.utc),
)

The time-window parameter names are from_time and to_time in 2.0.

ErrorWhen
KalshiTickerErrorA ticker cannot be parsed or is outside the supported settlement universe
PolymarketStrikeErrorAn above, below, or between strike cannot be parsed
PolymarketEventErrorAn event cannot be validated or fetched
PolymarketSettlementErrorA trustworthy settlement value cannot be established
TooEarlyToSettleErrorSettlement is requested before the record exists
DeferredMarketErrorThe event is on a guarded unsupported path

The TypeScript markets package uses the same 2.0 names:

import { discover, settle } from "@mostlyrightmd/markets/polymarket";
const events = await discover();
const result = await settle({
event: events[0]!,
loader: async ({ icao, fromDate, toDate }) => {
// Return observation rows for this station and window.
return [];
},
});

The Polymarket Gamma API is not browser-CORS-friendly; run discovery and settlement server-side or through an extension background worker with the required host permission.