sec_id 5.0.0 → 5.1.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 +10 -0
- data/README.md +54 -8
- data/lib/sec_id/base.rb +38 -0
- data/lib/sec_id/cei.rb +7 -0
- data/lib/sec_id/cfi.rb +3 -0
- data/lib/sec_id/concerns/normalizable.rb +18 -0
- data/lib/sec_id/cusip.rb +14 -0
- data/lib/sec_id/figi.rb +10 -0
- data/lib/sec_id/fisn.rb +5 -0
- data/lib/sec_id/iban.rb +15 -0
- data/lib/sec_id/isin.rb +14 -0
- data/lib/sec_id/lei.rb +10 -0
- data/lib/sec_id/occ.rb +10 -0
- data/lib/sec_id/sedol.rb +3 -0
- data/lib/sec_id/valoren.rb +7 -0
- data/lib/sec_id/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b0779f0d2735ded84be536bcc9690a4b106c729b03aab007a0458b6512020e8
|
|
4
|
+
data.tar.gz: 3b4d99c3534856e5e05ff68cec5355f3c7a2665e2854dad5415815e275a734b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ec036b3fbf2c3d7a89ec823fed2dea6c8cb92be1ede8792bae623c1474454141a3dcc3da27d14c5e3734b050dd95b25672552fc9f4c6983bc68d807a7493d392
|
|
7
|
+
data.tar.gz: 397e7c17dd46c8aad067262289307317e04cdba4fac65d890aa3e3ff1a1b9ecf175ab916d9600dab7a7a5d4629b54f7750fd40f11c79ed220d3bca339a210d0c
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,16 @@ and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [5.1.0] - 2026-02-19
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `#==`, `#eql?`, and `#hash` methods on all identifier types — two instances of the same type with the same normalized form are equal and usable as Hash keys / in Sets
|
|
16
|
+
- `#to_h` method on all identifier types for consistent hash serialization — returns `{ type:, full_id:, normalized:, valid:, components: }` with type-specific component hashes (e.g. ISIN: `country_code`, `nsin`, `check_digit`)
|
|
17
|
+
- `#to_pretty_s` and `.to_pretty_s` display formatting methods on all identifier types, returning a human-readable string or `nil` for invalid input — with type-specific formats for IBAN (4-char groups), LEI (4-char groups), ISIN (CC + NSIN + CD), CUSIP (cusip6 + issue + CD), FIGI (prefix+G + random + CD), OCC (space-separated components), and Valoren (thousands grouping)
|
|
18
|
+
- Lookup service integration guides and runnable examples for OpenFIGI, SEC EDGAR, GLEIF, and Eurex APIs (`docs/guides/`, `examples/`)
|
|
19
|
+
- GitHub community standards files: Code of Conduct, Contributing guide, Security policy, issue templates, and PR template
|
|
20
|
+
|
|
11
21
|
## [5.0.0] - 2026-02-17
|
|
12
22
|
|
|
13
23
|
### Added
|
data/README.md
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- [Valoren](#valoren) - Swiss Security Number
|
|
23
23
|
- [CFI](#cfi) - Classification of Financial Instruments
|
|
24
24
|
- [FISN](#fisn) - Financial Instrument Short Name
|
|
25
|
+
- [Lookup Service Integration](#lookup-service-integration)
|
|
25
26
|
- [Development](#development)
|
|
26
27
|
- [Contributing](#contributing)
|
|
27
28
|
- [Changelog](#changelog)
|
|
@@ -37,7 +38,7 @@ Ruby 3.2+ is required.
|
|
|
37
38
|
Add this line to your application's Gemfile:
|
|
38
39
|
|
|
39
40
|
```ruby
|
|
40
|
-
gem 'sec_id', '~> 5.
|
|
41
|
+
gem 'sec_id', '~> 5.1'
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
And then execute:
|
|
@@ -58,10 +59,38 @@ gem install sec_id
|
|
|
58
59
|
|
|
59
60
|
All identifier classes provide `valid?`, `errors`, `validate`, `validate!` methods at both class and instance levels.
|
|
60
61
|
|
|
61
|
-
**All identifiers** support normalization:
|
|
62
|
+
**All identifiers** support normalization and display formatting:
|
|
62
63
|
- `.normalize(id)` - strips separators, upcases, validates, and returns the canonical string
|
|
63
64
|
- `#normalized` / `#normalize` - returns the canonical string for a valid instance
|
|
64
65
|
- `#normalize!` - mutates `full_id` to canonical form, returns `self`
|
|
66
|
+
- `#to_pretty_s` / `.to_pretty_s(id)` - returns a human-readable formatted string, or `nil` for invalid input
|
|
67
|
+
|
|
68
|
+
**All identifiers** support hash serialization:
|
|
69
|
+
- `#to_h` - returns a hash with `:type`, `:full_id`, `:normalized`, `:valid`, and `:components` keys
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
SecID::ISIN.new('US5949181045').to_h
|
|
73
|
+
# => { type: :isin, full_id: 'US5949181045', normalized: 'US5949181045',
|
|
74
|
+
# valid: true, components: { country_code: 'US', nsin: '594918104', check_digit: 5 } }
|
|
75
|
+
|
|
76
|
+
SecID::ISIN.new('INVALID').to_h
|
|
77
|
+
# => { type: :isin, full_id: 'INVALID', normalized: nil,
|
|
78
|
+
# valid: false, components: { country_code: nil, nsin: nil, check_digit: nil } }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**All identifiers** support value equality — two instances of the same type with the same normalized form are equal:
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
a = SecID::ISIN.new('US5949181045')
|
|
85
|
+
b = SecID::ISIN.new('us 5949 1810 45')
|
|
86
|
+
|
|
87
|
+
a == b # => true
|
|
88
|
+
a.eql?(b) # => true
|
|
89
|
+
|
|
90
|
+
# Works as Hash keys and in Sets
|
|
91
|
+
{ a => 'MSFT' }[b] # => 'MSFT'
|
|
92
|
+
Set.new([a, b]).size # => 1
|
|
93
|
+
```
|
|
65
94
|
|
|
66
95
|
**Check-digit based identifiers** (ISIN, CUSIP, CEI, SEDOL, FIGI, LEI, IBAN) also provide:
|
|
67
96
|
- `restore` / `.restore` - returns the full identifier string with correct check-digit (no mutation)
|
|
@@ -192,6 +221,7 @@ isin.valid? # => true
|
|
|
192
221
|
isin.restore # => 'US5949181045'
|
|
193
222
|
isin.restore! # => #<SecID::ISIN> (mutates instance)
|
|
194
223
|
isin.calculate_check_digit # => 5
|
|
224
|
+
isin.to_pretty_s # => 'US 594918104 5'
|
|
195
225
|
isin.to_cusip # => #<SecID::CUSIP>
|
|
196
226
|
isin.nsin_type # => :cusip
|
|
197
227
|
isin.to_nsin # => #<SecID::CUSIP>
|
|
@@ -236,6 +266,7 @@ cusip.valid? # => true
|
|
|
236
266
|
cusip.restore # => '594918104'
|
|
237
267
|
cusip.restore! # => #<SecID::CUSIP> (mutates instance)
|
|
238
268
|
cusip.calculate_check_digit # => 4
|
|
269
|
+
cusip.to_pretty_s # => '594918 10 4'
|
|
239
270
|
cusip.to_isin('US') # => #<SecID::ISIN>
|
|
240
271
|
cusip.cins? # => false
|
|
241
272
|
```
|
|
@@ -308,6 +339,7 @@ figi.valid? # => true
|
|
|
308
339
|
figi.restore # => 'BBG000DMBXR2'
|
|
309
340
|
figi.restore! # => #<SecID::FIGI> (mutates instance)
|
|
310
341
|
figi.calculate_check_digit # => 2
|
|
342
|
+
figi.to_pretty_s # => 'BBG 000DMBXR 2'
|
|
311
343
|
```
|
|
312
344
|
|
|
313
345
|
### LEI
|
|
@@ -332,6 +364,7 @@ lei.valid? # => true
|
|
|
332
364
|
lei.restore # => '5493006MHB84DD0ZWV18'
|
|
333
365
|
lei.restore! # => #<SecID::LEI> (mutates instance)
|
|
334
366
|
lei.calculate_check_digit # => 18
|
|
367
|
+
lei.to_pretty_s # => '5493 006M HB84 DD0Z WV18'
|
|
335
368
|
```
|
|
336
369
|
|
|
337
370
|
### IBAN
|
|
@@ -358,6 +391,7 @@ iban.restore # => 'DE89370400440532013000'
|
|
|
358
391
|
iban.restore! # => #<SecID::IBAN> (mutates instance)
|
|
359
392
|
iban.calculate_check_digit # => 89
|
|
360
393
|
iban.known_country? # => true
|
|
394
|
+
iban.to_pretty_s # => 'DE89 3704 0044 0532 0130 00'
|
|
361
395
|
```
|
|
362
396
|
|
|
363
397
|
Full BBAN structural validation is supported for EU/EEA countries. Other countries have length-only validation.
|
|
@@ -412,6 +446,7 @@ occ.full_id # => 'X 250620C00050000'
|
|
|
412
446
|
occ.valid? # => true
|
|
413
447
|
occ.normalize! # => #<SecID::OCC> (mutates full_id, returns self)
|
|
414
448
|
occ.full_id # => 'X 250620C00050000'
|
|
449
|
+
occ.to_pretty_s # => 'X 250620 C 00050000'
|
|
415
450
|
```
|
|
416
451
|
|
|
417
452
|
### WKN
|
|
@@ -454,6 +489,7 @@ valoren.identifier # => '3886335'
|
|
|
454
489
|
valoren.valid? # => true
|
|
455
490
|
valoren.normalized # => '003886335'
|
|
456
491
|
valoren.normalize! # => #<SecID::Valoren> (mutates full_id, returns self)
|
|
492
|
+
valoren.to_pretty_s # => '3 886 335'
|
|
457
493
|
valoren.to_isin # => #<SecID::ISIN> (CH ISIN by default)
|
|
458
494
|
valoren.to_isin('LI') # => #<SecID::ISIN> (LI ISIN)
|
|
459
495
|
```
|
|
@@ -506,6 +542,19 @@ fisn.to_s # => 'APPLE INC/SH'
|
|
|
506
542
|
|
|
507
543
|
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.
|
|
508
544
|
|
|
545
|
+
## Lookup Service Integration
|
|
546
|
+
|
|
547
|
+
SecID validates identifiers but does not include HTTP clients. The [`docs/guides/`](docs/guides/) directory provides integration patterns for external lookup services using only stdlib (`net/http`, `json`):
|
|
548
|
+
|
|
549
|
+
| Guide | Service | Identifier |
|
|
550
|
+
|-------|---------|------------|
|
|
551
|
+
| [OpenFIGI](docs/guides/openfigi.md) | [OpenFIGI API](https://www.openfigi.com/api) | FIGI |
|
|
552
|
+
| [SEC EDGAR](docs/guides/sec-edgar.md) | [SEC EDGAR](https://www.sec.gov/edgar/sec-api-documentation) | CIK |
|
|
553
|
+
| [GLEIF](docs/guides/gleif.md) | [GLEIF API](https://www.gleif.org/en/lei-data/gleif-api) | LEI |
|
|
554
|
+
| [Eurex](docs/guides/eurex.md) | [Eurex Reference Data](https://www.eurex.com/ex-en/data/free-reference-data-api) | ISIN |
|
|
555
|
+
|
|
556
|
+
Each guide includes a complete adapter class and a [runnable example](examples/).
|
|
557
|
+
|
|
509
558
|
## Development
|
|
510
559
|
|
|
511
560
|
After checking out the repo, run `bin/setup` to install dependencies.
|
|
@@ -516,12 +565,9 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
|
516
565
|
|
|
517
566
|
## Contributing
|
|
518
567
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
4. Commit using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format (`git commit -m 'feat: add some feature'`)
|
|
523
|
-
5. Push to the branch (`git push origin my-new-feature`)
|
|
524
|
-
6. Create a new Pull Request
|
|
568
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/svyatov/sec_id). See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code style, and PR guidelines.
|
|
569
|
+
|
|
570
|
+
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
|
|
525
571
|
|
|
526
572
|
## Changelog
|
|
527
573
|
|
data/lib/sec_id/base.rb
CHANGED
|
@@ -63,8 +63,46 @@ module SecID
|
|
|
63
63
|
raise NotImplementedError
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
# @param other [Object]
|
|
67
|
+
# @return [Boolean]
|
|
68
|
+
def ==(other)
|
|
69
|
+
other.class == self.class && comparison_id == other.comparison_id
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
alias eql? ==
|
|
73
|
+
|
|
74
|
+
# @return [Integer]
|
|
75
|
+
def hash
|
|
76
|
+
[self.class, comparison_id].hash
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns a hash representation of this identifier for serialization.
|
|
80
|
+
#
|
|
81
|
+
# @return [Hash] hash with :type, :full_id, :normalized, :valid, and :components keys
|
|
82
|
+
def to_h
|
|
83
|
+
{
|
|
84
|
+
type: self.class.short_name.downcase.to_sym,
|
|
85
|
+
full_id: full_id,
|
|
86
|
+
normalized: valid? ? normalized : nil,
|
|
87
|
+
valid: valid?,
|
|
88
|
+
components: components
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
protected
|
|
93
|
+
|
|
94
|
+
# @return [String]
|
|
95
|
+
def comparison_id
|
|
96
|
+
valid? ? normalized : full_id
|
|
97
|
+
end
|
|
98
|
+
|
|
66
99
|
private
|
|
67
100
|
|
|
101
|
+
# @return [Hash]
|
|
102
|
+
def components
|
|
103
|
+
{}
|
|
104
|
+
end
|
|
105
|
+
|
|
68
106
|
# @param sec_id_number [String, #to_s] the identifier to parse
|
|
69
107
|
# @return [MatchData, Hash] the regex match data or empty hash if no match
|
|
70
108
|
def parse(sec_id_number)
|
data/lib/sec_id/cei.rb
CHANGED
|
@@ -46,6 +46,13 @@ module SecID
|
|
|
46
46
|
@check_digit = cei_parts[:check_digit]&.to_i
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# @return [Hash]
|
|
52
|
+
def components = { prefix:, numeric:, entity_id:, check_digit: }
|
|
53
|
+
|
|
54
|
+
public
|
|
55
|
+
|
|
49
56
|
# @return [Integer] the calculated check digit (0-9)
|
|
50
57
|
# @raise [InvalidFormatError] if the CEI format is invalid
|
|
51
58
|
def calculate_check_digit
|
data/lib/sec_id/cfi.rb
CHANGED
|
@@ -23,6 +23,15 @@ module SecID
|
|
|
23
23
|
cleaned = id.to_s.strip.gsub(self::SEPARATORS, '')
|
|
24
24
|
new(cleaned.upcase).normalized
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
# Returns a human-readable formatted string, or nil if invalid.
|
|
28
|
+
#
|
|
29
|
+
# @param id [String, #to_s] the identifier to format
|
|
30
|
+
# @return [String, nil]
|
|
31
|
+
def to_pretty_s(id)
|
|
32
|
+
cleaned = id.to_s.strip.gsub(self::SEPARATORS, '')
|
|
33
|
+
new(cleaned.upcase).to_pretty_s
|
|
34
|
+
end
|
|
26
35
|
end
|
|
27
36
|
|
|
28
37
|
# Returns the canonical normalized form of this identifier.
|
|
@@ -48,6 +57,15 @@ module SecID
|
|
|
48
57
|
self
|
|
49
58
|
end
|
|
50
59
|
|
|
60
|
+
# Returns a human-readable formatted string, or nil if invalid.
|
|
61
|
+
#
|
|
62
|
+
# @return [String, nil]
|
|
63
|
+
def to_pretty_s
|
|
64
|
+
return nil unless valid?
|
|
65
|
+
|
|
66
|
+
to_s
|
|
67
|
+
end
|
|
68
|
+
|
|
51
69
|
# @return [String]
|
|
52
70
|
def to_s
|
|
53
71
|
identifier.to_s
|
data/lib/sec_id/cusip.rb
CHANGED
|
@@ -45,6 +45,13 @@ module SecID
|
|
|
45
45
|
@check_digit = cusip_parts[:check_digit]&.to_i
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
# @return [String, nil]
|
|
49
|
+
def to_pretty_s
|
|
50
|
+
return nil unless valid?
|
|
51
|
+
|
|
52
|
+
"#{cusip6} #{issue} #{check_digit}"
|
|
53
|
+
end
|
|
54
|
+
|
|
48
55
|
# @return [Integer] the calculated check digit (0-9)
|
|
49
56
|
# @raise [InvalidFormatError] if the CUSIP format is invalid
|
|
50
57
|
def calculate_check_digit
|
|
@@ -63,6 +70,13 @@ module SecID
|
|
|
63
70
|
ISIN.new(country_code + restore).restore!
|
|
64
71
|
end
|
|
65
72
|
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# @return [Hash]
|
|
76
|
+
def components = { cusip6:, issue:, check_digit: }
|
|
77
|
+
|
|
78
|
+
public
|
|
79
|
+
|
|
66
80
|
# @return [Boolean] true if first character is a letter (CINS identifier)
|
|
67
81
|
def cins?
|
|
68
82
|
cusip6[0] < '0' || cusip6[0] > '9'
|
data/lib/sec_id/figi.rb
CHANGED
|
@@ -50,6 +50,13 @@ module SecID
|
|
|
50
50
|
@check_digit = figi_parts[:check_digit]&.to_i
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# @return [String, nil]
|
|
54
|
+
def to_pretty_s
|
|
55
|
+
return nil unless valid?
|
|
56
|
+
|
|
57
|
+
"#{prefix}G #{random_part} #{check_digit}"
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
# @return [Integer] the calculated check digit (0-9)
|
|
54
61
|
# @raise [InvalidFormatError] if the FIGI format is invalid
|
|
55
62
|
def calculate_check_digit
|
|
@@ -59,6 +66,9 @@ module SecID
|
|
|
59
66
|
|
|
60
67
|
private
|
|
61
68
|
|
|
69
|
+
# @return [Hash]
|
|
70
|
+
def components = { prefix:, random_part:, check_digit: }
|
|
71
|
+
|
|
62
72
|
# @return [Boolean]
|
|
63
73
|
def valid_format?
|
|
64
74
|
!identifier.nil? && !RESTRICTED_PREFIXES.include?(prefix)
|
data/lib/sec_id/fisn.rb
CHANGED
data/lib/sec_id/iban.rb
CHANGED
|
@@ -106,8 +106,23 @@ module SecID
|
|
|
106
106
|
"#{country_code}#{check_digit.to_s.rjust(2, '0')}#{bban}"
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
+
# @return [String, nil]
|
|
110
|
+
def to_pretty_s
|
|
111
|
+
to_s.scan(/.{1,4}/).join(' ') if valid?
|
|
112
|
+
end
|
|
113
|
+
|
|
109
114
|
private
|
|
110
115
|
|
|
116
|
+
# @return [Hash]
|
|
117
|
+
def components
|
|
118
|
+
hash = { country_code:, bban:, check_digit: }
|
|
119
|
+
hash[:bank_code] = bank_code if bank_code
|
|
120
|
+
hash[:branch_code] = branch_code if branch_code
|
|
121
|
+
hash[:account_number] = account_number if account_number
|
|
122
|
+
hash[:national_check] = national_check if national_check
|
|
123
|
+
hash
|
|
124
|
+
end
|
|
125
|
+
|
|
111
126
|
# @return [Integer]
|
|
112
127
|
def check_digit_width
|
|
113
128
|
2
|
data/lib/sec_id/isin.rb
CHANGED
|
@@ -76,6 +76,13 @@ module SecID
|
|
|
76
76
|
@check_digit = isin_parts[:check_digit]&.to_i
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
# @return [String, nil]
|
|
80
|
+
def to_pretty_s
|
|
81
|
+
return nil unless valid?
|
|
82
|
+
|
|
83
|
+
"#{country_code} #{nsin} #{check_digit}"
|
|
84
|
+
end
|
|
85
|
+
|
|
79
86
|
# @return [Integer] the calculated check digit (0-9)
|
|
80
87
|
# @raise [InvalidFormatError] if the ISIN format is invalid
|
|
81
88
|
def calculate_check_digit
|
|
@@ -135,6 +142,13 @@ module SecID
|
|
|
135
142
|
Valoren.new(nsin)
|
|
136
143
|
end
|
|
137
144
|
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
# @return [Hash]
|
|
148
|
+
def components = { country_code:, nsin:, check_digit: }
|
|
149
|
+
|
|
150
|
+
public
|
|
151
|
+
|
|
138
152
|
# Returns the type of NSIN embedded in this ISIN.
|
|
139
153
|
#
|
|
140
154
|
# @return [Symbol] :cusip, :sedol, :wkn, :valoren, or :generic
|
data/lib/sec_id/lei.rb
CHANGED
|
@@ -50,6 +50,13 @@ module SecID
|
|
|
50
50
|
@check_digit = lei_parts[:check_digit]&.to_i
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# @return [String, nil]
|
|
54
|
+
def to_pretty_s
|
|
55
|
+
return nil unless valid?
|
|
56
|
+
|
|
57
|
+
to_s.scan(/.{1,4}/).join(' ')
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
# @return [Integer] the calculated 2-digit check digit (1-98)
|
|
54
61
|
# @raise [InvalidFormatError] if the LEI format is invalid
|
|
55
62
|
def calculate_check_digit
|
|
@@ -59,6 +66,9 @@ module SecID
|
|
|
59
66
|
|
|
60
67
|
private
|
|
61
68
|
|
|
69
|
+
# @return [Hash]
|
|
70
|
+
def components = { lou_id:, reserved:, entity_id:, check_digit: }
|
|
71
|
+
|
|
62
72
|
# @return [Integer]
|
|
63
73
|
def check_digit_width
|
|
64
74
|
2
|
data/lib/sec_id/occ.rb
CHANGED
|
@@ -138,8 +138,18 @@ module SecID
|
|
|
138
138
|
full_id
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
+
# @return [String, nil]
|
|
142
|
+
def to_pretty_s
|
|
143
|
+
return nil unless valid?
|
|
144
|
+
|
|
145
|
+
"#{underlying} #{date_str} #{type} #{strike_mills}"
|
|
146
|
+
end
|
|
147
|
+
|
|
141
148
|
private
|
|
142
149
|
|
|
150
|
+
# @return [Hash]
|
|
151
|
+
def components = { underlying:, date_str:, type:, strike_mills: }
|
|
152
|
+
|
|
143
153
|
# @return [Array<Symbol>]
|
|
144
154
|
def error_codes
|
|
145
155
|
return detect_errors unless valid_format?
|
data/lib/sec_id/sedol.rb
CHANGED
data/lib/sec_id/valoren.rb
CHANGED
|
@@ -40,6 +40,13 @@ module SecID
|
|
|
40
40
|
@identifier = valoren_parts[:identifier]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
# @return [String, nil]
|
|
44
|
+
def to_pretty_s
|
|
45
|
+
return nil unless valid?
|
|
46
|
+
|
|
47
|
+
identifier.reverse.scan(/.{1,3}/).join(' ').reverse
|
|
48
|
+
end
|
|
49
|
+
|
|
43
50
|
# @param country_code [String] the ISO 3166-1 alpha-2 country code (default: 'CH')
|
|
44
51
|
# @return [ISIN] a new ISIN instance with calculated check digit
|
|
45
52
|
# @raise [InvalidFormatError] if the country code is not CH or LI
|
data/lib/sec_id/version.rb
CHANGED