diff --git a/harnesses/pm-resolution-delay/cmd/script/kalshi_resolution.go b/harnesses/pm-resolution-delay/cmd/script/kalshi_resolution.go index f3d98c26..da70ef2a 100644 --- a/harnesses/pm-resolution-delay/cmd/script/kalshi_resolution.go +++ b/harnesses/pm-resolution-delay/cmd/script/kalshi_resolution.go @@ -183,6 +183,11 @@ func (k *kalshiTracker) pollClosed() { k.mu.Lock() defer k.mu.Unlock() for _, m := range markets { + // KXMV* = auto-generated multivariate parlays. They can briefly pass + // through status=closed (6-10s window) before auto-settling. Exclude. + if strings.HasPrefix(m.Ticker, "KXMV") { + continue + } ct, err := time.Parse(time.RFC3339, m.CloseTime) if err != nil { continue diff --git a/src/app/api/series/[slug]/route.ts b/src/app/api/series/[slug]/route.ts index f247e535..371358ff 100644 --- a/src/app/api/series/[slug]/route.ts +++ b/src/app/api/series/[slug]/route.ts @@ -183,6 +183,12 @@ export async function GET( } const url = new URL(req.url); + // When ?raw=1 the response values stay in OCB's internal unit convention + // (milliseconds for "s" benches, basis points for "bps" benches) so the + // time-series chart can pass them directly to fmtUnit without a second + // division. The video renderer omits raw=1 and gets the display-friendly + // conversion (seconds / percent) it expects. + const rawMode = url.searchParams.get("raw") === "1"; const rangeParam = url.searchParams.get("range") ?? "24h"; if (!isRangeKey(rangeParam)) { return NextResponse.json( @@ -330,16 +336,20 @@ export async function GET( // "bps" = stored in basis points, site displays as % (÷100) → send "pct" + divide values // "s" = stored in milliseconds, site displays as seconds → send "s" + divide values // "pct", "bp", "usd", "count", … → pass through unchanged + // When ?raw=1 (time-series chart), skip conversion so fmtUnit receives + // values in the same internal unit as the 24h series from the bench object. let displayUnit = sourceUnit; const providers = rawProviders.map((p) => ({ ...p })); - if (sourceUnit === "bps") { - displayUnit = "pct"; - for (const p of providers) { - p.values = p.values.map((v) => (v == null ? null : v / 100)); - } - } else if (sourceUnit === "s") { - for (const p of providers) { - p.values = p.values.map((v) => (v == null ? null : v / 1000)); + if (!rawMode) { + if (sourceUnit === "bps") { + displayUnit = "pct"; + for (const p of providers) { + p.values = p.values.map((v) => (v == null ? null : v / 100)); + } + } else if (sourceUnit === "s") { + for (const p of providers) { + p.values = p.values.map((v) => (v == null ? null : v / 1000)); + } } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 04f21faa..3fe4b286 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -147,7 +147,7 @@ const ORG_JSONLD = { // Wikidata entity: anchors the OpenChainBench brand in the // Knowledge Graph so the brand query resolves to this domain // instead of the unrelated "OpenBench" homonyms. - "https://www.wikidata.org/wiki/Q140172649", + "https://www.wikidata.org/wiki/Q140756438", ], }, { diff --git a/src/components/time-series-chart/index.tsx b/src/components/time-series-chart/index.tsx index c2e7fcb8..a510f3b3 100644 --- a/src/components/time-series-chart/index.tsx +++ b/src/components/time-series-chart/index.tsx @@ -186,7 +186,7 @@ export function TimeSeriesChart({ // never refetched. const done: Record<"7d" | "30d", boolean> = { "7d": false, "30d": false }; const buildQs = (range: "7d" | "30d") => { - const qs = new URLSearchParams({ range }); + const qs = new URLSearchParams({ range, raw: "1" }); if (regionProp && regionProp !== "all") qs.set("region", regionProp); if (chainProp && chainProp !== "all") qs.set("chain", chainProp); return qs.toString(); @@ -243,7 +243,7 @@ export function TimeSeriesChart({ "30d": !need30d, }; const buildQs = (range: "7d" | "30d") => { - const qs = new URLSearchParams({ range, panel: activePanelId }); + const qs = new URLSearchParams({ range, panel: activePanelId, raw: "1" }); if (regionProp && regionProp !== "all") qs.set("region", regionProp); if (chainProp && chainProp !== "all") qs.set("chain", chainProp); return qs.toString(); @@ -299,7 +299,7 @@ export function TimeSeriesChart({ if (!need90d && !need1y) return; let cancelled = false; const buildQs = (r: "90d" | "1y") => { - const qs = new URLSearchParams({ range: r, panel: activePanelId }); + const qs = new URLSearchParams({ range: r, panel: activePanelId, raw: "1" }); if (regionProp && regionProp !== "all") qs.set("region", regionProp); if (chainProp && chainProp !== "all") qs.set("chain", chainProp); return qs.toString();