When to Use
Invoke this skill when the same instrument arrives from two genuinely independent sources — a direct exchange feed against an aggregator, a consolidated tape against a proprietary feed, two commercial vendors — and a strategy must price off them continuously. The component answers one question per tick:
Is there a price we are entitled to trade on, and has anything actually verified it?
Those are two different claims, and conflating them is what makes a redundant feed pair dangerous rather than safe. A price emitted during a failover is usable but nothing checks it; a price emitted while two feeds disagree is neither.
When NOT to Use
- For A/B line arbitration on one exchange feed. CME MDP 3.0 sends every packet on both "UDP Feed A" and "UDP Feed B" precisely so UDP loss on one line is covered by the other. Those are copies of one stream in one sequence space, arbitrated losslessly by packet sequence number — first copy wins, duplicate discarded, gap triggers recovery. Price-divergence logic on identical lines is strictly worse than sequence arbitration. See
sequence-number-gap-detection-for-feeds. - As a substitute for book reconciliation. This compares one scalar price per vendor. Snapshot-plus-delta consistency belongs in
market-data-snapshot-plus-delta-reconciliation. - With three or more sources. Two feeds cannot identify which one is wrong (see the workflow below). With three, median/MAD outlier filtering can attribute the outlier — use
multi-source-price-reconciliation-tie-breaking. - Across unlike price bases. Vendor A's last trade against Vendor B's quote midpoint diverges by roughly half a spread permanently. Normalise first:
multi-exchange-feed-normalization. - As a risk control. It emits a trust flag; it does not stop trading. Wire
is_trusted=Falseintokill-switch-and-drawdown-circuit-breakersorgraduated-response-to-data-quality-degradationto make it act.
Prerequisites
- Two vendor streams for the same symbol on the same price basis, plus a per-vendor entitlement to use them for the intended purpose.
- A single local receipt clock for both feeds — never vendor- or exchange-supplied event timestamps. Staleness is a duration; measuring it across two vendors' clocks measures their skew instead (
clock-skew-correction-for-tick-timestamps). - A per-instrument divergence tolerance calibrated from recorded cross-vendor history, floored at the instrument's minimum price increment expressed in percent.
- A supervisor timer able to call the health check at an interval well below the stale threshold.
Workflow
-
Confirm the two feeds are actually independent.
- Decision point: if both lines carry the same sequence space, stop — this is A/B arbitration, not vendor arbitration, and belongs in a sequence-number handler.
-
Floor the divergence tolerance at one tick.
- A tolerance below one minimum price increment makes every legal one-tick disagreement a breach. Under Reg NMS Rule 612 an NMS stock quoted at or above $1.00 moves in $0.01 increments, so one tick exceeds 5 bps for any stock under $20 — the common "5 bps" default silently mis-fires across most of the sub-$20 universe.
-
Validate every tick before it reaches state.
- Reject non-finite and non-positive prices at the boundary. NaN fails every comparison (
nan <= toleranceisFalse), so an unchecked NaN routes to the divergence branch and is published as a tradeable price. - Decision point: a tick older than that vendor's last observation is a replay — drop it. Overwriting a newer observation rewinds the vendor's age and can un-stale a feed that has actually died.
- Reject non-finite and non-positive prices at the boundary. NaN fails every comparison (
-
Classify staleness before comparing prices.
- One feed stale → fail over to the survivor; the price is usable but no longer cross-verified.
- Decision point: if the survivor is itself a quarantined feed, do not promote it silently. Emit the price untrusted — being last does not make it right.
- Both feeds stale → no price at all.
consensus_priceisNone, not the last good value.
-
Detect the blackout the tick path cannot see.
- An arriving tick is always fresh, so a vendor is only ever seen as stale by its counterpart's traffic. When both vendors go silent — the outage the whole component exists for — no tick arrives and nothing is evaluated. A supervisor must call the health check on a timer.
-
Compare only observations that are close enough in time to be comparable.
- Two feeds read at two instants are two different observations. Averaging them manufactures a price that never existed; blaming a vendor for the difference blames it for the market having moved.
- Decision point: when the observations are not simultaneous, take the freshest price, attribute nothing, and mark it unverified if it also breaches tolerance.
-
Arbitrate simultaneous, fresh observations.
- Within tolerance → emit the midpoint as the only cross-verified state.
- Beyond tolerance → do not quarantine on the first disagreeing tick. A fast market produces exactly this signature for as long as one feed leads.
-
Attribute on evidence before falling back on policy.
- Evidence: a vendor still delivering ticks but repeating one price while the counterpart moves is demonstrably not tracking the market. Quarantine it — this attribution requires no policy choice.
- Policy: a divergence that persists past the confirmation window with no distinguishing evidence resolves to the operator-configured reference vendor. With two sources this is a preference, not a detection — record it as such rather than reporting the other vendor as a detected outlier.
- Everything in between is emitted with
is_trusted=False. Downstream must not open new risk on an unresolved price.
-
Release quarantines on hysteresis, never on the first agreement.
- Require N consecutive clean comparisons. Releasing immediately flaps between quarantine and consensus tick by tick.
-
Alert on transitions, not on ticks.
- Log on state change. A per-tick error log is a log storm on a hot path in exactly the fast market where the logs matter. EU firms should note that RTS 6 Article 16 requires real-time alerts within five seconds of the relevant event.
Full procedure: see
references/workflows.md. Standards and sourced citations: seereferences/standards.md. Printable pre-flight checklist: seeassets/checklist.md.
Common Pitfalls
- Treating divergence as evidence of a bad tick. Cross-vendor disagreement is dominated by relative latency. The SEC's Market Data Infrastructure release describes the structural gap: proprietary feed subscribers "receive more content-rich data faster" than consolidated-tape consumers. A feed that is merely ahead is not an outlier.
- Blaming a fixed vendor on divergence. Defaulting to the primary on every breach means a bad tick on the primary is published as the arbitrated price while the healthy secondary is reported as the outlier — the failure inverted.
- Tolerances below one tick. 0.05% on a $12 stock is half a minimum increment; every legal one-cent disagreement raises an alarm.
- Stale-price-as-consensus. A vendor frozen at its last price for ten seconds still "agrees" with anything close to it. Only a comparison between two fresh observations means anything.
- Blackout invisibility. Stale detection driven only by arriving ticks cannot fire when every feed dies, which is the one outage that matters most.
- Reporting zero divergence when nothing was compared. A failover result carrying
divergence = 0.0reads on a dashboard as "the feeds agreed exactly." - Averaging non-simultaneous prices. The midpoint of a current price and a three-second-old price is a number no venue ever quoted, and it lags.
- Quarantine flapping. Without hysteresis, one clean tick releases the quarantine and the next breach re-raises it, several times a second.
- Promoting a quarantined feed on failover. The last feed standing may be the one you distrusted five seconds ago.
- Vendor event timestamps as receipt times. Staleness computed across two vendors' clocks measures clock skew, and a skew of more than the stale threshold marks a perfectly healthy feed dead.
Verification
- Feed two simultaneous ticks within tolerance and confirm
decision == CONSENSUS,is_cross_verified is True, and the midpoint price. - Inject a 5% spike on one vendor and confirm the first divergent tick returns
DIVERGENCE_UNRESOLVEDwithis_trusted Falseand no quarantine, then confirm a divergence persisting past the confirmation window escalates toQUARANTINE_ACTIVElabelled as the configured reference-vendor policy. - Let a real move propagate to the second feed inside the confirmation window and confirm nothing is quarantined.
- Hold one vendor's price constant while the other moves, and confirm the frozen vendor is quarantined on evidence with
FROZEN_PRICE. - Stop both feeds and confirm the health check returns
NO_TRUSTED_FEEDwithconsensus_price is None. - Submit NaN, infinite, zero and negative prices and confirm each raises before entering state.
- Run
python -m unittest discover -s skills/market-data-feed-arbitration-across-vendors/scriptsand confirm a 100% pass rate.
Related Skills
clock-skew-correction-for-tick-timestampssequence-number-gap-detection-for-feedsmulti-source-price-reconciliation-tie-breakingvendor-outage-fallback-data-source-hierarchymarket-data-latency-monitoring-per-vendormarket-data-snapshot-plus-delta-reconciliationmulti-exchange-feed-normalizationgraduated-response-to-data-quality-degradationbroker-status-page-monitoring-integration