Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The current state of every feed:
| [Order-Intent](./order-intent/spec.md) | `0x494F` | `3` | 3.0.1 |
| [Perp Stats](./perp-stats/spec.md) | `0x4450` | `3` | 3.0.1 |
| [Reference Data Distribution](./reference-data/spec.md) | *(host feed's)* | *(host feed's)* | 1.0.2 |
| [Source ID Registry](./sources/spec.md) | *(none)* | *(none)* | 1.2.0 |
| [Source ID Registry](./sources/spec.md) | *(none)* | *(none)* | 1.4.0 |
| [Glossary](./GLOSSARY.md) | *(none)* | *(none)* | 1.3.0 |

Midpoint sits at `1` while its siblings are at `3` because it was deliberately left on its 64-byte `InstrumentDefinition` variant when the shared layout changed at both `2.0.0` and `3.0.0`. This is the scheme working as intended: the specs are siblings, not a single versioned family, and a decoder reads each feed's byte to know which layout it is holding.
Expand Down
28 changes: 16 additions & 12 deletions sources/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ A Source ID identifies the **matching engine** whose activity the message descri

**A Source ID names a matching engine, not a venue.** One venue may run several matching engines and therefore hold several Source IDs. Two engines are distinct where their order-matching rules differ, and equally where they match independently over disjoint instrument sets under identical rules; a capacity shard the venue can rebalance is a channel rather than an engine. [GLOSSARY.md](../GLOSSARY.md) carries the full test and is the authority for it. A new engine at an already-registered venue is a new ID rather than a reuse of that venue's existing one. Because IDs are never renumbered, this only ever adds, and an ID already assigned keeps meaning whichever engine has been publishing under it. Venues split their own engines on their own schedule, so treat the set as open rather than assuming the current table is final.

This document specifies version **1.3.0**: the reserved ranges, the current assignment set, and the process for requesting a new ID.
**A distinct market identifier code is strong evidence of a distinct engine.** Where a regulated venue operates under several ISO 10383 MICs, each names a market with its own rulebook and its own matching, so the MIC settles the test above without further argument. The converse does not hold: one MIC routinely covers several engines, which is the ordinary case wherever a venue runs spot and derivatives under one code. Treat a distinct MIC as sufficient, never as necessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The MIC criterion over-splits: ISO 10383 segment MICs routinely share one matching engine.

Line 9 says a distinct MIC "settles the test above without further argument". But ISO 10383 has operating MICs and segment MICs, and segment MICs commonly name market segments of a single matching platform rather than separate matching. Euronext Paris carries XPAR plus XMLI, ALXP, XMAT and others, all matched on one Optiq platform under one rulebook; London and Deutsche Börse are the same shape.

Under this paragraph as written, that venue is entitled to a separate Source ID per segment MIC — which is exactly the case GLOSSARY.md excludes ("a capacity shard the venue can rebalance is a channel rather than an engine"). The registry would grant four IDs where the authoritative test grants one, and IDs are never renumbered, so the split is unrecoverable.

Worth narrowing to operating MICs, or restating the criterion at the strength the bold lead sentence uses. The lead says "strong evidence" and the closing sentence says "sufficient" — those are different rules, and a requester will read whichever helps them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This widens the engine-distinctness test in the document that disclaims authority over it.

Line 7, unchanged just above: "GLOSSARY.md carries the full test and is the authority for it." GLOSSARY.md Matching engine (1.3.0) states a two-limb test — rules differ, or independent matching over disjoint sets — and is not touched by this PR.

So after this merges, a requester following the stated authority applies two limbs and a reviewer applying sources/spec.md 1.4.0 applies three, and the same request resolves differently depending on which document was consulted.

The repo's precedent runs the other way: the last widening landed in GLOSSARY.md 1.3.0 first, and this registry's own 1.2.0 entry records itself as "conformed the Source ID definition above to GLOSSARY.md 1.3.0". Same move here — add the MIC limb to the glossary entry, bump it, and let this document cite it.


This document specifies version **1.4.0**: the reserved ranges, the current assignment set, and the process for requesting a new ID.

## Reserved Ranges

Expand All @@ -19,23 +21,23 @@ This document specifies version **1.3.0**: the reserved ranges, the current assi

## Assigned Source IDs

