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) <noreply@anthropic.com>
Replace volume-based contract selection with Yahoo Finance continuous
contract price matching ({PRODUCT}=F). The old approach compared volumes
across front/roll candidates, which failed when serial months had
deceptive volume (6EJ26 > 6EM26) or Yahoo was rate-limited (all 0s).
Now fetches the continuous contract price and matches it against
candidates within 0.1% tolerance. Falls back to roll1 if Yahoo fails.
Also adds User-Agent header to avoid 429 rate limiting.
Verified: GC=F price matches GCM26, 6E=F price matches 6EM26.
Also fixes stale 'Random' comment in auto-trade.ts and cleans up
frontVolume/rolledVolume references from settings page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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 <noreply@anthropic.com>
- New lib/contract-resolver.ts: picks the best contract month for each
symbol by comparing Yahoo Finance volume between the front month
(Tradovate suggest API) and the roll target (rollcontract API)
- lib/clients.ts: auto-resolves all enabled instruments 15s after startup
and again daily at midnight via a setInterval check
- lib/tradovate-class.ts: findFrontMonthContract checks resolver cache
first before falling back to the suggest API
- app/api/instruments/contracts/route.ts: GET returns cached contracts,
POST triggers a fresh resolve
- app/settings/page.tsx: shows active contract + rolled badge per symbol;
auto-resolves on load if cache is empty; removed manual Resolve button
- app/api/debug/route.ts: include entity data in recentEntityEvents
- CLAUDE.md: instructs Claude to always work on main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>