Polymarket now publishes a HYPE monthly event
(what-price-will-hyperliquid-hit-in-{month}, no year suffix), so the
old strike-probe fallback was both unnecessary and mis-ranged -- its
strikes [24..52] predated HYPE roughly doubling to ~$72, so every
"above" market ($76-92) was invisible and all 8 above rows came back
NO POLY. Point HYPE at its event like every other asset and re-range
the probe fallback to the current band [52..92].
Regenerated June pairs.json: HYPE now 16/16 with a Poly leg (was 8/16),
total 110/126 (every non-ZEC row paired; ZEC stays Kalshi-only). Only
HYPE rows changed; the other 7 assets are byte-identical.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
gj() now retries 5x with exponential backoff (0.5->8s) instead of 3x
flat, so a throttled burst mid-discovery no longer silently truncates a
ladder. build() reports any asset whose Kalshi ladder came back empty,
and main() aborts (exit 2) rather than overwriting pairs.json when that
happens -- a failed fetch must not be mistaken for "no markets listed."
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The monthly scanner is driven by a static curated pairs.json, so new monthly
contracts don't appear until that file is rebuilt. roll_month.py discovers both
legs live for a target month: it anchors on Kalshi's full strike ladder
(series KX{ASSET}MAX/MINMON, target expiry code) and attaches each strike's
nearest same-direction Polymarket market (events forward-parsed; HYPE probed).
Validated against May: re-discovers 100% of curated tickers, all slugs parse,
nearest-match agrees except where the curated file points at now-closed Poly
markets. Safety: backs up the prior file and refuses to overwrite when it finds
fewer than --min-pairs (so running it before the month lists can't wipe it).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>