Class: SecID::OCC
Overview
OCC identifiers have no check digit and validation includes both format and date parseability checks.
OCC Option Symbol - standardized option symbol format used by Option Clearing Corporation. Format: 6-char underlying (padded) + 6-char date (YYMMDD) + type (C/P) + 8-digit strike (in mills).
Constant Summary collapse
- FULL_NAME =
Human-readable name of the standard.
'OCC Option Symbol'- ID_LENGTH =
Valid length(s) of a normalized identifier.
(16..21)
- EXAMPLE =
A representative valid identifier.
'AAPL 210917C00150000'- VALID_CHARS_REGEX =
Pattern matching the identifier's permitted character set.
/\A[A-Z0-9 ]+\z/- SEPARATORS =
Separators stripped during normalization; spaces are structural here, so only hyphens.
/-/- ID_REGEX =
Regular expression for parsing OCC symbol components.
/\A (?<initial> (?=.{1,6})(?<underlying>\d?[A-Z]{1,5}\d?)(?<padding>[ ]*)) (?<date>\d{6}) (?<type>[CP]) (?<strike_mills>\d{8}) \z/x
Constants included from Generatable
Generatable::ALPHA, Generatable::ALPHANUMERIC, Generatable::DIGITS
Constants included from Validatable
Instance Attribute Summary collapse
-
#date_str ⇒ String?
readonly
The expiration date string in YYMMDD format.
-
#strike_mills ⇒ String?
readonly
The strike price in mills (thousandths of a dollar, represented as an 8-digit string).
-
#type ⇒ String?
readonly
The option type ('C' for call, 'P' for put).
-
#underlying ⇒ String?
readonly
The underlying security symbol (1-6 chars).
Attributes inherited from Base
Class Method Summary collapse
-
.build(underlying:, date:, type:, strike:) ⇒ OCC
Builds an OCC symbol from components.
-
.compose_symbol(underlying, date_str, type, strike_mills) ⇒ String
Composes an OCC symbol string from its components.
-
.generate(random: Random.new) ⇒ OCC
Generates a random OCC option symbol.
Instance Method Summary collapse
-
#date ⇒ Date?
(also: #date_obj)
The parsed date or nil if invalid.
-
#initialize(symbol) ⇒ OCC
constructor
A new instance of OCC.
-
#normalized ⇒ String
The normalized OCC symbol.
-
#strike ⇒ Float?
Strike price in dollars.
- #to_pretty_s ⇒ String?
- #to_s ⇒ String
- #valid? ⇒ Boolean
Methods inherited from Base
#==, #as_json, example, full_name, has_check_digit?, #hash, id_length, length_specificity, length_values, short_name, #to_h
Methods included from Validatable
#errors, #validate, #validate!
Methods included from Normalizable
Constructor Details
#initialize(symbol) ⇒ OCC
Returns a new instance of OCC.
118 119 120 121 122 123 124 125 |
# File 'lib/sec_id/occ.rb', line 118 def initialize(symbol) symbol_parts = parse(symbol) @identifier = symbol_parts[:initial] @underlying = symbol_parts[:underlying] @date_str = symbol_parts[:date] @type = symbol_parts[:type] @strike_mills = symbol_parts[:strike_mills] end |
Instance Attribute Details
#date_str ⇒ String? (readonly)
Returns the expiration date string in YYMMDD format.
46 47 48 |
# File 'lib/sec_id/occ.rb', line 46 def date_str @date_str end |
#strike_mills ⇒ String? (readonly)
Returns the strike price in mills (thousandths of a dollar, represented as an 8-digit string).
52 53 54 |
# File 'lib/sec_id/occ.rb', line 52 def strike_mills @strike_mills end |
#type ⇒ String? (readonly)
Returns the option type ('C' for call, 'P' for put).
49 50 51 |
# File 'lib/sec_id/occ.rb', line 49 def type @type end |
#underlying ⇒ String? (readonly)
Returns the underlying security symbol (1-6 chars).
43 44 45 |
# File 'lib/sec_id/occ.rb', line 43 def @underlying end |
Class Method Details
.build(underlying:, date:, type:, strike:) ⇒ OCC
Builds an OCC symbol from components.
79 80 81 82 83 84 |
# File 'lib/sec_id/occ.rb', line 79 def build(underlying:, date:, type:, strike:) date_obj = date.is_a?(Date) ? date : Date.parse(date) strike_mills = normalize_strike_mills(strike) new(compose_symbol(, date_obj.strftime('%y%m%d'), type, strike_mills)) end |
.compose_symbol(underlying, date_str, type, strike_mills) ⇒ String
Composes an OCC symbol string from its components.
93 94 95 96 97 98 |
# File 'lib/sec_id/occ.rb', line 93 def compose_symbol(, date_str, type, strike_mills) = .to_s.ljust(6, "\s") padded_strike = format('%08d', strike_mills.to_i) "#{}#{date_str}#{type}#{padded_strike}" end |
.generate(random: Random.new) ⇒ OCC
Generated symbols are valid in format only — they are not real, listed options.
Generates a random OCC option symbol.
60 61 62 63 64 65 66 67 68 |
# File 'lib/sec_id/occ.rb', line 60 def self.generate(random: Random.new) build( underlying: random_string(ALPHA, random.rand(1..5), random: random), # Year 2000-2068 so the 2-digit-year symbol round-trips: strptime maps %y 69-99 to 19xx. date: Date.new(2000 + random.rand(0..68), random.rand(1..12), random.rand(1..28)), type: %w[C P].sample(random: random), strike: random_string(DIGITS, 8, random: random) ) end |
Instance Method Details
#date ⇒ Date? Also known as: date_obj
Returns the parsed date or nil if invalid.
140 141 142 143 144 145 146 147 |
# File 'lib/sec_id/occ.rb', line 140 def date return @date if defined?(@date) return unless date_str @date = Date.strptime(date_str, '%y%m%d') rescue ArgumentError @date = nil end |
#normalized ⇒ String
Returns the normalized OCC symbol.
129 130 131 132 |
# File 'lib/sec_id/occ.rb', line 129 def normalized validate! self.class.compose_symbol(, date_str, type, strike_mills) end |
#strike ⇒ Float?
Returns strike price in dollars.
151 152 153 154 155 |
# File 'lib/sec_id/occ.rb', line 151 def strike return @strike if defined?(@strike) @strike = strike_mills&.then { |m| m.to_i / 1000.0 } end |
#to_pretty_s ⇒ String?
163 164 165 166 167 |
# File 'lib/sec_id/occ.rb', line 163 def to_pretty_s return nil unless valid? "#{} #{date_str} #{type} #{strike_mills}" end |
#to_s ⇒ String
158 159 160 |
# File 'lib/sec_id/occ.rb', line 158 def to_s full_id end |
#valid? ⇒ Boolean
135 136 137 |
# File 'lib/sec_id/occ.rb', line 135 def valid? valid_format? && !date.nil? # date must be parseable end |