| ID | Name | Code | Venue | Kind | Notes |
|----|------|------|-------|------|-------|
| `1` | Hyperliquid | `HYPERLIQUID` | Hyperliquid | Perpetual DEX | |
| `2` | Phoenix | `PHOENIX` | Phoenix | Perpetual DEX | |
| `3` | Kalshi | `KALSHI` | Kalshi | Perpetual Futures, Prediction Market | Registered under the codename `Lashay` until the venue launched. Carries two matching engines and is due to split; see below. |
| `4` | Setai Financials | `SETAI_FINANCIALS` | Setai | Futures | Interface versioned separately from `5`. |
| `5` | Setai Commodities | `SETAI_COMMODITIES` | Setai | Futures, Options on Futures | Interface versioned separately from `4`. |
| `6` | Binance USD-Margined Futures | `BINANCE` | Binance | Perpetual Futures, Dated Futures | The venue's own `futuresType` for this engine is `U_MARGINED`. Spot, coin-margined futures and options are separate matching engines at this venue, unclaimed, and will share this `Code`. |
| ID | Name | Code | Venue | MIC | Kind | Notes |
|----|------|------|-------|-----|------|-------|
| `1` | Hyperliquid | `HYPERLIQUID` | Hyperliquid | — | Perpetual DEX | |
| `2` | Phoenix | `PHOENIX` | Phoenix | — | Perpetual DEX | |
| `3` | Kalshi | `KALSHI` | Kalshi | `KLSH` | Perpetual Futures, Prediction Market | Registered under the codename `Lashay` until the venue launched. Carries two matching engines and is due to split; see below. |
| `4` | Setai Financials | `SETAI` | Setai | *(withheld)* | Futures | Interface versioned separately from `5`. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Both Setai cells read (withheld), so the only multi-row venue with MICs cannot demonstrate the new rule.

Line 39 says "Where two rows at one venue carry different MICs, that alone establishes them as distinct engines." IDs 4 and 5 are the one place in this table where that could be shown, and both cells are withheld — and the state is defined in the singular ("one exists"), which does not say whether these two rows share a MIC or hold different ones.

There is a second-order effect: if they do hold different MICs — which the withholding rationale implies, since naming them would identify the venue — then line 67's "the first assignment resting on the second half of the rule rather than the first" is superseded by the new sufficient condition and was not updated. Either the withheld state needs to encode same/different, or that sentence needs a clause acknowledging the MIC ground now also applies.

| `5` | Setai Commodities | `SETAI` | Setai | *(withheld)* | Futures, Options on Futures | Interface versioned separately from `4`. |
| `6` | Binance USD-Margined Futures | `BINANCE` | Binance | — | Perpetual Futures, Dated Futures | The venue's own `futuresType` for this engine is `U_MARGINED`. Spot, coin-margined futures and options are separate matching engines at this venue, unclaimed, and will share this `Code`. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The em dash on ID 6 contradicts this document's own account of the venue.

Line 39 defines the em dash as "the venue has none, which is the normal case for a decentralised exchange and for any venue outside the standard's scope". Line 61 says of this same row: "The operator of record is Nest Exchange Limited, licensed in the Abu Dhabi Global Market as a Recognised Investment Exchange for derivatives since 5 January 2026."

A licensed RIE is squarely inside ISO 10383's scope, so the em dash asserts something the ID 6 section denies. The column has three states and none of them means "not researched", so an unfilled cell is indistinguishable from an authoritative "none exists" — and a registry mirror built from this table will carry the assertion.


`Code` is the machine-readable short name **for the venue**. It matches the `Venue` column and takes the same name TradingView uses. Uppercase, never an abbreviation, each space and hyphen a single underscore.

**Several matching engines at one venue share a `Code`.** It names the venue, not the engine, so `Code` alone cannot key an engine: `Source ID` is the engine key, and anything carrying `Code` as a stable identifier — a metric label value, a composed product identifier — needs `source_id` beside it to name an engine. `Name` is where a human reader tells two engines apart.

IDs `4` and `5` predate this rule and still carry engine-level Codes, `SETAI_FINANCIALS` and `SETAI_COMMODITIES`. They are left alone here: a `Code` already in use downstream cannot be changed without coordinating with whoever carries it.

