Skip to main content

Module detect

Module detect 

Source
Expand description

Auto-detection — recognising which kind of identifier a raw string is.

Reference data rarely arrives labelled. A spreadsheet cell, a CSV column, or a free-text field holds an identifier, and the consuming system must first decide which one before it can route, settle, or report against it. SecurityId::detect makes that decision: it takes a raw string and returns the single identifier kind it is — or None when nothing fits.

  "5493001KJTIIGC8Y1R12"  ──▶  SecurityId::Lei   (20 chars, MOD 97-10 ok)
  "US0378331005"          ──▶  SecurityId::Isin  (12 chars, Luhn ok)
  "BBG000BLNNH6"          ──▶  SecurityId::Figi  (12 chars, [2]=='G', ok)
  "037833100"             ──▶  SecurityId::Cusip ( 9 chars, X9.6 ok)
  "0263494"               ──▶  SecurityId::Sedol ( 7 chars, weighted ok)
  "DEUTDEFF"              ──▶  SecurityId::Bic   ( 8 chars, ISO 9362)
  "garbage"               ──▶  None

§How detection decides

Detection is checksum-strength first: a passing check digit is high-confidence evidence, so kinds that carry one are tried before kinds that do not. The order is fixed — LEI, ISIN, FIGI, CUSIP, SEDOL, BIC, MIC. Each candidate is the strict parse of the corresponding identifier type, so a kind is only reported when the input is fully, structurally valid for it, check digit included.

Two ambiguities are resolved by that order:

  • ISIN vs FIGI — both are 12 characters. ISIN is tried first; a string that is a valid ISIN is reported as one. FIGI additionally requires character 3 to be the literal G and forbids the seven ISIN-colliding provider prefixes, so a genuine FIGI is never a valid ISIN and falls through to the FIGI branch.
  • CUSIP vs BIC — an 8-character string could be either. CUSIP carries a check digit and is tried first; only a string that is not a valid CUSIP reaches the BIC branch.

§What is not detected

Three kinds are deliberately excluded from auto-detection because they are structural-only and would collide:

  • CFI — 6 upper-case letters; would shadow many other 6-letter inputs.
  • WKN — 6 alphanumeric characters; no check digit to disambiguate.
  • VALOR — 1 to 9 digits; a short run of digits is far too ambiguous.

These have no check digit and overlap heavily with one another and with other kinds, so detection would only guess. Parse them explicitly with Cfi::parse, Wkn::parse, or Valor::parse when the kind is already known.

§MIC and the registry feature

A MIC has no check digit, so a structurally valid MIC alone is weak evidence. Detection therefore reports IdentifierKind::Mic only when the mic-registry feature is enabled and the string is a registered MIC — one present in the embedded ISO 10383 snapshot, via Mic::parse_registered. With the feature disabled, MIC is never auto-detected.

§References

  • ISO 6166 (ISIN), ISO 17442 (LEI), ISO 9362 (BIC), ISO 10383 (MIC), ANSI X9.6 (CUSIP), ANSI X9.145 (FIGI) — the standards whose grammars and check digits this module relies on to tell the kinds apart.

Enums§

IdentifierKind
The kind of a securities identifier — its type tag, with no payload.
SecurityId
Any one validated securities identifier, tagged by its kind.