Trading Calendar & Session Correctness Playbook (Multi-Venue Execution)

2026-03-07 · finance

Trading Calendar & Session Correctness Playbook (Multi-Venue Execution)

Date: 2026-03-07
Category: knowledge (trading operations / execution reliability)

Why this matters

Many live-trading incidents are not model errors. They are time-domain errors:

These failures often look like "random rejects" or "weird slippage day" but are actually calendar bugs.

If your execution stack is multi-venue (KRX + US, cash + futures, lit + dark), calendar correctness is a first-class risk control.


Scope of "calendar correctness"

Calendar correctness is not just a holiday CSV. It is the full set of rules that determine when each action is legal and safe:

  1. Trading day eligibility (business day / holiday / ad-hoc closure)
  2. Session segmentation (pre-open, auction, continuous, close auction, post)
  3. Special schedules (half-days, early close, delayed open)
  4. Clock domain handling (exchange local time, server time, DST)
  5. Cross-venue consistency (hedge venue status, data venue status, routing venue status)

Failure modes to design against

1) Hard rejects

Impact: reject loops, message churn, degraded queue priority when re-entering.

2) Silent opportunity loss

Impact: underfill and benchmark drift without obvious alerts.

3) Cross-venue hedge break

Impact: unintended directional exposure and tail slippage.

4) DST drift incidents

Impact: jobs execute one hour early/late for weeks.


Data model: separate day rules from session rules

Use explicit, versioned entities.

A) TradingDay

Per venue + date:

B) SessionTemplate

Reusable session structure:

C) DaySessionOverride

For exceptions:

Never patch runtime logic ad hoc. Encode exceptions in data.


Time handling rules (non-negotiable)

  1. Store canonical timestamps in UTC.
  2. Store venue-local date/time + timezone id (e.g., America/New_York, Asia/Seoul) for schedule logic.
  3. Do not use fixed UTC offsets for DST venues.
  4. Evaluate session state using venue clock semantics, not server local time.
  5. Snapshot timezone database version in deployment metadata for reproducibility.

A lot of “mystery” date bugs are timezone-db drift or fixed-offset shortcuts.


Session-state machine for execution safety

Create one resolver API per venue:

resolveSessionState(venue, nowUtc) -> { state, phase, nextTransition, dayType, tradable }

Recommended high-level states:

Execution components consume this resolver instead of re-implementing schedule checks.


Control policy by state

CLOSED

PREOPEN / AUCTION_*

CONTINUOUS

HALTED_SPECIAL


Cross-venue consistency checks (critical)

Before enabling a multi-leg strategy bucket:

If any fail, auto-shift strategy to a degraded mode (NO_HEDGE_ENTRY, EXIT_ONLY, or PAUSE).


Validation and test strategy

1) Golden calendar test set

Build a permanent regression suite containing:

Every calendar update must pass this suite.

2) Transition-edge tests

For each phase boundary T test:

Most production bugs sit on boundaries, not mid-session.

3) Shadow resolver

During rollout, run new and old resolver in parallel and log diffs:

calendar_diff_rate = mismatched_state_events / total_state_events

Promote only when diff rate is near zero and explained.


Observability KPIs

Track by venue + strategy + dayType:

Good target: out-of-session rejects should be operationally near-zero except rare emergency closures.


Rollout sequence (practical)

  1. Build canonical calendar service + versioned data model.
  2. Migrate all execution clients to shared session resolver API.
  3. Enable read-only shadow checks and collect mismatch metrics.
  4. Canary on one venue/strategy cluster.
  5. Expand after two full cycles including at least one boundary-heavy window (e.g., month-end, known half-day, or DST week).
  6. Add kill-switch: fallback to last known-good calendar version.

Common anti-patterns

  1. Embedding market hours in strategy code

    • leads to duplicated, drifting logic.
  2. Single global "is market open" flag

    • invalid for multi-venue systems.
  3. Ignoring half-days as rare events

    • rare is exactly why they break silently.
  4. Assuming data-feed status implies order-routing status

    • they can diverge.
  5. Manual emergency patch without versioning

    • impossible postmortem and replay.

Minimal runbook for incident response

When calendar/session incident suspected:

  1. Freeze affected strategy buckets to safe mode.
  2. Record resolver output + raw venue schedule + local clock + tzdb version.
  3. Compare expected phase vs actual order/ack timestamps.
  4. If resolver bug confirmed, rollback to previous calendar version.
  5. Reconcile missed/invalid orders and document affected date/venue scope.

One-line takeaway

In live execution, time assumptions are risk assumptions: treat trading-calendar/session logic as a versioned control system, not static metadata.


References