From c99f6843a761e0d215c746e999e095a8a639a12a Mon Sep 17 00:00:00 2001 From: Senofy <63175905+Senofy@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:39:11 -0500 Subject: [PATCH] Fix contract resolver: prefer rolled contract on equal volume Changes > to >= so when both contracts have 0 volume (e.g. off-hours), the further-out standard month wins. Fixes SI resolving to SIJ (April, non-standard) instead of SIK (May, standard delivery month). Also fixes SI/SIL prefix collision by requiring month+digit after symbol. Co-Authored-By: Claude Opus 4.6 --- lib/contract-resolver.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/contract-resolver.ts b/lib/contract-resolver.ts index ec99817..0e2a13d 100644 --- a/lib/contract-resolver.ts +++ b/lib/contract-resolver.ts @@ -116,7 +116,12 @@ export async function resolveContracts( { headers } ); const contracts: ContractInfo[] = res.data ?? []; - const match = contracts.find((c) => c.name.startsWith(sym)); + // Match symbol exactly: after the symbol prefix, next char must be a month code (A-Z) then a digit + const match = contracts.find((c) => { + if (!c.name.startsWith(sym)) return false; + const rest = c.name.slice(sym.length); + return /^[A-Z]\d/.test(rest); + }); frontMonths[sym] = match ? { id: match.id, name: match.name, @@ -193,8 +198,9 @@ export async function resolveContracts( const frontVol = volumes[front.name] ?? 0; const rolledVol = volumes[rolled.name] ?? 0; - if (rolledVol > frontVol) { - // Rolled contract has more volume — use it + if (rolledVol >= frontVol) { + // Rolled contract has equal or more volume — use it + // (equal includes both-zero case: prefer the further-out month) results[sym] = { ...rolled, alternative: front.name, @@ -203,7 +209,7 @@ export async function resolveContracts( }; console.log(`[contract-resolver] ${sym}: ${front.name} (vol=${frontVol}) → ${rolled.name} (vol=${rolledVol}) ROLLED`); } else { - // Front month still has more volume — keep it + // Front month has more volume — keep it results[sym] = { ...front, alternative: rolled.name,