Skip to content

fix: derive futures expiry rolls from authoritative sessions - #102

Merged
stefan-jansen merged 4 commits into
mainfrom
fix/scheduled-futures-rolls
Oct 17, 2026
Merged

stefan-jansen merged 4 commits into
mainfrom
fix/scheduled-futures-rolls

Conversation

@stefan-jansen

@stefan-jansen stefan-jansen commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Closes #101

Outcome

TimeBasedRoll counts authoritative selected sessions strictly before expiration instead of weekdays or observed dates. Missing scheduled triggers no longer move backward: the existing contract availability process switches on the first eligible later observation. Explicit elapsed-day mode retains civil-day units but also stops snapping backward. Zero offset remains expiration itself.

Canonical calendar overrides shared FeedSpec metadata, then NYSE. Named24/7 is a real continuous schedule; descriptive ContractSpec.exchange is not a selector. Session-count mode rejects explicit/declared None as unsupported row-based expiry offsets rather than claiming continuous trading is row mode. The explicitly selected elapsed-day mode needs no calendar and accepts disabled selection without changing its units. FirstNoticeDateRoll preserves its existing notice-offset convention and propagates the same declaration to its TimeBasedRoll delegate. Old positional signatures remain valid.

Actual failing-base and passing-fix evidence

  • Production75717937810ba69f06e5512f8f2c1c0b4e78d22a, regression-onlyb57a60c1e38e913348b32ee42793a5d04bb5e5fb:2 selected-symbol failures in0.65s through SyntheticProvider -> actual OHLCV/definition Parquet layout -> real Databento parser -> ContinuousContractBuilder -> NoAdjustment. No parser/acquisition mocks or private-helper correctness assertions. Explicit expirations describe synthetic test contracts, not a vendor instrument expiration claim.
  • July10 expiry requires a July2 NYSE trigger, but old output retains the old contract onJuly2. July11 expiry requires July3; removing that entire session makes the old implementation switch early onJuly2 instead of the first later observedJuly7.
  • Explicit elapsed-day mode independently reproduces the same backward-snap defect on immutable55b86e2, whose futures roll source is identical to7571793:1 actual selected-symbol failure, not a missing-keyword TypeError.
  • Current f9a5fa3 includes main e6568c0 through normal expected-head-guarded GitHub Update branch. Its three owned files are unchanged from 44c6732, where 156 focused futures/session/provider cases passed in 7.08s before the strict local benchmark hold. Earlier 720cf76 passed 110 cases and all applicable hosted gates (3850 tests, 85.92% coverage). Neither result substitutes for fresh qualification of f9a5fa3. Current-head CI, ecosystem qualification, documentation and security runs are 39054527732, 39054527940, 39054527695 and 39054527558. No local tests, hooks or builds are being run during the hold.
  • Ruff lint/format, ty, diff checks, normal hooks and strict MkDocs pass. API reference records the changed units and explicit unsupported row mode. Full coverage/resource/installed-package/platform/docs/security gates run hosted before ordinary merge, not claimed complete from this focused lane.

Review and remaining scope

Owner reviewed actual diff, calendar precedence, zero/elapsed/session units, strictly-before-expiry selection, schedule independence from observations, parser/builder integration and FirstNotice delegation. AI-assisted source/tests/prose under maintainer direction; no independent reviewer claimed. Three files only; no unrelated session/ingestion changes or release/deployment. Volume/open-interest strategies retain their observation-rank behavior; this does not claim all calendar harmonization complete. Published0.2.1 remains immutable.

Copilot AI balanced review requested due to automatic review settings October 17, 2026 15:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@stefan-jansen
stefan-jansen merged commit 2edaed3 into main Oct 17, 2026
27 checks passed
@stefan-jansen
stefan-jansen deleted the fix/scheduled-futures-rolls branch October 17, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: schedule futures expiry rolls independently of observed dates

2 participants