module IdentifiersValid

Constants

CUSIP_FORMAT
CUSIP_SPECIAL_CHAR
ISIN_FORMAT
ISIN_REGEX
LETTER_TO_CODE_VALUE
SEDOL_FORMAT
SEDOL_VALID_CHAR
SEDOL_WEIGHT

Public Class Methods

check_cusip_char(char, index) click to toggle source
# File lib/identifiers_valid.rb, line 41
def self.check_cusip_char(char, index)
  v = if char.match?(/\d/)
        char.to_i
      elsif CUSIP_SPECIAL_CHAR[char]
        CUSIP_SPECIAL_CHAR[char]
      else
        char.ord - LETTER_TO_CODE_VALUE + 9
      end
  (index % 2).zero? ? v : v * 2
end
cusip_invalid?(cusip) click to toggle source
# File lib/identifiers_valid.rb, line 52
def self.cusip_invalid?(cusip)
  !cusip_valid?(cusip)
end
cusip_valid?(cusip) click to toggle source
# File lib/identifiers_valid.rb, line 28
def self.cusip_valid?(cusip)
  return nil if cusip.nil? || cusip.size != 9

  proc_cusip = cusip.split(//)
  key = proc_cusip.pop
  sum = proc_cusip.each_with_index.map do |char, i|
    v = check_cusip_char(char, i)
    (v / 10).to_i + (v % 10)
  end.inject(:+)

  valid?(sum, key) ? cusip : nil
end
identifier_invalid?(value, field_key) click to toggle source
# File lib/identifiers_valid.rb, line 24
def self.identifier_invalid?(value, field_key)
  !identifier_valid?(value, field_key)
end
identifier_valid?(value, field_key) click to toggle source
# File lib/identifiers_valid.rb, line 13
def self.identifier_valid?(value, field_key)
  case field_key.to_s.upcase
  when 'ISIN'
    isin_valid?(value)
  when 'SEDOL'
    sedol_valid?(value)
  when 'CUSIP'
    cusip_valid?(value)
  end
end
isin_invalid?(isin) click to toggle source
# File lib/identifiers_valid.rb, line 85
def self.isin_invalid?(isin)
  !isin_valid?(isin)
end
isin_valid?(isin) click to toggle source
# File lib/identifiers_valid.rb, line 71
def self.isin_valid?(isin)
  return nil if isin.nil? || !isin.match?(ISIN_REGEX)

  proc_isin = isin.split(//)
  key = proc_isin.pop.to_i
  proc_isin = proc_isin.map do |e|
    e.match?(/[A-Z]/) ? (e.ord - LETTER_TO_CODE_VALUE).to_s.split(//) : e
  end.flatten.reverse
  proc_isin.each_index do |i|
    proc_isin[i] = (proc_isin[i].to_i * 2).to_s.split(//) if (i % 2).zero?
  end.flatten!
  ((key + proc_isin.map(&:to_i).inject(:+)) % 10).zero? ? isin : nil
end
sedol_invalid?(sedol) click to toggle source
# File lib/identifiers_valid.rb, line 67
def self.sedol_invalid?(sedol)
  !sedol_valid?(sedol)
end
sedol_valid?(sedol) click to toggle source
# File lib/identifiers_valid.rb, line 56
def self.sedol_valid?(sedol)
  return nil if sedol.nil? || sedol.size != 7

  proc_sedol = sedol.split(//)
  proc_sedol.each { |char| return nil unless SEDOL_VALID_CHAR.include?(char) }
  key = proc_sedol.pop
  sum = proc_sedol.zip(SEDOL_WEIGHT)
                  .map { |ch, weight| ch.to_i(36) * weight }.inject(:+)
  valid?(sum, key) ? sedol : nil
end
valid?(sum, key) click to toggle source
# File lib/identifiers_valid.rb, line 89
def self.valid?(sum, key)
  ((10 - (sum % 10)) % 10).to_s == key
end