Duplicate-Trade Resolver
Install and import
npm install fintech-algorithmsimport { resolveTrades } from "fintech-algorithms/market-data-engineering/cleaning-and-validation/duplicate-trade-resolver";Signature
resolveTrades(input)Reconciles a stream of new, corrected and cancelled trade messages into one authoritative set. Replays of the same message must be idempotent, and a cancellation must survive a later redelivery of the trade it cancelled.
Parameters
| Name | Type | Notes |
|---|---|---|
input | TradeMessage[] | Messages carrying source_id, session_id, instrument_id, event_id, trade_id and an action of new, correct or cancel. |
Returns
{ policy_version, active, states, tombstones, pending, versions, raw_history, audit }
The resolved set (active), cancelled trades kept as tombstones so a redelivery cannot resurrect them, messages awaiting a predecessor (pending), and a full audit of how each decision was reached.
Errors
- When a message is missing an identifier required to place it — recorded in the audit rather than thrown
Complexity: time O(n),
space O(n).
Worked example
executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.
Input
[
{
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E2",
"trade_id": "T1",
"action": "CORRECT",
"ref_event_id": "E1",
"receive_ts": "2026-07-20T13:30:00.003Z",
"sequence": 2,
"price": 101,
"size": 12
},
{
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E1",
"trade_id": "T1",
"action": "NEW",
"receive_ts": "2026-07-20T13:30:00.004Z",
"sequence": 1,
"price": 100,
"size": 10
},
{
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E1",
"trade_id": "T1",
"action": "NEW",
"receive_ts": "2026-07-20T13:30:00.004Z",
"sequence": 1,
"price": 100,
"size": 10
}
]Showing 3 of 24 elements.
Call
resolveTrades(input)Returns
object with 8 fields: policy_version, active, states, tombstones, pending, versions, raw_history, audit
{
"policy_version": "synthetic-lifecycle-v2",
"active": [
{
"trade_key": "SIP-X|2026-07-20|XYZ|T5",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T5",
"status": "ACTIVE",
"head_event_id": "E13",
"head_event_key": "SIP-X|2026-07-20|E13",
"price": 80.5,
"size": 32,
"chain": ["E12", "E13"]
}
],
"states": {
"SIP-X|2026-07-20|XYZ|T1": {
"trade_key": "SIP-X|2026-07-20|XYZ|T1",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T1",
"status": "CANCELED",
"head_event_id": "E3",
"head_event_key": "SIP-X|2026-07-20|E3",
"price": 101,
"size": 12,
"chain": ["E1", "E2", "E3"],
"tombstone": {
"action": "CANCEL",
"event_id": "E3",
"ref_event_id": "E2"
}
},
"SIP-X|2026-07-20|XYZ|T3": {
"trade_key": "SIP-X|2026-07-20|XYZ|T3",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T3",
"status": "ERRORED",
"head_event_id": "E8",
"head_event_key": "SIP-X|2026-07-20|E8",
"price": 75,
"size": 20,
"chain": ["E7", "E8"],
"tombstone": {
"action": "ERROR",
"event_id": "E8",
"ref_event_id": "E7"
}
},
"SIP-X|2026-07-20|XYZ|T4": {
"trade_key": "SIP-X|2026-07-20|XYZ|T4",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T4",
"status": "CANCELED",
"head_event_id": "E18",
"head_event_key": "SIP-X|2026-07-20|E18",
"price": 60,
"size": 8,
"chain": ["E9", "E18"],
"tombstone": {
"action": "CANCEL",
"event_id": "E18",
"ref_event_id": "E9"
}
},
"SIP-X|2026-07-20|XYZ|T5": {
"trade_key": "SIP-X|2026-07-20|XYZ|T5",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T5",
"status": "ACTIVE",
"head_event_id": "E13",
"head_event_key": "SIP-X|2026-07-20|E13",
"price": 80.5,
"size": 32,
"chain": ["E12", "E13"]
},
"SIP-X|2026-07-21|XYZ|T1": {
"trade_key": "SIP-X|2026-07-21|XYZ|T1",
"source_id": "SIP-X",
"session_id": "2026-07-21",
"instrument_id": "XYZ",
"trade_id": "T1",
"status": "ERRORED",
"head_event_id": "E2",
"head_event_key": "SIP-X|2026-07-21|E2",
"price": 103,
"size": 11,
"chain": ["E1", "E2"],
"tombstone": {
"action": "ERROR",
"event_id": "E2",
"ref_event_id": "E1"
}
}
},
"tombstones": [
{
"trade_key": "SIP-X|2026-07-20|XYZ|T1",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T1",
"status": "CANCELED",
"head_event_id": "E3",
"head_event_key": "SIP-X|2026-07-20|E3",
"price": 101,
"size": 12,
"chain": ["E1", "E2", "E3"],
"tombstone": {
"action": "CANCEL",
"event_id": "E3",
"ref_event_id": "E2"
}
},
{
"trade_key": "SIP-X|2026-07-20|XYZ|T3",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T3",
"status": "ERRORED",
"head_event_id": "E8",
"head_event_key": "SIP-X|2026-07-20|E8",
"price": 75,
"size": 20,
"chain": ["E7", "E8"],
"tombstone": {
"action": "ERROR",
"event_id": "E8",
"ref_event_id": "E7"
}
},
{
"trade_key": "SIP-X|2026-07-20|XYZ|T4",
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"trade_id": "T4",
"status": "CANCELED",
"head_event_id": "E18",
"head_event_key": "SIP-X|2026-07-20|E18",
"price": 60,
"size": 8,
"chain": ["E9", "E18"],
"tombstone": {
"action": "CANCEL",
"event_id": "E18",
"ref_event_id": "E9"
}
}
],
"pending": [
{
"event_key": "SIP-X|2026-07-20|E10",
"trade_key": "SIP-X|2026-07-20|XYZ|T4",
"ref_event_id": "MISSING",
"action": "CORRECT"
}
],
"versions": [
{
"event_key": "SIP-X|2026-07-20|E1",
"trade_key": "SIP-X|2026-07-20|XYZ|T1",
"event_id": "E1",
"action": "NEW",
"sequence": 1,
"price": 100,
"size": 10,
"decision": "APPLY_NEW",
"head_before": null,
"head_after": "E1"
},
{
"event_key": "SIP-X|2026-07-20|E2",
"trade_key": "SIP-X|2026-07-20|XYZ|T1",
"event_id": "E2",
"action": "CORRECT",
"ref_event_id": "E1",
"sequence": 2,
"price": 101,
"size": 12,
"decision": "APPLY_CORRECTION",
"head_before": "E1",
"head_after": "E2"
},
{
"event_key": "SIP-X|2026-07-20|E3",
"trade_key": "SIP-X|2026-07-20|XYZ|T1",
"event_id": "E3",
"action": "CANCEL",
"ref_event_id": "E2",
"sequence": 3,
"decision": "APPLY_CANCEL",
"head_before": "E2",
"head_after": "E3"
}
],
"raw_history": [
{
"arrival_index": 0,
"event": {
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E2",
"trade_id": "T1",
"action": "CORRECT",
"ref_event_id": "E1",
"receive_ts": "2026-07-20T13:30:00.003Z",
"sequence": 2,
"price": 101,
"size": 12
},
"validation_errors": []
},
{
"arrival_index": 1,
"event": {
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E1",
"trade_id": "T1",
"action": "NEW",
"receive_ts": "2026-07-20T13:30:00.004Z",
"sequence": 1,
"price": 100,
"size": 10
},
"validation_errors": []
},
{
"arrival_index": 2,
"event": {
"source_id": "SIP-X",
"session_id": "2026-07-20",
"instrument_id": "XYZ",
"event_id": "E1",
"trade_id": "T1",
"action": "NEW",
"receive_ts": "2026-07-20T13:30:00.004Z",
"sequence": 1,
"price": 100,
"size": 10
},
"validation_errors": []
}
],
"audit": [
{
"arrival_index": 0,
"event_id": "E2",
"trade_id": "T1",
"decision": "APPLY_CORRECTION",
"reason": "correction references the current active version"
},
{
"arrival_index": 1,
"event_id": "E1",
"trade_id": "T1",
"decision": "APPLY_NEW",
"reason": "first valid NEW for this scoped trade key"
},
{
"arrival_index": 2,
"event_id": "E1",
"trade_id": "T1",
"decision": "DROP_REPLAY",
"reason": "byte-equivalent normalized event_id already retained"
}
]
}Diagrams
Calculation flow
Resolution state and evidence paths
stateDiagram-v2 [*] --> Absent Absent --> Active: valid NEW Active --> Active: linked current-head CORRECT Active --> Canceled: linked CANCEL Active --> Errored: linked ERROR Absent --> Pending: missing parent Active --> Quarantine: stale or cross-key reference Absent --> Quarantine: ID or sequence conflict Active --> Active: exact replay or duplicate NEW Canceled --> Quarantine: later lifecycle action Errored --> Quarantine: later lifecycle action
How it works
This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.
References
- Daily TAQ Client Specifications — New York Stock Exchange / Intercontinental Exchange
- Nasdaq TotalView-ITCH — Nasdaq
- Business Area: Post-Trade — FIX Trading Community
- TradeReportTransType — FIX Trading Community
- Dataset and historical-example note