option_lab 0.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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +139 -0
  4. data/.yard/hooks/before_generate.rb +7 -0
  5. data/.yardopts +11 -0
  6. data/Gemfile +26 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +180 -0
  9. data/Rakefile +44 -0
  10. data/docs/OptionLab/BinomialTree.html +1271 -0
  11. data/docs/OptionLab/BjerksundStensland.html +2022 -0
  12. data/docs/OptionLab/BlackScholes.html +2388 -0
  13. data/docs/OptionLab/Engine.html +1716 -0
  14. data/docs/OptionLab/Models/AmericanModelInputs.html +937 -0
  15. data/docs/OptionLab/Models/ArrayInputs.html +463 -0
  16. data/docs/OptionLab/Models/BaseModel.html +223 -0
  17. data/docs/OptionLab/Models/BinomialModelInputs.html +1161 -0
  18. data/docs/OptionLab/Models/BlackScholesInfo.html +967 -0
  19. data/docs/OptionLab/Models/BlackScholesModelInputs.html +851 -0
  20. data/docs/OptionLab/Models/ClosedPosition.html +445 -0
  21. data/docs/OptionLab/Models/EngineData.html +2523 -0
  22. data/docs/OptionLab/Models/EngineDataResults.html +435 -0
  23. data/docs/OptionLab/Models/Inputs.html +2241 -0
  24. data/docs/OptionLab/Models/LaplaceInputs.html +777 -0
  25. data/docs/OptionLab/Models/Option.html +736 -0
  26. data/docs/OptionLab/Models/Outputs.html +1753 -0
  27. data/docs/OptionLab/Models/PoPOutputs.html +645 -0
  28. data/docs/OptionLab/Models/PricingResult.html +848 -0
  29. data/docs/OptionLab/Models/Stock.html +583 -0
  30. data/docs/OptionLab/Models/TreeVisualization.html +688 -0
  31. data/docs/OptionLab/Models.html +251 -0
  32. data/docs/OptionLab/Plotting.html +548 -0
  33. data/docs/OptionLab/Support.html +2884 -0
  34. data/docs/OptionLab/Utils.html +619 -0
  35. data/docs/OptionLab.html +133 -0
  36. data/docs/_index.html +376 -0
  37. data/docs/class_list.html +54 -0
  38. data/docs/css/common.css +1 -0
  39. data/docs/css/full_list.css +58 -0
  40. data/docs/css/style.css +503 -0
  41. data/docs/file.LICENSE.html +70 -0
  42. data/docs/file.README.html +263 -0
  43. data/docs/file_list.html +64 -0
  44. data/docs/frames.html +22 -0
  45. data/docs/index.html +263 -0
  46. data/docs/js/app.js +344 -0
  47. data/docs/js/full_list.js +242 -0
  48. data/docs/js/jquery.js +4 -0
  49. data/docs/method_list.html +1974 -0
  50. data/docs/top-level-namespace.html +110 -0
  51. data/examples/american_options.rb +163 -0
  52. data/examples/covered_call.rb +76 -0
  53. data/lib/option_lab/binomial_tree.rb +238 -0
  54. data/lib/option_lab/bjerksund_stensland.rb +276 -0
  55. data/lib/option_lab/black_scholes.rb +323 -0
  56. data/lib/option_lab/engine.rb +492 -0
  57. data/lib/option_lab/models.rb +768 -0
  58. data/lib/option_lab/plotting.rb +182 -0
  59. data/lib/option_lab/support.rb +471 -0
  60. data/lib/option_lab/utils.rb +107 -0
  61. data/lib/option_lab/version.rb +5 -0
  62. data/lib/option_lab.rb +134 -0
  63. data/option_lab.gemspec +43 -0
  64. metadata +207 -0
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'holidays'
5
+ require 'numo/narray'
6
+
7
+ module OptionLab
8
+ module Utils
9
+ # Calendar cache to improve performance
10
+ @holiday_cache = {}
11
+
12
+ class << self
13
+ # Get number of non-business days between dates
14
+ # @param start_date [Date] Start date
15
+ # @param end_date [Date] End date
16
+ # @param country [String] Country code
17
+ # @return [Integer] Number of non-business days
18
+ def get_nonbusiness_days(start_date, end_date, country = "US")
19
+ if end_date <= start_date
20
+ raise ArgumentError, "End date must be after start date!"
21
+ end
22
+
23
+ # Create cache key
24
+ cache_key = "#{country}-#{start_date}-#{end_date}"
25
+
26
+ # Return cached result if available
27
+ return @holiday_cache[cache_key] if @holiday_cache.key?(cache_key)
28
+
29
+ # Calculate number of days
30
+ n_days = (end_date - start_date).to_i
31
+
32
+ # Get holidays for the country (default to :us if there's an issue)
33
+ begin
34
+ holidays = Holidays.between(start_date, end_date, country.to_sym)
35
+ rescue Holidays::InvalidRegion
36
+ holidays = Holidays.between(start_date, end_date, :us)
37
+ end
38
+ holiday_dates = holidays.map { |h| h[:date].strftime('%Y-%m-%d') }
39
+
40
+ # Count non-business days
41
+ nonbusiness_days = 0
42
+
43
+ n_days.times do |i|
44
+ current_date = start_date + i
45
+
46
+ # Check if weekend or holiday
47
+ if current_date.saturday? || current_date.sunday? ||
48
+ holiday_dates.include?(current_date.strftime('%Y-%m-%d'))
49
+ nonbusiness_days += 1
50
+ end
51
+ end
52
+
53
+ # Cache the result
54
+ @holiday_cache[cache_key] = nonbusiness_days
55
+
56
+ nonbusiness_days
57
+ end
58
+
59
+ # Get profit/loss data
60
+ # @param outputs [Models::Outputs] Strategy outputs
61
+ # @param leg [Integer, nil] Strategy leg index
62
+ # @return [Array<Numo::DFloat, Numo::DFloat>] Stock prices and profits/losses
63
+ def get_pl(outputs, leg = nil)
64
+ if outputs.data.profit.size > 0 && leg && leg < outputs.data.profit.shape[0]
65
+ [outputs.data.stock_price_array, outputs.data.profit[leg, true]]
66
+ else
67
+ [outputs.data.stock_price_array, outputs.data.strategy_profit]
68
+ end
69
+ end
70
+
71
+ # Save profit/loss data to CSV
72
+ # @param outputs [Models::Outputs] Strategy outputs
73
+ # @param filename [String, IO] CSV filename or IO object
74
+ # @param leg [Integer, nil] Strategy leg index
75
+ # @return [void]
76
+ def pl_to_csv(outputs, filename = "pl.csv", leg = nil)
77
+ stock_prices, profits = get_pl(outputs, leg)
78
+
79
+ # Create matrix with stock prices and profits
80
+ data = Numo::DFloat.zeros(stock_prices.size, 2)
81
+ data[true, 0] = stock_prices
82
+ data[true, 1] = profits
83
+
84
+ # Handle filename as string or IO object
85
+ if filename.is_a?(String)
86
+ # Save to CSV file
87
+ File.open(filename, 'w') do |file|
88
+ file.puts "StockPrice,Profit/Loss"
89
+
90
+ data.shape[0].times do |i|
91
+ file.puts "#{data[i, 0]},#{data[i, 1]}"
92
+ end
93
+ end
94
+ elsif filename.respond_to?(:puts)
95
+ # Write to IO object
96
+ filename.puts "StockPrice,Profit/Loss"
97
+
98
+ data.shape[0].times do |i|
99
+ filename.puts "#{data[i, 0]},#{data[i, 1]}"
100
+ end
101
+ else
102
+ raise ArgumentError, "Filename must be a String or an IO object"
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OptionLab
4
+ VERSION = "0.1.0"
5
+ end
data/lib/option_lab.rb ADDED
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'option_lab/version'
4
+ require_relative 'option_lab/models'
5
+ require_relative 'option_lab/black_scholes'
6
+ require_relative 'option_lab/binomial_tree'
7
+ require_relative 'option_lab/bjerksund_stensland'
8
+ require_relative 'option_lab/support'
9
+ require_relative 'option_lab/engine'
10
+ require_relative 'option_lab/utils'
11
+ require_relative 'option_lab/plotting'
12
+
13
+ # Main module for OptionLab
14
+ module OptionLab
15
+
16
+ class Error < StandardError; end
17
+
18
+ # Public API methods
19
+ class << self
20
+
21
+ # Run a strategy calculation
22
+ # @param inputs [Hash, Models::Inputs] Input data for the strategy calculation
23
+ # @return [Models::Outputs] Output data from the strategy calculation
24
+ def run_strategy(inputs)
25
+ Engine.run_strategy(inputs)
26
+ end
27
+
28
+ # Plot profit/loss diagram
29
+ # @param outputs [Models::Outputs] Output data from a strategy calculation
30
+ # @return [void]
31
+ def plot_pl(outputs)
32
+ Plotting.plot_pl(outputs)
33
+ end
34
+
35
+ # Create price array
36
+ # @param inputs_data [Hash, Models::BlackScholesModelInputs, Models::LaplaceInputs]
37
+ # @param n [Integer] Number of prices to generate
38
+ # @param seed [Integer, nil] Random seed
39
+ # @return [Numo::DFloat] Array of prices
40
+ def create_price_array(inputs_data, n: 100_000, seed: nil)
41
+ Support.create_price_array(inputs_data, n: n, seed: seed)
42
+ end
43
+
44
+ # Get profit/loss data
45
+ # @param outputs [Models::Outputs] Output data from a strategy calculation
46
+ # @param leg [Integer, nil] Index of a strategy leg
47
+ # @return [Array<Numo::DFloat, Numo::DFloat>] Array of stock prices and profits/losses
48
+ def get_pl(outputs, leg = nil)
49
+ Utils.get_pl(outputs, leg)
50
+ end
51
+
52
+ # Save profit/loss data to CSV
53
+ # @param outputs [Models::Outputs] Output data from a strategy calculation
54
+ # @param filename [String] Name of the CSV file
55
+ # @param leg [Integer, nil] Index of a strategy leg
56
+ # @return [void]
57
+ def pl_to_csv(outputs, filename = 'pl.csv', leg = nil)
58
+ Utils.pl_to_csv(outputs, filename, leg)
59
+ end
60
+
61
+ # Price an option using the Cox-Ross-Rubinstein binomial tree model
62
+ # @param option_type [String] 'call' or 'put'
63
+ # @param s0 [Float] Spot price
64
+ # @param x [Float] Strike price
65
+ # @param r [Float] Risk-free interest rate
66
+ # @param volatility [Float] Volatility
67
+ # @param years_to_maturity [Float] Time to maturity in years
68
+ # @param n_steps [Integer] Number of time steps
69
+ # @param is_american [Boolean] True for American options, false for European
70
+ # @param dividend_yield [Float] Continuous dividend yield
71
+ # @return [Float] Option price
72
+ def price_binomial(option_type, s0, x, r, volatility, years_to_maturity, n_steps = 100, is_american = true, dividend_yield = 0.0)
73
+ BinomialTree.price_option(option_type, s0, x, r, volatility, years_to_maturity, n_steps, is_american, dividend_yield)
74
+ end
75
+
76
+ # Get binomial tree data for visualization and analysis
77
+ # @param option_type [String] 'call' or 'put'
78
+ # @param s0 [Float] Spot price
79
+ # @param x [Float] Strike price
80
+ # @param r [Float] Risk-free interest rate
81
+ # @param volatility [Float] Volatility
82
+ # @param years_to_maturity [Float] Time to maturity in years
83
+ # @param n_steps [Integer] Number of time steps
84
+ # @param is_american [Boolean] True for American options, false for European
85
+ # @param dividend_yield [Float] Continuous dividend yield
86
+ # @return [Hash] Tree structure with stock prices and option values
87
+ def get_binomial_tree(option_type, s0, x, r, volatility, years_to_maturity, n_steps = 15, is_american = true, dividend_yield = 0.0)
88
+ BinomialTree.get_tree(option_type, s0, x, r, volatility, years_to_maturity, n_steps, is_american, dividend_yield)
89
+ end
90
+
91
+ # Calculate option Greeks using the CRR binomial tree model
92
+ # @param option_type [String] 'call' or 'put'
93
+ # @param s0 [Float] Spot price
94
+ # @param x [Float] Strike price
95
+ # @param r [Float] Risk-free interest rate
96
+ # @param volatility [Float] Volatility
97
+ # @param years_to_maturity [Float] Time to maturity in years
98
+ # @param n_steps [Integer] Number of time steps
99
+ # @param is_american [Boolean] True for American options, false for European
100
+ # @param dividend_yield [Float] Continuous dividend yield
101
+ # @return [Hash] Option Greeks (delta, gamma, theta, vega, rho)
102
+ def get_binomial_greeks(option_type, s0, x, r, volatility, years_to_maturity, n_steps = 100, is_american = true, dividend_yield = 0.0)
103
+ BinomialTree.get_greeks(option_type, s0, x, r, volatility, years_to_maturity, n_steps, is_american, dividend_yield)
104
+ end
105
+
106
+ # Price an option using the Bjerksund-Stensland model
107
+ # @param option_type [String] 'call' or 'put'
108
+ # @param s0 [Float] Spot price
109
+ # @param x [Float] Strike price
110
+ # @param r [Float] Risk-free interest rate
111
+ # @param volatility [Float] Volatility
112
+ # @param years_to_maturity [Float] Time to maturity in years
113
+ # @param dividend_yield [Float] Continuous dividend yield
114
+ # @return [Float] Option price
115
+ def price_american(option_type, s0, x, r, volatility, years_to_maturity, dividend_yield = 0.0)
116
+ BjerksundStensland.price_option(option_type, s0, x, r, volatility, years_to_maturity, dividend_yield)
117
+ end
118
+
119
+ # Calculate option Greeks using the Bjerksund-Stensland model
120
+ # @param option_type [String] 'call' or 'put'
121
+ # @param s0 [Float] Spot price
122
+ # @param x [Float] Strike price
123
+ # @param r [Float] Risk-free interest rate
124
+ # @param volatility [Float] Volatility
125
+ # @param years_to_maturity [Float] Time to maturity in years
126
+ # @param dividend_yield [Float] Continuous dividend yield
127
+ # @return [Hash] Option Greeks (delta, gamma, theta, vega, rho)
128
+ def get_american_greeks(option_type, s0, x, r, volatility, years_to_maturity, dividend_yield = 0.0)
129
+ BjerksundStensland.get_greeks(option_type, s0, x, r, volatility, years_to_maturity, dividend_yield)
130
+ end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/option_lab/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'option_lab'
7
+ spec.version = OptionLab::VERSION
8
+ spec.authors = ['Jack Killilea']
9
+ spec.email = ['xkillilea@gmail.com']
10
+
11
+ spec.summary = 'Ruby library for evaluating options trading strategies'
12
+ spec.description = 'A lightweight Ruby library designed to provide quick evaluation of option strategies.'
13
+ spec.homepage = 'https://github.com/xjackk/option_lab'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.3.0'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ %x(git ls-files -z).split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) ||
26
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
27
+ end
28
+ end
29
+ spec.bindir = 'exe'
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ['lib']
32
+
33
+ # Dependencies
34
+ spec.add_dependency 'distribution', '~> 0.8.0' # Statistical distributions
35
+ spec.add_dependency 'unicode_plot', '~> 0.0.5' # For terminal-based plotting
36
+ spec.add_dependency 'numo-linalg', '~> 0.1.7' # Linear algebra functions
37
+ spec.add_dependency 'numo-narray', '~> 0.9.2' # For numerical operations (similar to numpy)
38
+
39
+ # Development dependencies
40
+ spec.add_development_dependency 'rake', '~> 13.0'
41
+ spec.add_development_dependency 'rspec', '~> 3.12'
42
+ spec.add_development_dependency 'rubocop', '~> 1.50'
43
+ end
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: option_lab
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jack Killilea
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: distribution
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: unicode_plot
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: numo-linalg
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: numo-narray
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '13.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '13.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.12'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.12'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.50'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.50'
111
+ description: A lightweight Ruby library designed to provide quick evaluation of option
112
+ strategies.
113
+ email:
114
+ - xkillilea@gmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".rspec"
120
+ - ".rubocop.yml"
121
+ - ".yard/hooks/before_generate.rb"
122
+ - ".yardopts"
123
+ - Gemfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - docs/OptionLab.html
128
+ - docs/OptionLab/BinomialTree.html
129
+ - docs/OptionLab/BjerksundStensland.html
130
+ - docs/OptionLab/BlackScholes.html
131
+ - docs/OptionLab/Engine.html
132
+ - docs/OptionLab/Models.html
133
+ - docs/OptionLab/Models/AmericanModelInputs.html
134
+ - docs/OptionLab/Models/ArrayInputs.html
135
+ - docs/OptionLab/Models/BaseModel.html
136
+ - docs/OptionLab/Models/BinomialModelInputs.html
137
+ - docs/OptionLab/Models/BlackScholesInfo.html
138
+ - docs/OptionLab/Models/BlackScholesModelInputs.html
139
+ - docs/OptionLab/Models/ClosedPosition.html
140
+ - docs/OptionLab/Models/EngineData.html
141
+ - docs/OptionLab/Models/EngineDataResults.html
142
+ - docs/OptionLab/Models/Inputs.html
143
+ - docs/OptionLab/Models/LaplaceInputs.html
144
+ - docs/OptionLab/Models/Option.html
145
+ - docs/OptionLab/Models/Outputs.html
146
+ - docs/OptionLab/Models/PoPOutputs.html
147
+ - docs/OptionLab/Models/PricingResult.html
148
+ - docs/OptionLab/Models/Stock.html
149
+ - docs/OptionLab/Models/TreeVisualization.html
150
+ - docs/OptionLab/Plotting.html
151
+ - docs/OptionLab/Support.html
152
+ - docs/OptionLab/Utils.html
153
+ - docs/_index.html
154
+ - docs/class_list.html
155
+ - docs/css/common.css
156
+ - docs/css/full_list.css
157
+ - docs/css/style.css
158
+ - docs/file.LICENSE.html
159
+ - docs/file.README.html
160
+ - docs/file_list.html
161
+ - docs/frames.html
162
+ - docs/index.html
163
+ - docs/js/app.js
164
+ - docs/js/full_list.js
165
+ - docs/js/jquery.js
166
+ - docs/method_list.html
167
+ - docs/top-level-namespace.html
168
+ - examples/american_options.rb
169
+ - examples/covered_call.rb
170
+ - lib/option_lab.rb
171
+ - lib/option_lab/binomial_tree.rb
172
+ - lib/option_lab/bjerksund_stensland.rb
173
+ - lib/option_lab/black_scholes.rb
174
+ - lib/option_lab/engine.rb
175
+ - lib/option_lab/models.rb
176
+ - lib/option_lab/plotting.rb
177
+ - lib/option_lab/support.rb
178
+ - lib/option_lab/utils.rb
179
+ - lib/option_lab/version.rb
180
+ - option_lab.gemspec
181
+ homepage: https://github.com/xjackk/option_lab
182
+ licenses:
183
+ - MIT
184
+ metadata:
185
+ homepage_uri: https://github.com/xjackk/option_lab
186
+ source_code_uri: https://github.com/xjackk/option_lab
187
+ changelog_uri: https://github.com/xjackk/option_lab/blob/main/CHANGELOG.md
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: 3.3.0
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubygems_version: 3.5.11
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Ruby library for evaluating options trading strategies
207
+ test_files: []