cross-vendor-timestamp-precision-reconciliation · v2.0.0 · 2026-08-23 · sha256 d314613ac46a0fb8
cross-vendor-timestamp-precision-reconciliation v2.0.0A
Immutable. This exact content is served forever at /api/v1/blob/d314613ac46a0fb8.
--- name: cross-vendor-timestamp-precision-reconciliation description: Market data reconciliation engine normalizing multi-vendor timestamps (s, ms, us, ns, ISO-8601) to 64-bit nanosecond UTC epoch with exact integer arithmetic, flagging out-of-order arrivals, precision shortfalls, and matched-event vendor skew. domain: Data Management Global subdomain: Market Data Reconciliation tags: - timestamp-reconciliation - nanoseconds - utc-epoch - iso-8601 - databento - refinitiv - bloomberg - mifid-ii-rts25 brokers_frameworks: - Databento - Refinitiv ELEKTRON - Bloomberg B-PIPE - Python Dataclasses version: "2.0.0" author: algo-trading-skills-contributors license: Apache-2.0 --- ## When to Use Use this skill when a pipeline ingests market data from more than one vendor and the timestamps arrive in different units and encodings (float seconds, integer milliseconds, ISO-8601 strings, int64 nanoseconds — e.g. Databento publishes int64 UTC nanoseconds since epoch). Mixing them without exact normalization produces mis-ordered tick sequences, phantom latency measurements, and precision claims a firm cannot support in a MiFID II RTS 25 clock-traceability review. This module converts every raw timestamp into a 64-bit integer nanosecond UTC epoch using **exact integer/Decimal arithmetic**, flags out-of-order arrivals, audits the precision tier actually delivered, and measures cross-vendor skew between records that describe the *same* event. ## When NOT to Use - **As a clock-synchronization monitor.** This engine compares timestamps *in data*. It cannot measure a host's offset from UTC — that is PTP/NTP telemetry; see `clock-drift-monitoring-alerting-thresholds` and `cross-datacenter-clock-sync-validation`. RTS 25 compliance is demonstrated with traceability evidence for the clock, not with a feed-comparison report. - **To infer vendor clock error from a skew number.** A matched-event skew mixes the vendors' clock offsets with *where each vendor timestamps* — a matching-engine event time and a capture-NIC receive time legitimately differ by the network path (Databento, for instance, exposes both an event time and a receive time per record). Attribute a skew only after confirming both vendors' timestamping points. - **When no shared event key exists.** Without an exchange sequence number or venue trade id, records from two vendors cannot be proven to describe the same event, and the interval between consecutive ticks is not a skew measurement. The engine skips the analysis rather than emitting unfounded warnings. - **For sub-nanosecond or post-2262 timestamps.** int64 nanoseconds saturate at `2262-04-11T23:47:16.854775807Z`; both out-of-range values and sub-nanosecond fractional digits raise rather than being silently rounded. ## Prerequisites - Vendor tick records with `tick_id` (unique), `vendor_id`, `symbol`, `raw_timestamp`, and `precision_format` (`SECONDS`, `MILLISECONDS`, `MICROSECONDS`, `NANOSECONDS`, `ISO8601`). - Optional `event_key` (exchange sequence number / venue trade id) — required for any cross-vendor skew analysis. - Optional `required_precision_tier` reflecting the applicable obligation (see `references/standards.md` for the RTS 25 and CAT figures) and a skew threshold `max_allowed_vendor_drift_ms`. ## Workflow 1. **Precision Normalization Engine** — `normalize_timestamp_to_ns()` returns `(ns_int64, iso_utc_str, precision_tier)`: - Numeric inputs are scaled with `Decimal`, never float: `int(1_700_000_000_123 * 1e6)` evaluates to `1700000000123000064`, because float64 has 53 significand bits and the representable spacing at 1.7e18 ns is 256 ns. - A **float** input is read as `Decimal(str(value))` — the shortest decimal that round-trips it — so `1700000000.123` becomes `1700000000123000000` ns rather than the binary tail `…122999808`. Decision point: a float declared as `NANOSECONDS` is **rejected**, because the float has already destroyed the precision the format claims. - **ISO-8601** is parsed with an explicit fractional-digit split, not `datetime`: `datetime` stops at microseconds and would silently drop the last three digits of `…20.123456789Z`. Offsets (`Z`, `±HH:MM`) are applied; a naive string is treated as UTC **with a warning**; more than 9 fractional digits raises unless the surplus is zero padding. - The precision tier for ISO input is derived from the **number of fractional digits** (0 → `SECONDS`, ≤3 → `MILLISECONDS`, ≤6 → `MICROSECONDS`, ≤9 → `NANOSECONDS`), so a millisecond feed is not recorded as microsecond-grade. - `iso_utc_str` is rendered by integer division with all 9 fractional digits — an audit string truncated to milliseconds does not document the value it accompanies. - Any result outside the signed 64-bit range raises. 2. **Temporal Alignment & Out-of-Order Detection**: - Ticks are walked in **arrival order**, and any tick whose timestamp precedes the highest timestamp already seen ($\Delta t < 0$) is flagged and counted. Decision point: inspecting adjacent pairs of the *sorted* list instead under-counts — arrivals $[5, 1, 2, 3]$ contain three late ticks but only one adjacent inversion survives sorting. - The batch is treated as **one merged stream**: the running maximum spans all symbols and vendors, which is what a sequencer or replay buffer needs. Decision point: if a late tick in one symbol should not count as out-of-order relative to another symbol, group the batch by symbol and reconcile each group separately. - Output is sorted by `(ns, arrival_index)` so equal timestamps keep a reproducible order. - Duplicate `tick_id` values raise: the id keys arrival ordering, and duplicates silently corrupt it. 3. **Precision Audit**: each tick is compared against `required_precision_tier`; shortfalls are flagged per record (`meets_precision_requirement`) and counted (`precision_violation_count`) rather than absorbed into a nanosecond schema. 4. **Matched-Event Skew Audit**: signed skew is computed only between different vendors sharing `(symbol, event_key)`; the sign identifies which vendor is ahead. Where one vendor reports the same event twice, its earliest timestamp is used. With no event keys present, the analysis is skipped and `skew_pairs_evaluated` is 0. 5. **Audit Report Generation**: a `TimestampReconciliationReport` carrying normalized ticks, out-of-order count, tier distribution, precision violations, and skew observations. > Full procedure: see `references/workflows.md`. > Standards reference: see `references/standards.md`. > Printable pre-flight checklist: see `assets/checklist.md`. ## Common Pitfalls - **Scaling Through float64**: `int(ms * 1e6)` and `int(seconds * 1e9)` are the two most common conversions in market data code and both are wrong at nanosecond resolution — `1_700_000_000_123 ms` becomes `…123000064` and `1700000000.123 s` becomes `…122999808`. `int()` also truncates toward zero, so the error is a systematic bias, not noise. Use integer or `Decimal` arithmetic end to end. - **Parsing Nanosecond ISO-8601 with `datetime`**: `datetime` resolution stops at microseconds, so `2023-11-14T22:13:20.123456789Z` silently loses its last three digits — a 789 ns error that no exception announces. - **Ignoring Timezone Offsets**: a naive ISO string treated as UTC when the vendor emits local exchange time shifts every tick by hours. Require an explicit offset, or log loudly when assuming. - **Zero-Padding Fake Precision**: appending six zeros to millisecond data to satisfy a nanosecond schema fabricates precision. Record the tier actually delivered and compare it against the obligation. - **Mislabelling the Tier from the Schema**: precision is a property of the *value* (fractional digits present), not of the column type. Counting every ISO timestamp as microsecond-grade overstates the feed. - **Calling an Inter-Tick Interval "Clock Drift"**: two vendors' consecutive ticks are usually two different events; their 20 ms gap says nothing about either clock. Skew is only meaningful between records matched on an exchange sequence number or trade id — and even then it includes the difference between each vendor's timestamping point. - **Unsigned Skew**: reporting `abs(skew)` hides which vendor is ahead, which is the part that identifies the faulty feed. - **Out-of-Order Counted After Sorting**: sorting destroys arrival information; detection must run on the arrival sequence. - **int64 Overflow Assumed Away**: nanosecond epochs saturate int64 in 2262, and far-future or corrupt values silently wrap in downstream int64 columns unless the range is checked at ingest. ## Verification - Normalize `1_700_000_000_123` as `MILLISECONDS` and assert exactly `1700000000123000000` (the float path yields `…123000064`). - Normalize `1700000000.123` as `SECONDS` and assert exactly `1700000000123000000` (the float path yields `…122999808`). - Normalize `"2023-11-14T22:13:20.123456789Z"` and assert `1700000000123456789` with tier `NANOSECONDS` and an ISO output carrying all 9 digits; normalize `"…20.123Z"` and assert tier `MILLISECONDS`. - Pass `1.70000000012345678e18` as `NANOSECONDS` and expect `ValueError`; pass a year-3000 second value and expect the int64-range `ValueError`. - Reconcile arrivals with timestamps `[5, 1, 2, 3]` and assert `out_of_order_count == 3`. - Reconcile two different-vendor ticks 20 ms apart with **no** `event_key` and assert no drift warnings; add a shared `event_key` and assert a signed skew of `+20_000_000` ns with a warning, and that a skew of exactly the threshold does not warn. - Configure `required_precision_tier="MICROSECONDS"`, submit one millisecond ISO tick and one nanosecond tick, and assert `precision_violation_count == 1`. - Run `python -m unittest discover -s skills/cross-vendor-timestamp-precision-reconciliation/scripts`. ## Related Skills - `clock-drift-monitoring-alerting-thresholds` - `data-pipeline-schema-contract-testing` - `clock-skew-correction-for-tick-timestamps` - `cross-datacenter-clock-sync-validation`