diff --git a/README.md b/README.md index 09b89d3..2fdf775 100644 --- a/README.md +++ b/README.md @@ -30,35 +30,44 @@ Usage require 'rubygems' require 'options_library' - call = Option::Call.new - call.underlying = 95.40 # spot price of the underlying - call.strike = 90.00 # strike price of option - call.time = 0.015 # time in years - call.interest = 0.01 # equates to 1% risk free interest - call.sigma = 0.4875 # equates to 48.75% volatility - call.dividend = 0.0 # no annual dividend yield - - price = call.calc_price # theoretical value of the option - delta = call.calc_delta # option price sensitivity to a change in underlying price - gamma = call.calc_gamma # option delta sensitivity to a change in underlying price - vega = call.calc_vega # option price sensitivity to a change in sigma (volatility) - - implied_vol = call.calc_implied_vol( 1.80 ) # implied volatility based on the target price + # Build the option out with a block builder + call = Option::Call.new do + underlying 95.40 # spot price of the underlying + strike 90.5 # strike price of option + time 0.015 # time in years + interest 0.01 # equates to 1% risk free interest + sigma 0.4875 # equates to 48.75% volatility + dividend 0.05 # 5% annual dividend yield + end + + # Values are calculated when requested + p call.price # theoretical value of the option + p call.delta # option price sensitivity to a change in underlying price + p call.gamma # option delta sensitivity to a change in underlying price + p call.vega # option price sensitivity to a change in sigma (volatility) + + # implied volatility based on a target price + p call.implied_vol_for_price( 1.80 ) # Or go straight at the Calculator methods # Option::Calculator.price_call( underlying, strike, time, interest, sigma, dividend ) - call_price = Option::Calculator.price_call( 94.5, 90.5, 0.015, 0.01, 0.4875, 0.0 ) - -Testing -------- - -To run the tests: - - $ rake - -To add tests see the `Commands` section earlier in this -README. + call_price = Option::Calculator.price_call( 95.40, 90.5, 0.015, 0.01, 0.4875, 0.05 ) + # Deprecated API + call = Option::Call.new + call.underlying = 95.40 + call.strike = 90.00 + call.time = 0.015 + call.interest = 0.01 + call.sigma = 0.4875 + call.dividend = 0.0 + + price = call.calc_price + delta = call.calc_delta + gamma = call.calc_gamma + vega = call.calc_vega + + implied_vol = call.calc_implied_vol( 1.80 ) Contributing ------------ diff --git a/lib/options_library/option_call.rb b/lib/options_library/option_call.rb index c0bb4b4..1619418 100644 --- a/lib/options_library/option_call.rb +++ b/lib/options_library/option_call.rb @@ -5,8 +5,8 @@ module Option class Call < Model - def initialize - super(:call) + def initialize(&blk) + super(:call, &blk) end end diff --git a/lib/options_library/option_model.rb b/lib/options_library/option_model.rb index 0b6ade1..6b81e4b 100644 --- a/lib/options_library/option_model.rb +++ b/lib/options_library/option_model.rb @@ -14,9 +14,11 @@ class Model CALC_THETA_METHODS = { :call=>Calculator.method('theta_call'), :put=>Calculator.method('theta_put') } IMPLIED_VOL_METHODS = { :call=>Calculator.method('implied_vol_call'), :put=>Calculator.method('implied_vol_put') } - attr_accessor :underlying, :strike, :time, :interest, :sigma, :dividend, :option_type + attr_accessor :option_type + + def initialize(option_type, &blk) + raise 'Unknown option_type' unless KNOWN_OPTION_TYPES.include?(option_type) - def initialize(option_type) self.option_type = option_type self.underlying = 0.0 self.strike = 0.0 @@ -24,32 +26,78 @@ def initialize(option_type) self.interest = 0.0 self.sigma = 0.0 self.dividend = 0.0 - raise 'Unknown option_type' unless KNOWN_OPTION_TYPES.include?(option_type) + + if block_given? + # http://graysoftinc.com/ruby-voodoo/dsl-block-styles + blk.arity == 1 ? blk.call(self) : instance_eval(&blk) + end + end + + def underlying(value=nil) + @underlying = value if value + @underlying + end + alias_method :underlying=, :underlying + + def strike(value=nil) + @strike = value if value + @strike + end + alias_method :strike=, :strike + + def time(value=nil) + @time = value if value + @time + end + alias_method :time=, :time + + def interest(value=nil) + @interest = value if value + @interest + end + alias_method :interest=, :interest + + def sigma(value=nil) + @sigma = value if value + @sigma + end + alias_method :sigma=, :sigma + + def dividend(value=nil) + @dividend = value if value + @dividend end + alias_method :dividend=, :dividend def calc_price CALC_PRICE_METHODS[option_type].call(underlying, strike, time, interest, sigma, dividend) end + alias_method :price, :calc_price def calc_delta CALC_DELTA_METHODS[option_type].call(underlying, strike, time, interest, sigma, dividend) end + alias_method :delta, :calc_delta def calc_gamma Calculator.gamma(underlying, strike, time, interest, sigma, dividend) end + alias_method :gamma, :calc_gamma def calc_theta CALC_THETA_METHODS[option_type].call(underlying, strike, time, interest, sigma, dividend) end + alias_method :theta, :calc_theta def calc_vega Calculator.vega(underlying, strike, time, interest, sigma, dividend) end + alias_method :vega, :calc_vega def calc_implied_vol(target_price) IMPLIED_VOL_METHODS[option_type].call(underlying, strike, time, interest, target_price, dividend) end + alias_method :implied_vol_for_price, :calc_implied_vol end end diff --git a/lib/options_library/option_put.rb b/lib/options_library/option_put.rb index bc3cba3..3fecaa7 100644 --- a/lib/options_library/option_put.rb +++ b/lib/options_library/option_put.rb @@ -5,8 +5,8 @@ module Option class Put < Model - def initialize - super(:put) + def initialize(&blk) + super(:put, &blk) end end diff --git a/options_library.gemspec b/options_library.gemspec index c1a989e..030e5d1 100644 --- a/options_library.gemspec +++ b/options_library.gemspec @@ -2,21 +2,37 @@ Gem::Specification.new do |s| s.name = %q{options_library} - s.version = "1.0.3" + s.version = "1.0.4" s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version= s.authors = ["Dan Tylenda-Emmons"] - s.date = %q{2011-02-17} - s.description = %q{A gem used to calc the price of an option.} + s.date = %q{2016-06-22} + s.description = %q{A gem used to calc the price of call and put options.} s.email = %q{jrubyist@gmail.com} - s.extra_rdoc_files = ["README.md", "lib/options_library.rb", "lib/options_library/option_calculator.rb", "lib/options_library/option_call.rb", "lib/options_library/option_model.rb", "lib/options_library/option_put.rb"] - s.files = ["Manifest", "README.md", "Rakefile", "lib/options_library.rb", "lib/options_library/option_calculator.rb", "lib/options_library/option_call.rb", "lib/options_library/option_model.rb", "lib/options_library/option_put.rb", "options_library.gemspec", "options_library/options_library.iml"] + s.extra_rdoc_files = [ + "README.md", + "lib/options_library.rb", + "lib/options_library/option_calculator.rb", + "lib/options_library/option_call.rb", + "lib/options_library/option_model.rb", + "lib/options_library/option_put.rb"] + s.files = [ + "Manifest", + "README.md", + "lib/options_library.rb", + "lib/options_library/option_calculator.rb", + "lib/options_library/option_call.rb", + "lib/options_library/option_model.rb", + "lib/options_library/option_put.rb", + "options_library.gemspec"] s.homepage = %q{http://github.com/codertrader/options_library} s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Options_library", "--main", "README.md"] s.require_paths = ["lib"] s.rubyforge_project = %q{options_library} s.rubygems_version = %q{1.5.2} - s.summary = %q{A gem used to calc the price of an option.} + s.summary = %q{A gem used to calc the price of call and put options. Can also produce all of the greeks and will compute + implied volatility given a target price.} + s.license = "0BSD" if s.respond_to? :specification_version then s.specification_version = 3