Settlement truth layer for prediction markets. Raw weather observations, climate records, and forecasts with point-in-time query semantics.
Project description
MostlyRight
Settlement truth layer for prediction markets. Raw weather observations, climate records, and forecasts with point-in-time query semantics — for quants training Kalshi NHIGH/NLOW temperature models.
Install
pip install mostlyright # SDK only (~2 deps: httpx, jsonschema)
pip install mostlyright[parquet] # adds pandas + pyarrow for DataFrames
Quickstart
from mostlyright import MostlyRightClient
with MostlyRightClient() as client:
obs = client.observations("NYC", from_date="2024-07-04", to_date="2024-07-04")
# → list[Observation] with 30 raw METAR fields (temp_f, wind_speed_kt, ...)
Training workflow
Paired observations + NWS CLI settlement + optional forecasts, one row per settlement date. The primary training surface.
from mostlyright import MostlyRightClient
with MostlyRightClient() as client:
# 5 years, joined against IEM MOS forecasts + Open-Meteo fallback.
train = client.pairs(
"NYC",
from_date="2020-01-01",
to_date="2024-12-31",
include_forecast=True,
as_dataframe=True, # requires mostlyright[parquet]
)
# Columns: date, cli_high_f, cli_low_f (settlement truth),
# obs_high_f, obs_low_f (observed),
# fcst_high_f, fcst_low_f, fcst_model, fcst_issued_at, ...
Inference workflow
Live forecast signal, fetched directly from the upstream source — no
MostlyRight infrastructure between the quant and the weather model.
Column parity with the historical client.forecasts() output is the
contract.
import mostlyright
live = mostlyright.live.get_forecast("NYC", model="NBS", source="iem")
# → pandas.DataFrame with the same columns as client.forecasts(...)
prediction = model.predict(live)
# Or Open-Meteo (seamless hourly):
live_om = mostlyright.live.get_forecast(
"NYC", model="gfs_seamless", source="open_meteo"
)
Authentication
Dev mode requires no key. Production quants should set:
export MOSTLYRIGHT_API_KEY=<your-key>
Or pass explicitly:
import os
from mostlyright import MostlyRightClient
client = MostlyRightClient() # reads MOSTLYRIGHT_API_KEY from env
# Legacy THERMINAL_API_KEY is also honoured for drop-in migration.
Point-in-time queries
Every method accepts an as_of watermark. Results are filtered so an
inference loop on historical data sees only what was knowable at that
UTC moment — climate records are withheld until the NWS CLI publication
threshold has passed.
snap = client.snapshot("NYC", as_of="2024-07-04T18:00:00Z")
snap.observations # filtered to [window_start_utc, as_of]
snap.climate # None until CLI publishes (~10h after midnight LST)
snap.version # DataVersion — reproducibility token
Data methods
| Method | Returns | Purpose |
|---|---|---|
client.observations(station, from_date, to_date) |
METAR/SPECI observations | 30 raw fields, up to 24/day |
client.climate(station, from_date, to_date) |
NWS CLI daily records | Kalshi settlement source |
client.forecasts(station, ...) |
IEM MOS runs | Discrete issued_at runs, per-hour rows |
client.forecast_series(station, ...) |
Open-Meteo hourly | Seamless hourly, metric/SI |
client.pairs(station, from_date, to_date) |
Settlement-date rows | Observations + climate + optional forecast, joined |
client.snapshot(station, as_of) |
DataSnapshot |
All data available at a UTC moment |
client.feature_catalog() |
Feature metadata | Discovery surface for AI agents |
mostlyright.live.get_forecast(station, ...) |
pandas.DataFrame | Live upstream forecast |
See docs/QUICKSTART.md for the longer walkthrough
of each method, format options (toon, parquet, csv), and settlement
window conventions.
Available stations
20 airports with active Kalshi NHIGH/NLOW markets. Codes accept 3-letter
NWS form (NYC) or 4-letter ICAO (KNYC):
ATL AUS BOS DCA DEN DFW HOU LAS LAX MDW
MIA MSP MSY NYC OKC PHL PHX SAT SEA SFO
Station metadata (lat/lon, timezone, ICAO) is available at runtime:
stations = client.stations() # list[StationInfo]
info = client.station("NYC") # one station
Error handling
The SDK raises typed exceptions mapped from HTTP status codes:
from mostlyright.exceptions import (
NotFoundError, ValidationError, RateLimitError,
AuthenticationError, ForbiddenError, ServerError,
)
try:
obs = client.observations("XYZ") # unknown station
except NotFoundError as exc:
...
except RateLimitError as exc:
wait_s = exc.retry_after
All exception classes subclass mostlyright.exceptions.TherminalError.
Schemas
Every data entity has a JSON Schema under specs/
on GitHub (observation.json, climate.json, forecast.json,
forecast_series.json, snapshot.json, market_unified.json, ...).
The SDK validates every response against these schemas before returning.
Changelog
Release notes live on GitHub Releases.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mostlyright-0.14.1.tar.gz.
File metadata
- Download URL: mostlyright-0.14.1.tar.gz
- Upload date:
- Size: 122.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaec46c66a3fa2a2317cf82a1d1dd36893f582d9be603704a372fac9df6b2183
|
|
| MD5 |
108440b30cc4f939846c23980207049a
|
|
| BLAKE2b-256 |
d8093e5ee1681d8b01e59f48c9ee7c6623fa1b0bd591dd5b2011102263881d7e
|
File details
Details for the file mostlyright-0.14.1-py3-none-any.whl.
File metadata
- Download URL: mostlyright-0.14.1-py3-none-any.whl
- Upload date:
- Size: 128.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e4fc8997811095931e187bc1cdc1ef1dd8eb11b10154a8d956a1b5ad50aebfb
|
|
| MD5 |
672c07c39aec1672f13b101dab96fdf7
|
|
| BLAKE2b-256 |
e0f4e81ece2001f619c11c32eacdc0b88e1f62d0f88d3219a662256f19b9673d
|