Downstream systems already carry these values, so this column documents what exists rather than introducing anything new. This registry is the authority for it; any table of these values held elsewhere is a [registry mirror](../GLOSSARY.md) and is derived, never authoritative.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR deletes the only statement constraining a change to an existing Code, rather than narrowing it.

The removed sentence read: "a Code already in use downstream cannot be changed without coordinating with whoever carries it." Only its application to IDs 4 and 5 is obsolete; the rule itself is not. After this hunk, nothing in the registry requires coordination before changing any Code, and line 82 still classifies a Code edit on an existing row as a PATCH.

Concretely: a later PR renames KALSHI or BINANCE — values this document itself says downstream carries as metric label values — as a patch release. GLOSSARY.md line 32 records that this failure is silent: "a code that stops matching its live group fails silently rather than loudly." The compatibility promise at line 84 only covers what an ID means; it says nothing about the Code column.

Suggest keeping the general rule and dropping just the IDs 4/5 clause.


`MIC` is the engine's ISO 10383 market identifier code. An em dash means the venue has none, which is the normal case for a decentralised exchange and for any venue outside the standard's scope; *(withheld)* means one exists but naming it would identify a venue trading under a codename. Where two rows at one venue carry different MICs, that alone establishes them as distinct engines.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

MIC is defined here as the engine's code, which line 9 denies and row 3 disproves.

Line 9, added in this same PR: "one MIC routinely covers several engines". Line 74 repeats the framing — "records the engine's MIC where it has one". Engines do not hold MICs; markets and market operators do.

Row 3 is the counterexample already in the table: it carries one MIC KLSH while its own section says it "carries two matching engines and is due to split". When that split lands, a requester following step 2 must record "the engine's MIC" for each new row, finds only one venue-level code exists, and has no rule saying whether duplicating KLSH across both rows is correct.

"the market identifier code under which the engine trades" (or "the venue's MIC for this market") would match how the rest of the paragraph actually behaves.


`Venue` is the external exchange or market operator running the engine, as [GLOSSARY.md](../GLOSSARY.md) defines it. It is recorded separately from `Name` so that several engines at one venue are legible as such, which is the case the `Name` column alone cannot show.

Name the venue as TradingView does, where TradingView lists it. Its [data coverage list](https://www.tradingview.com/data-coverage/) is the reference. That is one fewer name for a subscriber to map. This governs `Venue` and `Code`, which carry the same name. TradingView has one name per venue and distinguishes products in the symbol, so it cannot name a matching engine, and neither column tries to: `Source ID` and `Name` do that.
Expand Down Expand Up @@ -69,7 +71,7 @@ Recorded because it is the first assignment resting on the second half of the ru
To request a new Source ID, open a pull request against this file that:

1. Adds a row to the **Assigned Source IDs** table with the next unused ID in the production range.
2. Names the matching engine in `Name`, gives its uppercase `Code`, names the exchange running it in `Venue`, and fills in `Kind` and (optionally) `Notes`.
2. Names the matching engine in `Name`, gives its uppercase `Code`, names the exchange running it in `Venue`, records the engine's `MIC` where it has one, and fills in `Kind` and (optionally) `Notes`.
3. States what makes the engine distinct from any already-registered engine at the same venue, where there is one.
4. Does not renumber, reorder, or remove existing rows.

Expand All @@ -83,6 +85,8 @@ Because assigned IDs are stable and MUST NOT be renumbered, reordered, removed,

### Changes

**1.4.0** — added the `MIC` column, recording each engine's ISO 10383 market identifier code, and stated that a distinct MIC is sufficient though not necessary to establish a distinct engine. Conformed `Code` on IDs `4` and `5` to the venue-level rule from `1.3.0`; both now read `SETAI`. No assignment changed and no ID was renumbered.

**1.3.0** — assigned Source ID `6` to the USD-margined futures matching engine at Binance, and made `Code` name the venue rather than the matching engine. Several engines at one venue now share a `Code`, so `Code` alone no longer keys an engine and `Source ID` is stated as the engine key. This supersedes `1.2.1`'s statement that `Code` names the matching engine and stays unique. IDs `4` and `5` keep their engine-level Codes, because a `Code` already carried downstream cannot be changed without coordination.

**1.2.1** — editorial. Name the venue as TradingView does. `Code` is unaffected, because TradingView cannot name a matching engine.
Expand Down