From 24cfa7efccc366049cb1c96eadad3c1eb3899d56 Mon Sep 17 00:00:00 2001 From: Brandon Li Date: Mon, 30 Mar 2026 18:22:11 -0500 Subject: [PATCH] Fix contract resolver picking wrong month for adjacent contracts Adjacent futures months (e.g. 6EK vs 6EM) have nearly identical prices, so the first-match-within-tolerance approach picked the front month (6EK/May) instead of the actual active contract (6EM/June). Now picks the candidate with the closest price to the continuous contract instead of breaking on the first match within 0.1% tolerance. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/contract-resolver.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/contract-resolver.ts b/lib/contract-resolver.ts index 17edfe1..c0bd9f7 100644 --- a/lib/contract-resolver.ts +++ b/lib/contract-resolver.ts @@ -216,14 +216,17 @@ export async function resolveContracts( console.log(`[contract-resolver] ${sym}: continuous=${continuousPrice}, candidates=[${candidates.map((c, i) => `${c.contract.name}=$${candidatePrices[i]}`).join(', ')}]`); - // Find the candidate whose price matches the continuous contract (within 0.1% tolerance) + // Find the candidate with the closest price to the continuous contract let best = candidates[0]; // default to front if (continuousPrice !== null) { + let bestDiff = Infinity; for (let i = 0; i < candidates.length; i++) { const price = candidatePrices[i]; - if (price !== null && Math.abs(price - continuousPrice) / continuousPrice < 0.001) { + if (price === null) continue; + const diff = Math.abs(price - continuousPrice); + if (diff < bestDiff) { + bestDiff = diff; best = candidates[i]; - break; // prefer the nearest matching contract } } } else {