sec_id 4.2.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -21
- data/README.md +286 -99
- data/lib/sec_id/base.rb +64 -67
- data/lib/sec_id/cei.rb +51 -0
- data/lib/sec_id/cfi.rb +314 -0
- data/lib/sec_id/cik.rb +29 -33
- data/lib/sec_id/concerns/checkable.rb +201 -0
- data/lib/sec_id/concerns/normalizable.rb +35 -0
- data/lib/sec_id/cusip.rb +30 -22
- data/lib/sec_id/figi.rb +29 -20
- data/lib/sec_id/fisn.rb +52 -0
- data/lib/sec_id/iban/country_rules.rb +266 -0
- data/lib/sec_id/iban.rb +159 -0
- data/lib/sec_id/isin.rb +116 -23
- data/lib/sec_id/lei.rb +69 -0
- data/lib/sec_id/occ.rb +106 -65
- data/lib/sec_id/sedol.rb +43 -6
- data/lib/sec_id/valoren.rb +74 -0
- data/lib/sec_id/version.rb +1 -1
- data/lib/sec_id/wkn.rb +41 -0
- data/lib/sec_id.rb +11 -2
- data/sec_id.gemspec +3 -1
- metadata +15 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d1a703602defc67f745ab0994c73f61d964ed1047a029cc01c2cf7edcda82045
|
|
4
|
+
data.tar.gz: cf7a004bb992ceb3a9991946d09c908a76d13852c7a87a0b2527a4633da869be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c4e726ce2c1cd7b64dc6d2f8db7e284166ff0229eef52f064975d244e766e28ba239dd8f39dc1730e3b092ae0e57cf982adb683711cde6dd9b15a4bc8c88eb09
|
|
7
|
+
data.tar.gz: '0986116c63812cc37af215b4f564e3db44d4ea154d90dc49a99e82096fe18e099277087a2b399920e2bf03acbdc69d098b6442c2195d434f2af3230cffe2b257'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,16 +1,66 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
|
|
7
|
+
and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
## [4.4.0] - 2026-01-29
|
|
4
12
|
|
|
5
13
|
### Added
|
|
6
14
|
|
|
7
|
-
-
|
|
15
|
+
- Cross-identifier conversions: SEDOL, WKN, and Valoren `to_isin` methods with country code validation; ISIN `to_sedol`, `to_wkn`, `to_valoren` methods with predicate helpers (`sedol?`, `wkn?`, `valoren?`) ([#115](https://github.com/svyatov/sec_id/pull/115))
|
|
16
|
+
- ISIN `nsin_type` and `to_nsin` methods for country-aware NSIN extraction ([#114](https://github.com/svyatov/sec_id/pull/114))
|
|
17
|
+
- CEI (CUSIP Entity Identifier) support for syndicated loan market entity identification ([#113](https://github.com/svyatov/sec_id/pull/113))
|
|
18
|
+
- FISN (Financial Instrument Short Name) support per ISO 18774 ([#112](https://github.com/svyatov/sec_id/pull/112))
|
|
19
|
+
- CFI (Classification of Financial Instruments) support with category/group validation and equity-specific predicates ([#111](https://github.com/svyatov/sec_id/pull/111))
|
|
20
|
+
- Valoren support (Swiss Security Number) ([@wtn](https://github.com/wtn), [#109](https://github.com/svyatov/sec_id/pull/109))
|
|
21
|
+
- WKN support (Wertpapierkennnummer - German securities identifier) ([@wtn](https://github.com/wtn), [#108](https://github.com/svyatov/sec_id/pull/108))
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Replaced `has_check_digit` DSL with explicit `Checkable` concern that consolidates all check-digit logic (constants, Luhn algorithms, validation, restoration)
|
|
26
|
+
- Simplified `Base` class to core validation and parsing; check-digit classes now `include Checkable`
|
|
27
|
+
- Non-check-digit classes (CIK, OCC, WKN, Valoren, CFI, FISN) no longer need any special declaration
|
|
28
|
+
- Moved `Normalizable` module to `lib/sec_id/concerns/` for consistency with other concerns
|
|
29
|
+
- Optimized hot paths by replacing `&method(:char_to_digit)` with inline blocks to avoid Method object allocation
|
|
30
|
+
- Added frozen Set constants for ISIN country code lookups (`SEDOL_COUNTRY_CODES`, `VALOREN_COUNTRY_CODES`)
|
|
8
31
|
|
|
9
32
|
### Fixed
|
|
10
33
|
|
|
11
|
-
-
|
|
34
|
+
- Allow Crown Dependencies (GG, IM, JE) and Overseas Territories (FK) in SEDOL/ISIN conversions ([@wtn](https://github.com/wtn), [#117](https://github.com/svyatov/sec_id/pull/117))
|
|
35
|
+
- Removed BR (Brazil) from CGS country codes — Brazil never used CINS numbers and Brazilian ISINs cannot be converted to CUSIP ([@wtn](https://github.com/wtn), [#110](https://github.com/svyatov/sec_id/pull/110))
|
|
12
36
|
|
|
13
|
-
|
|
37
|
+
## [4.3.0] - 2025-01-13
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- LEI support (Legal Entity Identifier, ISO 17442)
|
|
42
|
+
- IBAN support (International Bank Account Number, ISO 13616) with EU/EEA country validation
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Improved README: better formatting, navigation, and clear API distinction between check-digit and normalization identifiers
|
|
47
|
+
- Refactored CIK and OCC to inherit from Base class with `has_check_digit?` hook for cleaner architecture
|
|
48
|
+
- Added `Normalizable` module for consistent `normalize!` class method across identifiers
|
|
49
|
+
- Added `validate_format_for_calculation!` helper method to Base class to reduce code duplication
|
|
50
|
+
- Added comprehensive YARD documentation to all classes (public and private methods)
|
|
51
|
+
- Applied Stepdown Rule to method ordering throughout codebase
|
|
52
|
+
- Created shared RSpec examples for edge cases (nil, empty, whitespace inputs)
|
|
53
|
+
- Created shared RSpec examples for check-digit and normalization identifiers
|
|
54
|
+
- Applied shared examples to all identifier specs, removing ~350 lines of duplicate test code
|
|
55
|
+
- Improved test maintainability with 582 tests covering all identifier types
|
|
56
|
+
|
|
57
|
+
## [4.2.0] - 2025-01-12
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- OCC support ([@wtn](https://github.com/wtn), [#93](https://github.com/svyatov/sec_id/pull/93))
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
14
64
|
|
|
15
65
|
- Separate CIK from Base for cleaner architecture ([@wtn](https://github.com/wtn), [#92](https://github.com/svyatov/sec_id/pull/92))
|
|
16
66
|
- Use rubocop-rspec plugin ([@wtn](https://github.com/wtn), [#90](https://github.com/svyatov/sec_id/pull/90))
|
|
@@ -18,6 +68,10 @@
|
|
|
18
68
|
- Add permissions to CI workflow
|
|
19
69
|
- Clean up gemspec: update description and simplify files list
|
|
20
70
|
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- CUSIP#cins? usage example in README ([@wtn](https://github.com/wtn), [#91](https://github.com/svyatov/sec_id/pull/91))
|
|
74
|
+
|
|
21
75
|
## [4.1.0] - 2024-09-23
|
|
22
76
|
|
|
23
77
|
### Added
|
|
@@ -27,19 +81,16 @@
|
|
|
27
81
|
- Convert between CUSIPs and ISINs ([@wtn](https://github.com/wtn), [#86](https://github.com/svyatov/sec_id/pull/86), [#88](https://github.com/svyatov/sec_id/pull/88))
|
|
28
82
|
- CINS check method for CUSIPs ([@wtn](https://github.com/wtn), [#87](https://github.com/svyatov/sec_id/pull/87))
|
|
29
83
|
|
|
30
|
-
###
|
|
84
|
+
### Changed
|
|
31
85
|
|
|
32
86
|
- Small internal refactorings
|
|
33
87
|
|
|
34
88
|
## [4.0.0] - 2024-07-09
|
|
35
89
|
|
|
36
|
-
###
|
|
37
|
-
|
|
38
|
-
- Minimum required Ruby version is 3.1 now
|
|
39
|
-
- Default repository branch renamed to `main`
|
|
40
|
-
|
|
41
|
-
### Updated
|
|
90
|
+
### Changed
|
|
42
91
|
|
|
92
|
+
- **BREAKING:** Minimum required Ruby version is 3.1 now
|
|
93
|
+
- **BREAKING:** Default repository branch renamed to `main`
|
|
43
94
|
- Small internal refactorings
|
|
44
95
|
- TravisCI -> GitHub Actions
|
|
45
96
|
- Dropped tests for Ruby below 3.1
|
|
@@ -47,12 +98,9 @@
|
|
|
47
98
|
|
|
48
99
|
## [3.0.0] - 2020-03-10
|
|
49
100
|
|
|
50
|
-
###
|
|
51
|
-
|
|
52
|
-
- Minimum required Ruby version is 2.5 now
|
|
53
|
-
|
|
54
|
-
### Updated
|
|
101
|
+
### Changed
|
|
55
102
|
|
|
103
|
+
- **BREAKING:** Minimum required Ruby version is 2.5 now
|
|
56
104
|
- Small internal refactorings
|
|
57
105
|
- TravisCI config updated: dropped Ruby 2.3 and 2.4, added Ruby 2.7
|
|
58
106
|
- Rubocop's Ruby target version changed to 2.5
|
|
@@ -63,11 +111,9 @@
|
|
|
63
111
|
|
|
64
112
|
- SEDOL numbers support: `SecId::SEDOL`
|
|
65
113
|
|
|
66
|
-
###
|
|
67
|
-
|
|
68
|
-
- **Breaking change**
|
|
114
|
+
### Changed
|
|
69
115
|
|
|
70
|
-
|
|
116
|
+
- **BREAKING:** API for accessing full number is unified across all classes:
|
|
71
117
|
|
|
72
118
|
```
|
|
73
119
|
SecId::ISIN#full_number # previously SecId::ISIN#isin
|
|
@@ -86,7 +132,7 @@
|
|
|
86
132
|
- CUSIP numbers support: `SecId::CUSIP`
|
|
87
133
|
- CHANGELOG.md file added
|
|
88
134
|
|
|
89
|
-
###
|
|
135
|
+
### Changed
|
|
90
136
|
|
|
91
137
|
- Char to digit conversion now uses precalculated tables instead of dynamic calculation for speed
|
|
92
138
|
|
data/README.md
CHANGED
|
@@ -1,104 +1,69 @@
|
|
|
1
|
-
# SecId
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[SEDOL](
|
|
14
|
-
[FIGI](
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
[
|
|
1
|
+
# SecId [](https://rubygems.org/gems/sec_id) [](https://app.codecov.io/gh/svyatov/sec_id) [](https://github.com/svyatov/sec_id/actions?query=workflow%3ACI)
|
|
2
|
+
|
|
3
|
+
> Validate securities identification numbers with ease!
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Supported Ruby Versions](#supported-ruby-versions)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Supported Standards and Usage](#supported-standards-and-usage)
|
|
10
|
+
- [ISIN](#isin) - International Securities Identification Number
|
|
11
|
+
- [CUSIP](#cusip) - Committee on Uniform Securities Identification Procedures
|
|
12
|
+
- [CEI](#cei) - CUSIP Entity Identifier
|
|
13
|
+
- [SEDOL](#sedol) - Stock Exchange Daily Official List
|
|
14
|
+
- [FIGI](#figi) - Financial Instrument Global Identifier
|
|
15
|
+
- [LEI](#lei) - Legal Entity Identifier
|
|
16
|
+
- [IBAN](#iban) - International Bank Account Number
|
|
17
|
+
- [CIK](#cik) - Central Index Key
|
|
18
|
+
- [OCC](#occ) - Options Clearing Corporation Symbol
|
|
19
|
+
- [WKN](#wkn) - Wertpapierkennnummer
|
|
20
|
+
- [Valoren](#valoren) - Swiss Security Number
|
|
21
|
+
- [CFI](#cfi) - Classification of Financial Instruments
|
|
22
|
+
- [FISN](#fisn) - Financial Instrument Short Name
|
|
23
|
+
- [Development](#development)
|
|
24
|
+
- [Contributing](#contributing)
|
|
25
|
+
- [Changelog](#changelog)
|
|
26
|
+
- [Versioning](#versioning)
|
|
27
|
+
- [License](#license)
|
|
28
|
+
|
|
29
|
+
## Supported Ruby Versions
|
|
30
|
+
|
|
31
|
+
Ruby 3.1+ is required.
|
|
20
32
|
|
|
21
33
|
## Installation
|
|
22
34
|
|
|
23
35
|
Add this line to your application's Gemfile:
|
|
24
36
|
|
|
25
37
|
```ruby
|
|
26
|
-
gem 'sec_id', '~> 4.
|
|
38
|
+
gem 'sec_id', '~> 4.4'
|
|
27
39
|
```
|
|
28
40
|
|
|
29
41
|
And then execute:
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
$ gem install sec_id
|
|
36
|
-
|
|
37
|
-
## Usage
|
|
38
|
-
|
|
39
|
-
### Base API
|
|
40
|
-
|
|
41
|
-
Base API has 4 main methods which can be used both on class level and on instance level:
|
|
42
|
-
|
|
43
|
-
* `valid?` - never raises any errors, always returns `true` or `false`,
|
|
44
|
-
numbers without the check-digit will return `false`
|
|
45
|
-
|
|
46
|
-
```ruby
|
|
47
|
-
# class level
|
|
48
|
-
SecId::ISIN.valid?('US5949181045') # => true
|
|
49
|
-
SecId::ISIN.valid?('US594918104') # => false
|
|
50
|
-
|
|
51
|
-
# instance level
|
|
52
|
-
isin = SecId::ISIN.new('US5949181045')
|
|
53
|
-
isin.valid? # => true
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
* `valid_format?` - never raises any errors, always returns `true` or `false`,
|
|
57
|
-
numbers without the check-digit but in valid format will return `true`
|
|
58
|
-
|
|
59
|
-
```ruby
|
|
60
|
-
# class level
|
|
61
|
-
SecId::ISIN.valid_format?('US5949181045') # => true
|
|
62
|
-
SecId::ISIN.valid_format?('US594918104') # => true
|
|
63
|
-
|
|
64
|
-
# instance level
|
|
65
|
-
isin = SecId::ISIN.new('US594918104')
|
|
66
|
-
isin.valid_format? # => true
|
|
67
|
-
```
|
|
43
|
+
```bash
|
|
44
|
+
bundle install
|
|
45
|
+
```
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
raises an error if number's format is invalid and thus check-digit is impossible to calculate
|
|
47
|
+
Or install it yourself:
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
49
|
+
```bash
|
|
50
|
+
gem install sec_id
|
|
51
|
+
```
|
|
75
52
|
|
|
76
|
-
|
|
77
|
-
isin = SecId::ISIN.new('US5949181045')
|
|
78
|
-
isin.restore! # => 'US5949181045'
|
|
79
|
-
```
|
|
53
|
+
## Supported Standards and Usage
|
|
80
54
|
|
|
81
|
-
|
|
82
|
-
but the former is used at class level for bravity,
|
|
83
|
-
and the latter is used at instance level for clarity;
|
|
84
|
-
it calculates and returns the check-digit if the number is valid
|
|
85
|
-
and raises an error otherwise.
|
|
55
|
+
All identifier classes provide `valid?` and `valid_format?` methods at both class and instance levels.
|
|
86
56
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
57
|
+
**Check-digit based identifiers** (ISIN, CUSIP, CEI, SEDOL, FIGI, LEI, IBAN) also provide:
|
|
58
|
+
- `restore!` - restores check-digit and returns the full number
|
|
59
|
+
- `check_digit` / `calculate_check_digit` - calculates and returns the check-digit
|
|
90
60
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
isin.calculate_check_digit # => 5
|
|
94
|
-
isin.check_digit # => nil
|
|
95
|
-
```
|
|
61
|
+
**Normalization based identifiers** (CIK, OCC, Valoren) provide instead:
|
|
62
|
+
- `normalize!` - pads/formats the identifier to its standard form
|
|
96
63
|
|
|
97
|
-
|
|
98
|
-
at instance level represents original check-digit of the number passed to `new`,
|
|
99
|
-
which in this example is missing and thus it's `nil`.
|
|
64
|
+
### ISIN
|
|
100
65
|
|
|
101
|
-
|
|
66
|
+
> [International Securities Identification Number](https://en.wikipedia.org/wiki/International_Securities_Identification_Number) - a 12-character alphanumeric code that uniquely identifies a security.
|
|
102
67
|
|
|
103
68
|
```ruby
|
|
104
69
|
# class level
|
|
@@ -118,16 +83,38 @@ isin.valid_format? # => true
|
|
|
118
83
|
isin.restore! # => 'US5949181045'
|
|
119
84
|
isin.calculate_check_digit # => 5
|
|
120
85
|
isin.to_cusip # => #<SecId::CUSIP>
|
|
86
|
+
isin.nsin_type # => :cusip
|
|
87
|
+
isin.to_nsin # => #<SecId::CUSIP>
|
|
88
|
+
|
|
89
|
+
# NSIN extraction for different countries
|
|
90
|
+
SecId::ISIN.new('GB00B02H2F76').nsin_type # => :sedol
|
|
91
|
+
SecId::ISIN.new('GB00B02H2F76').to_nsin # => #<SecId::SEDOL>
|
|
92
|
+
SecId::ISIN.new('DE0007164600').nsin_type # => :wkn
|
|
93
|
+
SecId::ISIN.new('DE0007164600').to_nsin # => #<SecId::WKN>
|
|
94
|
+
SecId::ISIN.new('CH0012221716').nsin_type # => :valoren
|
|
95
|
+
SecId::ISIN.new('CH0012221716').to_nsin # => #<SecId::Valoren>
|
|
96
|
+
SecId::ISIN.new('FR0000120271').nsin_type # => :generic
|
|
97
|
+
SecId::ISIN.new('FR0000120271').to_nsin # => '000012027' (raw NSIN string)
|
|
98
|
+
|
|
99
|
+
# Type-specific conversion methods with validation
|
|
100
|
+
SecId::ISIN.new('GB00B02H2F76').sedol? # => true
|
|
101
|
+
SecId::ISIN.new('GB00B02H2F76').to_sedol # => #<SecId::SEDOL>
|
|
102
|
+
SecId::ISIN.new('DE0007164600').wkn? # => true
|
|
103
|
+
SecId::ISIN.new('DE0007164600').to_wkn # => #<SecId::WKN>
|
|
104
|
+
SecId::ISIN.new('CH0012221716').valoren? # => true
|
|
105
|
+
SecId::ISIN.new('CH0012221716').to_valoren # => #<SecId::Valoren>
|
|
121
106
|
```
|
|
122
107
|
|
|
123
|
-
###
|
|
108
|
+
### CUSIP
|
|
109
|
+
|
|
110
|
+
> [Committee on Uniform Securities Identification Procedures](https://en.wikipedia.org/wiki/CUSIP) - a 9-character alphanumeric code that identifies North American securities.
|
|
124
111
|
|
|
125
112
|
```ruby
|
|
126
113
|
# class level
|
|
127
114
|
SecId::CUSIP.valid?('594918104') # => true
|
|
128
115
|
SecId::CUSIP.valid_format?('59491810') # => true
|
|
129
116
|
SecId::CUSIP.restore!('59491810') # => '594918104'
|
|
130
|
-
SecId::CUSIP.check_digit('59491810') # =>
|
|
117
|
+
SecId::CUSIP.check_digit('59491810') # => 4
|
|
131
118
|
|
|
132
119
|
# instance level
|
|
133
120
|
cusip = SecId::CUSIP.new('594918104')
|
|
@@ -143,7 +130,33 @@ cusip.to_isin('US') # => #<SecId::ISIN>
|
|
|
143
130
|
cusip.cins? # => false
|
|
144
131
|
```
|
|
145
132
|
|
|
146
|
-
###
|
|
133
|
+
### CEI
|
|
134
|
+
|
|
135
|
+
> [CUSIP Entity Identifier](https://www.cusip.com/identifiers.html) - a 10-character alphanumeric code that identifies legal entities in the syndicated loan market.
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
# class level
|
|
139
|
+
SecId::CEI.valid?('A0BCDEFGH1') # => true
|
|
140
|
+
SecId::CEI.valid_format?('A0BCDEFGH') # => true
|
|
141
|
+
SecId::CEI.restore!('A0BCDEFGH') # => 'A0BCDEFGH1'
|
|
142
|
+
SecId::CEI.check_digit('A0BCDEFGH') # => 1
|
|
143
|
+
|
|
144
|
+
# instance level
|
|
145
|
+
cei = SecId::CEI.new('A0BCDEFGH1')
|
|
146
|
+
cei.full_number # => 'A0BCDEFGH1'
|
|
147
|
+
cei.prefix # => 'A'
|
|
148
|
+
cei.numeric # => '0'
|
|
149
|
+
cei.entity_id # => 'BCDEFGH'
|
|
150
|
+
cei.check_digit # => 1
|
|
151
|
+
cei.valid? # => true
|
|
152
|
+
cei.valid_format? # => true
|
|
153
|
+
cei.restore! # => 'A0BCDEFGH1'
|
|
154
|
+
cei.calculate_check_digit # => 1
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### SEDOL
|
|
158
|
+
|
|
159
|
+
> [Stock Exchange Daily Official List](https://en.wikipedia.org/wiki/SEDOL) - a 7-character alphanumeric code used in the United Kingdom, Ireland, Crown Dependencies (Jersey, Guernsey, Isle of Man), and select British Overseas Territories.
|
|
147
160
|
|
|
148
161
|
```ruby
|
|
149
162
|
# class level
|
|
@@ -153,16 +166,20 @@ SecId::SEDOL.restore!('B0Z52W') # => 'B0Z52W5'
|
|
|
153
166
|
SecId::SEDOL.check_digit('B0Z52W') # => 5
|
|
154
167
|
|
|
155
168
|
# instance level
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
sedol = SecId::SEDOL.new('B0Z52W5')
|
|
170
|
+
sedol.full_number # => 'B0Z52W5'
|
|
171
|
+
sedol.check_digit # => 5
|
|
172
|
+
sedol.valid? # => true
|
|
173
|
+
sedol.valid_format? # => true
|
|
174
|
+
sedol.restore! # => 'B0Z52W5'
|
|
175
|
+
sedol.calculate_check_digit # => 5
|
|
176
|
+
sedol.to_isin # => #<SecId::ISIN> (GB ISIN by default)
|
|
177
|
+
sedol.to_isin('IE') # => #<SecId::ISIN> (IE ISIN)
|
|
163
178
|
```
|
|
164
179
|
|
|
165
|
-
###
|
|
180
|
+
### FIGI
|
|
181
|
+
|
|
182
|
+
> [Financial Instrument Global Identifier](https://en.wikipedia.org/wiki/Financial_Instrument_Global_Identifier) - a 12-character alphanumeric code that provides unique identification of financial instruments.
|
|
166
183
|
|
|
167
184
|
```ruby
|
|
168
185
|
# class level
|
|
@@ -183,7 +200,61 @@ figi.restore! # => 'BBG000DMBXR2'
|
|
|
183
200
|
figi.calculate_check_digit # => 2
|
|
184
201
|
```
|
|
185
202
|
|
|
186
|
-
###
|
|
203
|
+
### LEI
|
|
204
|
+
|
|
205
|
+
> [Legal Entity Identifier](https://en.wikipedia.org/wiki/Legal_Entity_Identifier) - a 20-character alphanumeric code that uniquely identifies legal entities participating in financial transactions.
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
# class level
|
|
209
|
+
SecId::LEI.valid?('5493006MHB84DD0ZWV18') # => true
|
|
210
|
+
SecId::LEI.valid_format?('5493006MHB84DD0ZWV') # => true
|
|
211
|
+
SecId::LEI.restore!('5493006MHB84DD0ZWV') # => '5493006MHB84DD0ZWV18'
|
|
212
|
+
SecId::LEI.check_digit('5493006MHB84DD0ZWV') # => 18
|
|
213
|
+
|
|
214
|
+
# instance level
|
|
215
|
+
lei = SecId::LEI.new('5493006MHB84DD0ZWV18')
|
|
216
|
+
lei.full_number # => '5493006MHB84DD0ZWV18'
|
|
217
|
+
lei.lou_id # => '5493'
|
|
218
|
+
lei.reserved # => '00'
|
|
219
|
+
lei.entity_id # => '6MHB84DD0ZWV'
|
|
220
|
+
lei.check_digit # => 18
|
|
221
|
+
lei.valid? # => true
|
|
222
|
+
lei.valid_format? # => true
|
|
223
|
+
lei.restore! # => '5493006MHB84DD0ZWV18'
|
|
224
|
+
lei.calculate_check_digit # => 18
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### IBAN
|
|
228
|
+
|
|
229
|
+
> [International Bank Account Number](https://en.wikipedia.org/wiki/International_Bank_Account_Number) - an internationally standardized system for identifying bank accounts across national borders (ISO 13616).
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
# class level
|
|
233
|
+
SecId::IBAN.valid?('DE89370400440532013000') # => true
|
|
234
|
+
SecId::IBAN.valid_format?('DE370400440532013000') # => true
|
|
235
|
+
SecId::IBAN.restore!('DE370400440532013000') # => 'DE89370400440532013000'
|
|
236
|
+
SecId::IBAN.check_digit('DE370400440532013000') # => 89
|
|
237
|
+
|
|
238
|
+
# instance level
|
|
239
|
+
iban = SecId::IBAN.new('DE89370400440532013000')
|
|
240
|
+
iban.full_number # => 'DE89370400440532013000'
|
|
241
|
+
iban.country_code # => 'DE'
|
|
242
|
+
iban.bban # => '370400440532013000'
|
|
243
|
+
iban.bank_code # => '37040044'
|
|
244
|
+
iban.account_number # => '0532013000'
|
|
245
|
+
iban.check_digit # => 89
|
|
246
|
+
iban.valid? # => true
|
|
247
|
+
iban.valid_format? # => true
|
|
248
|
+
iban.restore! # => 'DE89370400440532013000'
|
|
249
|
+
iban.calculate_check_digit # => 89
|
|
250
|
+
iban.known_country? # => true
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Full BBAN structural validation is supported for EU/EEA countries. Other countries have length-only validation.
|
|
254
|
+
|
|
255
|
+
### CIK
|
|
256
|
+
|
|
257
|
+
> [Central Index Key](https://en.wikipedia.org/wiki/Central_Index_Key) - a 10-digit number used by the SEC to identify corporations and individuals who have filed disclosures.
|
|
187
258
|
|
|
188
259
|
```ruby
|
|
189
260
|
# class level
|
|
@@ -202,7 +273,9 @@ cik.normalize! # => '0001094517'
|
|
|
202
273
|
cik.to_s # => '0001094517'
|
|
203
274
|
```
|
|
204
275
|
|
|
205
|
-
###
|
|
276
|
+
### OCC
|
|
277
|
+
|
|
278
|
+
> [Options Clearing Corporation Symbol](https://en.wikipedia.org/wiki/Option_symbol#The_OCC_Option_Symbol) - a 21-character code used to identify equity options contracts.
|
|
206
279
|
|
|
207
280
|
```ruby
|
|
208
281
|
# class level
|
|
@@ -239,18 +312,132 @@ occ.normalize! # => 'X 250620C00050000'
|
|
|
239
312
|
occ.full_symbol # => 'X 250620C00050000'
|
|
240
313
|
```
|
|
241
314
|
|
|
315
|
+
### WKN
|
|
316
|
+
|
|
317
|
+
> [Wertpapierkennnummer](https://en.wikipedia.org/wiki/Wertpapierkennnummer) - a 6-character alphanumeric code used to identify securities in Germany.
|
|
318
|
+
|
|
319
|
+
```ruby
|
|
320
|
+
# class level
|
|
321
|
+
SecId::WKN.valid?('514000') # => true
|
|
322
|
+
SecId::WKN.valid?('CBK100') # => true
|
|
323
|
+
SecId::WKN.valid_format?('514000') # => true
|
|
324
|
+
|
|
325
|
+
# instance level
|
|
326
|
+
wkn = SecId::WKN.new('514000')
|
|
327
|
+
wkn.full_number # => '514000'
|
|
328
|
+
wkn.identifier # => '514000'
|
|
329
|
+
wkn.valid? # => true
|
|
330
|
+
wkn.valid_format? # => true
|
|
331
|
+
wkn.to_s # => '514000'
|
|
332
|
+
wkn.to_isin # => #<SecId::ISIN> (DE ISIN)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
WKN excludes letters I and O to avoid confusion with digits 1 and 0.
|
|
336
|
+
|
|
337
|
+
### Valoren
|
|
338
|
+
|
|
339
|
+
> [Valoren](https://en.wikipedia.org/wiki/Valoren_number) - a numeric identifier for securities in Switzerland, Liechtenstein, and Belgium.
|
|
340
|
+
|
|
341
|
+
```ruby
|
|
342
|
+
# class level
|
|
343
|
+
SecId::Valoren.valid?('3886335') # => true
|
|
344
|
+
SecId::Valoren.valid?('24476758') # => true
|
|
345
|
+
SecId::Valoren.valid?('35514757') # => true
|
|
346
|
+
SecId::Valoren.valid?('97429325') # => true
|
|
347
|
+
SecId::Valoren.valid_format?('3886335') # => true
|
|
348
|
+
SecId::Valoren.normalize!('3886335') # => '003886335'
|
|
349
|
+
|
|
350
|
+
# instance level
|
|
351
|
+
valoren = SecId::Valoren.new('3886335')
|
|
352
|
+
valoren.full_number # => '3886335'
|
|
353
|
+
valoren.padding # => ''
|
|
354
|
+
valoren.identifier # => '3886335'
|
|
355
|
+
valoren.valid? # => true
|
|
356
|
+
valoren.valid_format? # => true
|
|
357
|
+
valoren.normalize! # => '003886335'
|
|
358
|
+
valoren.to_s # => '003886335'
|
|
359
|
+
valoren.to_isin # => #<SecId::ISIN> (CH ISIN by default)
|
|
360
|
+
valoren.to_isin('LI') # => #<SecId::ISIN> (LI ISIN)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### CFI
|
|
364
|
+
|
|
365
|
+
> [Classification of Financial Instruments](https://en.wikipedia.org/wiki/ISO_10962) - a 6-character alphabetic code that classifies financial instruments per ISO 10962.
|
|
366
|
+
|
|
367
|
+
```ruby
|
|
368
|
+
# class level
|
|
369
|
+
SecId::CFI.valid?('ESXXXX') # => true
|
|
370
|
+
SecId::CFI.valid?('ESVUFR') # => true
|
|
371
|
+
SecId::CFI.valid_format?('ESXXXX') # => true
|
|
372
|
+
|
|
373
|
+
# instance level
|
|
374
|
+
cfi = SecId::CFI.new('ESVUFR')
|
|
375
|
+
cfi.full_number # => 'ESVUFR'
|
|
376
|
+
cfi.identifier # => 'ESVUFR'
|
|
377
|
+
cfi.category_code # => 'E'
|
|
378
|
+
cfi.group_code # => 'S'
|
|
379
|
+
cfi.category # => :equity
|
|
380
|
+
cfi.group # => :common_shares
|
|
381
|
+
cfi.valid? # => true
|
|
382
|
+
cfi.valid_format? # => true
|
|
383
|
+
|
|
384
|
+
# Equity-specific predicates
|
|
385
|
+
cfi.equity? # => true
|
|
386
|
+
cfi.voting? # => true
|
|
387
|
+
cfi.restrictions? # => false
|
|
388
|
+
cfi.fully_paid? # => true
|
|
389
|
+
cfi.registered? # => true
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
CFI validates the category code (position 1) against 14 valid values and the group code (position 2) against valid values for that category. Attribute positions 3-6 accept any letter A-Z, with X meaning "not applicable".
|
|
393
|
+
|
|
394
|
+
### FISN
|
|
395
|
+
|
|
396
|
+
> [Financial Instrument Short Name](https://en.wikipedia.org/wiki/ISO_18774) - a human-readable short name for financial instruments per ISO 18774.
|
|
397
|
+
|
|
398
|
+
```ruby
|
|
399
|
+
# class level
|
|
400
|
+
SecId::FISN.valid?('APPLE INC/SH') # => true
|
|
401
|
+
SecId::FISN.valid?('apple inc/sh') # => true (normalized to uppercase)
|
|
402
|
+
SecId::FISN.valid_format?('APPLE INC/SH') # => true
|
|
403
|
+
|
|
404
|
+
# instance level
|
|
405
|
+
fisn = SecId::FISN.new('APPLE INC/SH')
|
|
406
|
+
fisn.full_number # => 'APPLE INC/SH'
|
|
407
|
+
fisn.identifier # => 'APPLE INC/SH'
|
|
408
|
+
fisn.issuer # => 'APPLE INC'
|
|
409
|
+
fisn.description # => 'SH'
|
|
410
|
+
fisn.valid? # => true
|
|
411
|
+
fisn.valid_format? # => true
|
|
412
|
+
fisn.to_s # => 'APPLE INC/SH'
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
FISN format: `Issuer Name/Abbreviated Instrument Description` with issuer (1-15 chars) and description (1-19 chars) separated by a forward slash. Character set: uppercase A-Z, digits 0-9, and space.
|
|
416
|
+
|
|
242
417
|
## Development
|
|
243
418
|
|
|
244
419
|
After checking out the repo, run `bin/setup` to install dependencies.
|
|
245
|
-
Then, run `rake
|
|
420
|
+
Then, run `bundle exec rake` to run the tests. You can also run `bin/console`
|
|
246
421
|
for an interactive prompt that will allow you to experiment.
|
|
247
422
|
|
|
248
423
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
249
424
|
|
|
250
425
|
## Contributing
|
|
251
426
|
|
|
252
|
-
|
|
253
|
-
|
|
427
|
+
1. Fork it
|
|
428
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
429
|
+
3. Make your changes and run tests (`bundle exec rake`)
|
|
430
|
+
4. Commit using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format (`git commit -m 'feat: add some feature'`)
|
|
431
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
432
|
+
6. Create a new Pull Request
|
|
433
|
+
|
|
434
|
+
## Changelog
|
|
435
|
+
|
|
436
|
+
See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes, following [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format.
|
|
437
|
+
|
|
438
|
+
## Versioning
|
|
439
|
+
|
|
440
|
+
This project follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html)
|
|
254
441
|
|
|
255
442
|
## License
|
|
256
443
|
|