Module: SecID

Defined in:
lib/sec_id.rb,
lib/sec_id/bic.rb,
lib/sec_id/cei.rb,
lib/sec_id/cfi.rb,
lib/sec_id/cik.rb,
lib/sec_id/dti.rb,
lib/sec_id/lei.rb,
lib/sec_id/occ.rb,
lib/sec_id/upi.rb,
lib/sec_id/wkn.rb,
lib/sec_id/base.rb,
lib/sec_id/figi.rb,
lib/sec_id/fisn.rb,
lib/sec_id/iban.rb,
lib/sec_id/isin.rb,
lib/sec_id/cusip.rb,
lib/sec_id/sedol.rb,
lib/sec_id/errors.rb,
lib/sec_id/railtie.rb,
lib/sec_id/scanner.rb,
lib/sec_id/valoren.rb,
lib/sec_id/version.rb,
lib/sec_id/detector.rb,
lib/sec_id/cfi/field.rb,
lib/sec_id/cfi/tables.rb,
lib/sec_id/suggestion.rb,
lib/sec_id/deep_freeze.rb,
lib/sec_id/deprecation.rb,
lib/sec_id/bic/country_codes.rb,
lib/sec_id/cfi/attribute_set.rb,
lib/sec_id/cfi/classification.rb,
lib/sec_id/concerns/checkable.rb,
lib/sec_id/iban/country_rules.rb,
lib/sec_id/concerns/generatable.rb,
lib/sec_id/concerns/suggestable.rb,
lib/sec_id/concerns/validatable.rb,
lib/sec_id/concerns/normalizable.rb

Overview

Toolkit for securities identifiers — validate, normalize, parse, detect, convert, generate, and classify ISIN, CUSIP, CEI, SEDOL, FIGI, LEI, IBAN, CIK, OCC, WKN, Valoren, CFI, FISN, BIC, DTI, and UPI.

Defined Under Namespace

Modules: Checkable, DeepFreeze, Deprecation, Generatable, Normalizable, Suggestable, Validatable Classes: AmbiguousMatchError, BIC, Base, CEI, CFI, CIK, CUSIP, DTI, Detector, Error, Errors, FIGI, FISN, IBAN, ISIN, InvalidChecksumError, InvalidFormatError, InvalidStructureError, LEI, Match, OCC, Railtie, SEDOL, Scanner, Suggestion, UPI, Valoren, WKN

Constant Summary collapse

InvalidCheckDigitError =
Deprecated.

Use InvalidChecksumError. Kept as a v7 bridge (same class object, so rescue under either name keeps working); removed in v8.

InvalidChecksumError
VERSION =

Current gem version.

'7.1.0'

Class Method Summary collapse

Class Method Details

.[](key) ⇒ Class

Looks up an identifier class by its symbol key.

Parameters:

  • key (Symbol)

    identifier type (e.g. :isin, :cusip)

Returns:

  • (Class)

    the identifier class

Raises:

  • (ArgumentError)

    if key is unknown



36
37
38
39
40
# File 'lib/sec_id.rb', line 36

def [](key)
  identifier_map.fetch(key) do
    raise ArgumentError, "Unknown identifier type: #{key.inspect}"
  end
end

.detect(str) ⇒ Array<Symbol>

Detects all identifier types that match the given string.

Parameters:

  • str (String, nil)

    the identifier string to detect

Returns:

  • (Array<Symbol>)

    matching type symbols sorted by specificity



53
54
55
# File 'lib/sec_id.rb', line 53

def detect(str)
  detector.call(str)
end

.explain(str, types: nil) ⇒ Hash

Returns hash with :input and :candidates keys.

Parameters:

  • str (String, nil)

    the identifier string to explain

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types

Returns:

  • (Hash)

    hash with :input and :candidates keys



90
91
92
93
94
95
96
97
98
# File 'lib/sec_id.rb', line 90

def explain(str, types: nil)
  input = str.to_s.strip
  target_keys = types || identifier_list.map(&:type_key)
  candidates = target_keys.map do |key|
    instance = self[key].new(input)
    { type: key, valid: instance.valid?, errors: instance.errors.details }
  end
  { input: input, candidates: candidates }
end

.extract(text, types: nil) ⇒ Array<Match>

Parameters:

  • text (String, nil)

    the text to scan

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types

Returns:

Raises:

  • (ArgumentError)

    if any key in types is unknown



73
74
75
# File 'lib/sec_id.rb', line 73

def extract(text, types: nil)
  scan(text, types: types).to_a
