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/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/deep_freeze.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/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, and DTI.

Defined Under Namespace

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

Constant Summary collapse

VERSION =

Current gem version.

'6.0.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



32
33
34
35
36
# File 'lib/sec_id.rb', line 32

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



49
50
51
# File 'lib/sec_id.rb', line 49

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



86
87
88
89
90
91
92
93
94
# File 'lib/sec_id.rb', line 86

def explain(str, types: nil)
  input = str.to_s.strip
  target_keys = types || identifier_list.map { |k| k.short_name.downcase.to_sym }
  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



69
70
71
# File 'lib/sec_id.rb', line 69

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



138
139
140
# File 'lib/sec_id.rb', line 138

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>)


41
42
43
# File 'lib/sec_id.rb', line 41

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:



101
102
103
104
105
106
107
108
# File 'lib/sec_id.rb', line 101

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:



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sec_id.rb', line 116

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



78
79
80
81
# File 'lib/sec_id.rb', line 78

def scan(text, types: nil, &)
  classes = types&.map { |key| self[key] }
  scanner.call(text, classes: classes, &)
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



59
60
61
62
63
# File 'lib/sec_id.rb', line 59

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

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