end

.generate(key, random: Random.new) ⇒ SecID::Base

Note:

Generated identifiers are valid in format only — they are not real, registered securities.

Generates a new, format-valid identifier instance of the given type.

Parameters:

  • key (Symbol)

    identifier type (e.g. :isin, :cusip)

  • random (Random) (defaults to: Random.new)

    seedable source for reproducible output

Returns:

  • (SecID::Base)

    a generated, format-valid instance of the type mapped to key (e.g. ISIN for :isin)

Raises:

  • (ArgumentError)

    if key is unknown



142
143
144
# File 'lib/sec_id.rb', line 142

def generate(key, random: Random.new)
  self[key].generate(random: random)
end

.identifiersArray<Class>

Returns all registered identifier classes in load order.

Returns:

  • (Array<Class>)


45
46
47
# File 'lib/sec_id.rb', line 45

def identifiers
  identifier_list.dup
end

.parse(str, types: nil, on_ambiguous: :first) ⇒ SecID::Base, ...

Returns depends on on_ambiguous mode.

Parameters:

  • str (String, nil)

    the identifier string to parse

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types (e.g. [:isin, :cusip])

  • on_ambiguous (:first, :raise, :all) (defaults to: :first)

    how to handle multiple matches

Returns:

Raises:



105
106
107
108
109
110
111
112
# File 'lib/sec_id.rb', line 105

def parse(str, types: nil, on_ambiguous: :first)
  case on_ambiguous
  when :first then types.nil? ? parse_any(str) : parse_from(str, types)
  when :raise then parse_strict(str, types)
  when :all   then parse_all(str, types)
  else raise ArgumentError, "Unknown on_ambiguous mode: #{on_ambiguous.inspect}"
  end
end

.parse!(str, types: nil, on_ambiguous: :first) ⇒ SecID::Base+

Returns depends on on_ambiguous mode.

Parameters:

  • str (String, nil)

    the identifier string to parse

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types (e.g. [:isin, :cusip])

  • on_ambiguous (:first, :raise, :all) (defaults to: :first)

    how to handle multiple matches

Returns:

Raises:



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/sec_id.rb', line 120

def parse!(str, types: nil, on_ambiguous: :first)
  result = parse(str, types: types, on_ambiguous: on_ambiguous)

  if on_ambiguous == :all
    raise(InvalidFormatError, parse_error_message(str, types)) if result.empty?

    return result
  end

  result || raise(InvalidFormatError, parse_error_message(str, types))
end

.scan(text, types: nil) {|match| ... } ⇒ Enumerator<Match>

Returns if no block given.

Parameters:

  • text (String, nil)

    the text to scan

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types

Yield Parameters:

Returns:

  • (Enumerator<Match>)

    if no block given

Raises:

  • (ArgumentError)

    if any key in types is unknown



82
83
84
85
# File 'lib/sec_id.rb', line 82

def scan(text, types: nil, &)
  classes = types&.map { |key| self[key] }
  scanner.call(text, classes: classes, &)
end

.suggest(str, types: nil) ⇒ Array<Suggestion>

Note:

Repair is only defined for checksum types; non-checksum types have no oracle and are silently skipped.

Returns confidence-ranked repair candidates for a checksum-failing identifier, inferred across all format-compatible checksum types (or the given types:).

Parameters:

  • str (String, nil)

    the identifier string to repair

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types (non-checksum types are ignored)

Returns:

  • (Array<Suggestion>)

    cross-type ranked candidates, each carrying its type; empty when no format-compatible checksum type matches

Raises:

  • (ArgumentError)

    if any key in types is unknown



157
158
159
160
161
162
# File 'lib/sec_id.rb', line 157

def suggest(str, types: nil)
  input = str.to_s.strip.upcase
  suggestable_types(input, types)
    .flat_map { |klass| klass.suggest(input) }
    .sort_by { |suggestion| [Suggestable::RANK.fetch(suggestion.edit), self[suggestion.type].detection_priority.last] }
end

.valid?(str, types: nil) ⇒ Boolean

Checks whether the string is a valid identifier.

Parameters:

  • str (String, nil)

    the identifier string to validate

  • types (Array<Symbol>, nil) (defaults to: nil)

    restrict to specific types (e.g. [:isin, :cusip])

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)

    if any key in types is unknown



63
64
65
66
67
# File 'lib/sec_id.rb', line 63

def valid?(str, types: nil)
  return detector.matches?(str) if types.nil?

  types.any? { |key| self[key].valid?(str) }
end