├── .rspec ├── spec ├── support │ ├── format_float.rb │ ├── strict_equals.rb │ ├── strict_equals_pct.rb │ ├── nilable_equals.rb │ ├── nilable_equals_pct.rb │ └── calculate_greeks_hash.rb ├── greeks │ ├── 22days.calls.csv │ ├── 50days.puts.csv │ ├── 22days.puts.csv │ ├── 50days.calls.csv │ ├── calculations │ │ ├── gamma_spec.rb │ │ ├── delta_spec.rb │ │ ├── rho_spec.rb │ │ ├── vega_spec.rb │ │ ├── normal_distribution_spec.rb │ │ ├── theta_spec.rb │ │ ├── iv_vega_spec.rb │ │ ├── iv_option_price_spec.rb │ │ ├── time_values_spec.rb │ │ └── iv_spec.rb │ ├── greeks_spec.rb │ └── 24days.haliburton.html ├── spec_helper.rb ├── helpers │ └── greek_calculation_shorthand_helpers.rb └── ed.csv ├── .gitignore ├── Gemfile ├── lib ├── greeks │ └── calculations │ │ ├── normal_distribution.rb │ │ ├── rho.rb │ │ ├── vega.rb │ │ ├── theta.rb │ │ ├── gamma.rb │ │ ├── delta.rb │ │ ├── iv.rb │ │ └── time_values.rb └── greeks.rb ├── greeks.gemspec ├── README.md └── Gemfile.lock /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation --color --profile -------------------------------------------------------------------------------- /spec/support/format_float.rb: -------------------------------------------------------------------------------- 1 | def FormatFloat(value, decimal_places) 2 | sign = value < 0 ? -1: 1; 3 | vv = value.abs(); 4 | power = 10.0**decimal_places 5 | vv = vv * power + 0.00000001; 6 | vv = sign * vv.round() / power; 7 | vv 8 | end 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | coverage 6 | InstalledFiles 7 | lib/bundler/man 8 | pkg 9 | rdoc 10 | spec/reports 11 | test/tmp 12 | test/version_tmp 13 | tmp 14 | 15 | # YARD artifacts 16 | .yardoc 17 | _yardoc 18 | doc/ 19 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'require_all' 4 | gem 'hash_plus', '>= 1.3' 5 | 6 | group :development, :test do 7 | gem 'awesome_print' 8 | gem 'rspec' 9 | gem 'better_errors' 10 | gem 'brakeman' 11 | gem 'oink' 12 | gem 'pry' 13 | gem 'pry-nav' 14 | gem 'rubocop' 15 | gem 'simplecov', :require => false 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/strict_equals.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | 3 | RSpec::Matchers.define :strict_equals do |expected, decimal_places| 4 | match do |actual| 5 | FormatFloat(actual, decimal_places).should == expected 6 | end 7 | 8 | failure_message do |actual| 9 | "expected that '#{actual}' would match of '#{expected}' to within '#{decimal_places}' decimal places" 10 | end 11 | end -------------------------------------------------------------------------------- /spec/support/strict_equals_pct.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | 3 | RSpec::Matchers.define :strict_equals_pct do |expected, decimal_places| 4 | match do |actual| 5 | FormatFloat(actual.to_f * 100.0, decimal_places).should == expected 6 | end 7 | 8 | failure_message do |actual| 9 | "expected that '#{actual}' would match of '#{expected}' to within '#{decimal_places}' decimal places" 10 | end 11 | end -------------------------------------------------------------------------------- /spec/support/nilable_equals.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | 3 | RSpec::Matchers.define :nilable_equals do |expected, decimal_places| 4 | match do |actual| 5 | if expected.nil? || expected.zero? 6 | actual.should be_nil 7 | else 8 | actual.should strict_equals expected, decimal_places 9 | end 10 | end 11 | 12 | failure_message do |actual| 13 | "expected that '#{actual}' would match of '#{expected}' to within '#{decimal_places}' decimal places" 14 | end 15 | end -------------------------------------------------------------------------------- /spec/support/nilable_equals_pct.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | 3 | RSpec::Matchers.define :nilable_equals_pct do |expected, decimal_places| 4 | match do |actual| 5 | if expected.nil? || expected.zero? 6 | actual.should be_nil 7 | else 8 | actual.should strict_equals_pct expected, decimal_places 9 | end 10 | end 11 | 12 | failure_message do |actual| 13 | "expected that '#{actual}' would match of '#{expected}' to within '#{decimal_places}' decimal places" 14 | end 15 | end -------------------------------------------------------------------------------- /spec/greeks/22days.calls.csv: -------------------------------------------------------------------------------- 1 | :stock_price,:stock_dividend_rate,:federal_reserve_interest_rate,:option_expires_in_days,:option_strike,:option_price,:option_volume,:option_open_interest,:iv,:delta,:gamma,:vega,:rho,:theta,:delta_vs_theta,:annualized_premium_value,:premium_value,:time_value,:annualized_time_value,:break_even 4.04,0,0.02,22,3.5,0.59,12737,10106,59.92,5.81,1.84,0.24,0.3,-0.53,-11.04,247.22,0.54,0.05,19.52,43.77 4.04,0,0.02,22,4,0.26,35380,23733,59.5,8.6,4.8,0.92,0.48,-1.99,-4.33,99.94,0.04,0.22,84.15,33.38 4.04,0,0.02,22,4.5,0.09,19750,17432,60.3,11.8,8.2,2.22,0.68,-4.82,-2.44,31.43,0,0.09,34.96,17.92 -------------------------------------------------------------------------------- /spec/greeks/50days.puts.csv: -------------------------------------------------------------------------------- 1 | :stock_price,:stock_dividend_rate,:federal_reserve_interest_rate,:option_expires_in_days,:option_strike,:option_price,:option_volume,:option_open_interest,:iv,:delta,:gamma,:vega,:rho,:theta,:delta_vs_theta,:annualized_premium_value,:premium_value,:time_value,:annualized_time_value,:break_even 4.04,0,0.03,50,3.5,0.17,100,"2,847",68,-5.8,-5.1,1.9,-0.95,-1.86,3.13,33.94,0,0.17,29.5,26.33 4.04,0,0.03,50,4,0.37,"4,420","2,881",65.15,-4.8,-3.7,1.05,-0.8,-1.03,4.63,63.32,0,0.37,62.72,37.53 4.04,0,0.03,50,4.5,0.68,"10,411","10,110",65.4,-3.7,-2.5,0.55,-0.66,-0.54,6.88,100.72,0.46,0.22,37.95,45.74 -------------------------------------------------------------------------------- /spec/greeks/22days.puts.csv: -------------------------------------------------------------------------------- 1 | :stock_price,:stock_dividend_rate,:federal_reserve_interest_rate,:option_expires_in_days,:option_strike,:option_price,:option_volume,:option_open_interest,:iv,:delta,:gamma,:vega,:rho,:theta,:delta_vs_theta,:annualized_premium_value,:premium_value,:time_value,:annualized_time_value,:break_even 4.04,0,0.02,22,3.5,0.06,"18,702","14,647",63.5,-11,-9.5,2.65,-0.76,-5.75,1.91,26.97,0,0.06,23.4,17.63 4.04,0,0.02,22,4,0.22,"5,339","4,782",59.55,-8.15,-6,1.08,-0.58,-2.36,3.46,84.97,0,0.22,84.15,35.56 4.04,0,0.02,22,4.5,0.55,835,"1,062",60.4,-5.4,-2.9,0.36,-0.4,-0.79,6.87,182.99,0.46,0.09,34.96,47.09 -------------------------------------------------------------------------------- /spec/greeks/50days.calls.csv: -------------------------------------------------------------------------------- 1 | :stock_price,:stock_dividend_rate,:federal_reserve_interest_rate,:option_expires_in_days,:option_strike,:option_price,:option_volume,:option_open_interest,:iv,:delta,:gamma,:vega,:rho,:theta,:delta_vs_theta,:annualized_premium_value,:premium_value,:time_value,:annualized_time_value,:break_even 4.04,0,0.03,50,3.5,0.69,"15,069","6,219",63.7,4.5,1.7,0.43,0.49,-0.42,-10.64,128.78,0.54,0.15,26.09,39.28 4.04,0,0.03,50,4,0.4,"23,810","17,934",63.4,5.7,2.95,0.94,0.66,-0.93,-6.16,68.21,0.04,0.36,61.09,31.62 4.04,0,0.03,50,4.5,0.22,"8,741","8,971",64.5,6.8,4.2,1.68,0.82,-1.64,-4.16,34.16,0,0.22,37.95,22.2 -------------------------------------------------------------------------------- /spec/greeks/calculations/gamma_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::gamma" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | let(:opts) { {:stock_price => 1.0, :option_expires_pct_year_sqrt => 2.0, :nd1 => 4.0, :rate_vs_expires => 5.0} } 8 | 9 | ## 10 | # General behavior tests 11 | ## 12 | it { expect{ gamma(opts) }.to raise_error ArgumentError } 13 | 14 | it { gamma(opts.merge(:iv => nil)).should be_nil } 15 | 16 | it { gamma(opts.merge(:iv => 3.0)).round(2).should === 3.33 } 17 | 18 | ## 19 | # More specific examples 20 | ## 21 | # TODO 22 | end 23 | -------------------------------------------------------------------------------- /lib/greeks/calculations/normal_distribution.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | # Moddeled after the Excel NORMSDIST function 4 | def normal_distribution(value) 5 | p = 0.2316419 6 | b1 = 0.319381530 7 | b2 = -0.356563782 8 | b3 = 1.781477937 9 | b4 = -1.821255978 10 | b5 = 1.330274429 11 | 12 | y = value.abs 13 | z = Math.exp(-y*y/2) / Math.sqrt(2 * Math::PI) 14 | t = 1 / ( 1 + p * y) 15 | cum = 1 - z * (b1*t + b2*t*t + b3*t*t*t + b4*t*t*t*t + b5*t*t*t*t*t) 16 | 17 | cum = 1 - cum if (value < 0) 18 | cum 19 | end 20 | 21 | 22 | # Normal distribution function (Gaussian bell curve) 23 | def normal_distribution_gaussian(value) 24 | Math.exp(-0.5 * value * value) / Math.sqrt(2 * Math::PI) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/greeks/calculations/delta_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::delta" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | let(:opts) { {:rate_vs_expires => 1.0, :d1_normal_distribution => 1.0} } 8 | 9 | ## 10 | # General behavior tests 11 | ## 12 | it { expect{ delta(opts) }.to raise_error ArgumentError } 13 | 14 | it { delta(opts.merge(:option_type => :call, :iv => nil)).should be_nil } 15 | it { delta(opts.merge(:option_type => :put, :iv => nil)).should be_nil } 16 | 17 | it { delta(opts.merge(:option_type => :call, :iv => 'any value')).should === 1.0 } 18 | it { delta(opts.merge(:option_type => :put, :iv => 'any value')).should === -1.0 } 19 | 20 | ## 21 | # More specific examples 22 | ## 23 | # TODO 24 | end 25 | -------------------------------------------------------------------------------- /greeks.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | Gem::Specification.new do |gem| 4 | gem.name = "greeks" 5 | gem.version = '1.4' 6 | gem.authors = ["Glenn Nagel"] 7 | gem.email = ["glenn@mercury-wireless.com"] 8 | gem.homepage = "https://github.com/gnagel/greeks" 9 | gem.summary = %q{Calculate greeks for options trading (Implied Volatility, Delta, Gamma, Vega, Rho, and Theta)} 10 | gem.description = %q{Calculate greeks (iv, delta, gamma, vega, rho, theta)} 11 | gem.license = 'MIT' 12 | 13 | gem.files = `git ls-files`.split($/) 14 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 15 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 16 | gem.require_paths = ["lib", "tasks"] 17 | 18 | gem.add_dependency('require_all') 19 | gem.add_dependency('hash_plus', '>= 1.3') 20 | end 21 | -------------------------------------------------------------------------------- /spec/greeks/calculations/rho_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::rho" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | let(:opts) { {:option_expires_pct_year => 1.0, :strike_vs_fed_vs_expires => 2.0, :d2_normal_distribution => 3.0} } 8 | 9 | ## 10 | # General behavior tests 11 | ## 12 | it { expect{ rho(opts) }.to raise_error ArgumentError } 13 | 14 | it { rho(opts.merge(:option_type => :call, :iv => nil)).should be_nil } 15 | it { rho(opts.merge(:option_type => :put, :iv => nil)).should be_nil } 16 | 17 | it { rho(opts.merge(:option_type => :call, :iv => 'any value')).should === 0.06 } 18 | it { rho(opts.merge(:option_type => :put, :iv => 'any value')).should === -0.06 } 19 | 20 | ## 21 | # More specific examples 22 | ## 23 | # TODO 24 | end 25 | -------------------------------------------------------------------------------- /lib/greeks/calculations/rho.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | # Rho 4 | # The change in the value of an option for a change in the prevailing interest rate that matches the duration of the option, 5 | # all else held equal. Generally rho is not a big driver of price changes for options, as interest rates tend to be relatively stable. 6 | def rho(opts = {}) 7 | opts.requires_keys_are_present(:iv) 8 | return nil if opts[:iv].nil? 9 | 10 | opts.requires_keys_are_not_nil(:option_type, :option_expires_pct_year, :strike_vs_fed_vs_expires, :d2_normal_distribution, :iv) 11 | 12 | multiplier = case opts[:option_type] 13 | when :call 14 | 1.0 15 | when :put 16 | -1.0 17 | else 18 | raise "Invalid option_type = #{opts[:option_type].inspect}" 19 | end 20 | 21 | multiplier * opts[:option_expires_pct_year] * opts[:strike_vs_fed_vs_expires] * opts[:d2_normal_distribution] / 100 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/greeks/calculations/vega.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | # Vega 4 | # The change in the price of an option for a change in the implied volatility of the option, all else held equal. 5 | # In general, as the options market thinks it is more difficult to value a stock, implied volatility and therefore 6 | # the price of the options will increase. For example, if an option is trading for $1, the implied volatility is 20%, 7 | # and the vega is $0.05, then a one-percentage-point increase in implied volatility to 21% would correspond to an increase in 8 | # the price of the option to $1.05. In percentage terms, the vega in this case would be ($0.05/$1.00)/(1 percentage point) = 5%. 9 | def vega(opts = {}) 10 | opts.requires_keys_are_present(:iv) 11 | return nil if opts[:iv].nil? 12 | 13 | opts.requires_keys_are_not_nil(:price_vs_rate_vs_expires, :nd1, :option_expires_pct_year_sqrt, :iv) 14 | 15 | opts[:price_vs_rate_vs_expires] * opts[:option_expires_pct_year_sqrt] * opts[:nd1] / 100 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/greeks/calculations/vega_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::vega" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | let(:opts) { {:price_vs_rate_vs_expires => 1.0, :nd1 => 1.0, :option_expires_pct_year_sqrt => 1.0} } 8 | 9 | ## 10 | # General behavior tests 11 | ## 12 | it { expect{ vega(opts) }.to raise_error ArgumentError } 13 | 14 | it { vega(opts.merge(:iv => nil)).should be_nil } 15 | 16 | it { vega(opts.merge(:iv => 'any value')).round(2).should === 0.01 } 17 | 18 | ## 19 | # More specific examples 20 | ## 21 | it { vega(:price_vs_rate_vs_expires => 1.0, :nd1 => 1.0, :option_expires_pct_year_sqrt => 1.0, :iv => 'any value').should === 0.01 } 22 | it { vega(:price_vs_rate_vs_expires => 3.0, :nd1 => 2.0, :option_expires_pct_year_sqrt => 1.0, :iv => 'any value').should === 0.06 } 23 | it { vega(:price_vs_rate_vs_expires => 10.0, :nd1 => 10.0, :option_expires_pct_year_sqrt => 5.0, :iv => 'any value').should === 5.0 } 24 | end 25 | -------------------------------------------------------------------------------- /spec/greeks/calculations/normal_distribution_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::normal_distribution" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | it "should take 0.000005s per calculation" do 8 | test_speed(0.000005) { normal_distribution(0.0) } 9 | end 10 | 11 | it "should calculate the normal_distribution" do 12 | normal_distribution(-0.0).should === 0.5000000005248086 13 | normal_distribution(0.038237059844021946).should === 0.5152507249371991 14 | normal_distribution(0.038410221197121876).should === 0.5153197557441735 15 | normal_distribution(0.05419795049563356).should === 0.5216113427954938 16 | normal_distribution(0.08866836079942457).should === 0.5353273260368764 17 | normal_distribution(0.22705303864277918).should === 0.5898087102891723 18 | normal_distribution(0.23102722425730948).should === 0.5913531319833535 19 | normal_distribution(0.24375225242810844).should === 0.5962886004762329 20 | normal_distribution(0.24745839358343474).should === 0.5977232060736917 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/greeks/calculations/theta.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | def theta(opts = {}) 4 | opts.requires_keys_are_present(:iv) 5 | return nil if opts[:iv].nil? 6 | 7 | opts.requires_keys_are_not_nil(:stock_dividend_rate_f, :federal_reserve_interest_rate_f, :option_type, :option_expires_pct_year_sqrt, :iv, :strike_vs_fed_vs_expires, :price_vs_rate_vs_expires, :nd1, :d1_normal_distribution, :d2_normal_distribution) 8 | 9 | part0 = opts[:price_vs_rate_vs_expires] * opts[:nd1] * opts[:iv] 10 | part1 = 2 * opts[:option_expires_pct_year_sqrt] 11 | part2 = opts[:stock_dividend_rate_f] * opts[:price_vs_rate_vs_expires] * opts[:d1_normal_distribution] 12 | part3 = opts[:federal_reserve_interest_rate_f] * opts[:strike_vs_fed_vs_expires] * opts[:d2_normal_distribution] 13 | 14 | case opts[:option_type] 15 | when :call 16 | return (-part0 / part1 + part2 - part3) / 365 17 | when :put 18 | return (-part0 / part1 - part2 + part3) / 365 19 | else 20 | raise "Invalid option_type = #{opts[:option_type].inspect}" 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/support/calculate_greeks_hash.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | 3 | RSpec::Matchers.define :be_a_greeks_hash do |expected| 4 | match do |actual| 5 | hash = actual.to_hash 6 | hash.should_not be_nil 7 | hash.should_not be_empty 8 | 9 | keys = [hash.keys, expected.keys].flatten.uniq.sort 10 | verbose_puts "Keys: #{keys.inspect}" 11 | keys.each do |key| 12 | verbose_puts "[#{"%30s" % key}] Hash: #{hash[key].inspect} vs Actual: #{expected[key].inspect}" 13 | end 14 | 15 | # Delete all the values that match 16 | # This will leave only the values that differ 17 | expected.keys.dup.each do |key| 18 | if hash[key] == expected[key] 19 | expected.delete(key) 20 | next 21 | end 22 | 23 | if hash[key].class == expected[key].class && !hash[key].nil? && !hash[key].is_a?(Symbol) && hash[key].round(1) == expected[key].round(1) 24 | expected.delete(key) 25 | next 26 | end 27 | 28 | expected[key] = "#{expected.delete(key).inspect}(e) vs #{hash[key].inspect}(a)" 29 | end 30 | verbose_puts "Hash: #{hash}" 31 | verbose_puts "Expected: #{expected}" 32 | expected.should be_empty 33 | end 34 | 35 | failure_message do |actual| 36 | "expected that #{actual.to_hash} would match values of #{expected}" 37 | end 38 | end -------------------------------------------------------------------------------- /lib/greeks/calculations/gamma.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | # Gamma 4 | # A measurement of the change in delta as the price of the underlying stock changes. As the underlying stock price changes, 5 | # the delta of the option changes, too. Gamma indicates how quickly your exposure to the price movement of the underlying 6 | # security changes as the price of the underlying security varies. For example, if you have a call with a strike of $50 7 | # and the stock price is $50, the delta likely will be approximately $0.50 for a one-dollar movement of the stock. 8 | # At a stock price of $60, the delta will be greater, closer to $0.75. At a stock price of $40, the delta will be less, 9 | # closer to $0.25. In this example, if the stock price changes from $50 to $60, then the delta will change from $0.50 to $0.75. 10 | # The $10 change in stock price caused a $0.25 change in delta, so gamma is approximately $0.25/10, or $0.025, in this case. 11 | def gamma(opts = {}) 12 | opts.requires_keys_are_present(:iv) 13 | return nil if opts[:iv].nil? 14 | 15 | opts.requires_keys_are_not_nil(:stock_price, :option_expires_pct_year_sqrt, :nd1, :rate_vs_expires, :iv) 16 | 17 | opts[:nd1] * opts[:rate_vs_expires] / (opts[:stock_price] * opts[:iv] * opts[:option_expires_pct_year_sqrt]) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", File.dirname(__FILE__)) 2 | require 'rubygems' 3 | require 'greeks' 4 | 5 | require 'rspec' 6 | # require 'rspec-expectations' 7 | require 'benchmark' 8 | require 'require_all' 9 | require 'csv' 10 | # require 'rantly/property' 11 | # require 'rantly/rspec_extensions' 12 | require 'pry' 13 | require 'pry-nav' 14 | 15 | $spec_root = File.dirname(__FILE__) 16 | 17 | require_all File.join($spec_root, 'support') 18 | require_all File.join($spec_root, 'helpers') 19 | 20 | RSpec.configure do |config| 21 | config.include Math::GreekCalculationShorthandHelpers 22 | 23 | old_verbose, $VERBOSE = $VERBOSE, nil 24 | 25 | config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] } 26 | 27 | def verbose_puts(s) 28 | return unless $VERBOSE 29 | file = File.basename(caller(1).first) 30 | super("puts() from #{file}: #{s}") 31 | end 32 | 33 | def puts(s) 34 | file = File.basename(caller(1).first) 35 | super("puts() from #{file}: #{s}") 36 | end 37 | 38 | def print(s) 39 | file = File.basename(caller(1).first) 40 | super("print() from #{file}: #{s}") 41 | end 42 | 43 | def p(s) 44 | file = File.basename(caller(1).first) 45 | super("p() from #{file}: #{s}") 46 | end 47 | 48 | def test_speed(x_speed, x_times = 1000) 49 | time = Benchmark.realtime { x_times.times { |n| @result = yield } } 50 | (time / x_times).should < x_speed 51 | @result 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/greeks/calculations/theta_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::theta" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | let(:opts) { {:option_type => :call, :stock_dividend_rate_f => 0.00, :federal_reserve_interest_rate_f => 0.00, :option_expires_pct_year_sqrt => 1.0, :strike_vs_fed_vs_expires => 1.0, :price_vs_rate_vs_expires => 1.0, :nd1 => 1.0, :d1_normal_distribution => 1.0, :d2_normal_distribution => 1.0} } 8 | 9 | ## 10 | # General behavior tests 11 | ## 12 | it { expect{ theta(opts) }.to raise_error ArgumentError } 13 | 14 | it { theta(opts.merge(:iv => nil)).should be_nil } 15 | 16 | it { theta(opts.merge(:iv => 1.0)).round(2).should. === 0.0 } 17 | 18 | ## 19 | # More specific examples 20 | ## 21 | it { theta(:option_type => :call, :stock_dividend_rate_f => 1.0005, :federal_reserve_interest_rate_f => 2.0002, :option_expires_pct_year_sqrt => 1.0, :iv => 1.0, :strike_vs_fed_vs_expires => 3.0, :price_vs_rate_vs_expires => 4.0, :nd1 => 5.0, :d1_normal_distribution => 6.0, :d2_normal_distribution => 7.0).should === -0.0766909589041096 } 22 | 23 | it { theta(:option_type => :put, :stock_dividend_rate_f => 1.0005, :federal_reserve_interest_rate_f => 2.0002, :option_expires_pct_year_sqrt => 1.0, :iv => 1.0, :strike_vs_fed_vs_expires => 3.0, :price_vs_rate_vs_expires => 4.0, :nd1 => 5.0, :d1_normal_distribution => 6.0, :d2_normal_distribution => 7.0).should === 0.021896438356164394 } 24 | end 25 | -------------------------------------------------------------------------------- /lib/greeks/calculations/delta.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | # Delta 4 | # A measurement of the change in the price of an option resulting from a change in the price of the underlying security. 5 | # Delta is positive for calls and negative for puts. Delta can be calculated as the dollar change of the option that an 6 | # investor can expect for a one-dollar change in the underlying security. For example, let's say an option on a stock 7 | # trading at $50 costs $1 and has a delta of $0.50 per dollar of underlying stock price change. If the stock price rises 8 | # to $52, the price of the option will increase by $1 (the $2 price change times the $0.50 delta). After the stock price 9 | # movement, the option will be worth $2 ($1 initial cost plus $1 delta). Delta can also be calculated as a percentage 10 | # change in the option price for a one-percent change in the underlying security; this method of viewing the delta value 11 | # is also known as "leverage." 12 | def delta(opts) 13 | opts.requires_keys_are_present(:iv) 14 | return nil if opts[:iv].nil? 15 | 16 | opts.requires_keys_are_not_nil(:option_type, :rate_vs_expires, :d1_normal_distribution, :iv) 17 | 18 | 19 | multiplier = case opts[:option_type] 20 | when :call 21 | 1.0 22 | when :put 23 | -1.0 24 | else 25 | raise "Invalid option_type = #{opts[:option_type].inspect}" 26 | end 27 | 28 | multiplier * opts[:rate_vs_expires] * opts[:d1_normal_distribution] 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | greeks 2 | ====== 3 | 4 | Calculate greeks for options trading (Implied Volatility, Delta, Gamma, Vega, Rho, and Theta) 5 | 6 | 7 | Examples 8 | ======== 9 | What are the Greeks for Calls & Puts for AMD ($4.07 @ 35days)? 10 | 11 | AMD stock = $4.07 12 | Option Strike = $4.50 13 | Option Expires = 35 days 14 | 15 | Fed Rate = 0.01% 16 | Dividend Rate = 0% 17 | 18 | Call Bid = $0.16 19 | Put Bid = $0.59 20 | 21 | ```ruby 22 | # Calculate the Greeks for the Stock & Option Contract 23 | calc = Math::Greeks::Calculator.new( 24 | :stock_price => 4.07, 25 | :stock_dividend_rate => 0.00, 26 | :federal_reserve_interest_rate => 0.01, 27 | :option_expires_in_days => 35.0, 28 | :option_strike => 4.50, 29 | :option_type => :call, 30 | :option_price => 0.16, 31 | ) 32 | 33 | # What are the display values? 34 | hash = calc.to_hash # Convert the values for display/consumption 35 | hash[:iv] # => 61.93 (Implied Volatility %) 36 | hash[:delta] # => -4.57 (Delta %/%) 37 | hash[:gamma] # => -2.84 (Gamma pp/pp) 38 | hash[:vega] # => 0.49 (Vega %/pp) 39 | hash[:rho] # => -0.55 (Rho %/pp) 40 | hash[:theta] # => -0.68 (Theta %/day) 41 | hash[:break_even] # => 45.66 (Chance of Breakeven) 42 | 43 | # What are the raw values? 44 | calc.break_even # What is the raw Break Even odds (0.000 to 1.000) 45 | calc.iv # What is the raw IV value (0.000 to 1.000) 46 | calc.delta # What is the raw Delta $/$? 47 | calc.gamma # What is the raw Gamma $/$? 48 | calc.vega # What is the raw Vega $/pp? 49 | calc.rho # What is the raw Rho $/pp? 50 | calc.theta # What is the raw Theta $/day? 51 | ``` 52 | -------------------------------------------------------------------------------- /spec/greeks/calculations/iv_vega_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::iv_vega" do 4 | include Math 5 | include Math::GreekCalculations 6 | 7 | let(:stock_price) { 10.00 } 8 | let(:stock_dividend_rate_f) { 0.00 } 9 | let(:option_expires_pct_year) { 1.00 } 10 | let(:volatility_guess) { 0.50 } 11 | 12 | context "exactly at the money" do 13 | let(:option_strike) { 10.00 } 14 | 15 | context "0% interest" do 16 | let(:federal_reserve_interest_rate_f) { 0.00 } 17 | let(:expected) { 3.866681168028493 } 18 | 19 | it { var_vega().should === expected } 20 | end 21 | 22 | context "0.02% interest" do 23 | let(:federal_reserve_interest_rate_f) { 0.0002 } 24 | let(:expected) { 3.866294209940902 } 25 | 26 | it { var_vega().should === expected } 27 | end 28 | end 29 | 30 | context "out of the money" do 31 | let(:option_strike) { 15.00 } 32 | 33 | context "0% interest" do 34 | let(:federal_reserve_interest_rate_f) { 0.00 } 35 | let(:expected) { 3.4086802947730774 } 36 | 37 | it { var_vega().should === expected } 38 | end 39 | 40 | context "0.02% interest" do 41 | let(:federal_reserve_interest_rate_f) { 0.0002 } 42 | let(:expected) { 3.4094449205351056 } 43 | 44 | it { var_vega().should === expected } 45 | end 46 | end 47 | 48 | context "in of the money" do 49 | let(:option_strike) { 5.00 } 50 | 51 | context "0% interest" do 52 | let(:federal_reserve_interest_rate_f) { 0.00 } 53 | let(:expected) { 1.045940982192684 } 54 | 55 | it { var_vega().should === expected } 56 | end 57 | 58 | context "0.02% interest" do 59 | let(:federal_reserve_interest_rate_f) { 0.0002 } 60 | let(:expected) { 1.045256535627944 } 61 | 62 | it { var_vega().should === expected } 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /spec/greeks/calculations/iv_option_price_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::iv_option_price" do 4 | include Math 5 | include Math::GreekCalculations 6 | 7 | let(:stock_price) { 10.00 } 8 | let(:stock_dividend_rate_f) { 0.00 } 9 | let(:option_type) { :call } 10 | let(:option_expires_pct_year) { 1.00 } 11 | let(:volatility_guess) { 0.50 } 12 | 13 | context "exactly at the money" do 14 | let(:option_strike) { 10.00 } 15 | 16 | context "0% interest" do 17 | let(:federal_reserve_interest_rate_f) { 0.00 } 18 | let(:expected) { 1.9741254870839349 } 19 | 20 | it { var_option_price().should === expected } 21 | end 22 | 23 | context "0.02% interest" do 24 | let(:federal_reserve_interest_rate_f) { 0.0002 } 25 | let(:expected) { 1.9749281489443273 } 26 | 27 | it { var_option_price().should === expected } 28 | end 29 | end 30 | 31 | context "out of the money" do 32 | let(:option_strike) { 15.00 } 33 | 34 | context "0% interest" do 35 | let(:federal_reserve_interest_rate_f) { 0.00 } 36 | let(:expected) { 0.7088126378267066 } 37 | 38 | it { var_option_price().should === expected } 39 | end 40 | 41 | context "0.02% interest" do 42 | let(:federal_reserve_interest_rate_f) { 0.0002 } 43 | let(:expected) { 0.7092458172337008 } 44 | 45 | it { var_option_price().should === expected } 46 | end 47 | end 48 | 49 | context "in of the money" do 50 | let(:option_strike) { 5.00 } 51 | 52 | context "0% interest" do 53 | let(:federal_reserve_interest_rate_f) { 0.00 } 54 | let(:expected) { 5.130693877506824 } 55 | 56 | it { var_option_price().should === expected } 57 | end 58 | 59 | context "0.02% interest" do 60 | let(:federal_reserve_interest_rate_f) { 0.0002 } 61 | let(:expected) { 5.1315659170286185 } 62 | 63 | it { var_option_price().should === expected } 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activemodel (5.0.2) 5 | activesupport (= 5.0.2) 6 | activerecord (5.0.2) 7 | activemodel (= 5.0.2) 8 | activesupport (= 5.0.2) 9 | arel (~> 7.0) 10 | activesupport (5.0.2) 11 | concurrent-ruby (~> 1.0, >= 1.0.2) 12 | i18n (~> 0.7) 13 | minitest (~> 5.1) 14 | tzinfo (~> 1.1) 15 | arel (7.1.4) 16 | ast (2.3.0) 17 | awesome_print (1.7.0) 18 | better_errors (2.1.1) 19 | coderay (>= 1.0.0) 20 | erubis (>= 2.6.6) 21 | rack (>= 0.9.0) 22 | brakeman (3.5.0) 23 | coderay (1.1.1) 24 | concurrent-ruby (1.0.5) 25 | diff-lcs (1.3) 26 | docile (1.1.5) 27 | erubis (2.7.0) 28 | hash_plus (1.3) 29 | hodel_3000_compliant_logger (0.1.1) 30 | i18n (0.8.1) 31 | json (2.0.3) 32 | method_source (0.8.2) 33 | minitest (5.10.1) 34 | oink (0.10.1) 35 | activerecord 36 | hodel_3000_compliant_logger 37 | parser (2.4.0.0) 38 | ast (~> 2.2) 39 | powerpack (0.1.1) 40 | pry (0.10.4) 41 | coderay (~> 1.1.0) 42 | method_source (~> 0.8.1) 43 | slop (~> 3.4) 44 | pry-nav (0.2.4) 45 | pry (>= 0.9.10, < 0.11.0) 46 | rack (2.0.1) 47 | rainbow (2.2.1) 48 | require_all (1.4.0) 49 | rspec (3.5.0) 50 | rspec-core (~> 3.5.0) 51 | rspec-expectations (~> 3.5.0) 52 | rspec-mocks (~> 3.5.0) 53 | rspec-core (3.5.4) 54 | rspec-support (~> 3.5.0) 55 | rspec-expectations (3.5.0) 56 | diff-lcs (>= 1.2.0, < 2.0) 57 | rspec-support (~> 3.5.0) 58 | rspec-mocks (3.5.0) 59 | diff-lcs (>= 1.2.0, < 2.0) 60 | rspec-support (~> 3.5.0) 61 | rspec-support (3.5.0) 62 | rubocop (0.47.1) 63 | parser (>= 2.3.3.1, < 3.0) 64 | powerpack (~> 0.1) 65 | rainbow (>= 1.99.1, < 3.0) 66 | ruby-progressbar (~> 1.7) 67 | unicode-display_width (~> 1.0, >= 1.0.1) 68 | ruby-progressbar (1.8.1) 69 | simplecov (0.14.1) 70 | docile (~> 1.1.0) 71 | json (>= 1.8, < 3) 72 | simplecov-html (~> 0.10.0) 73 | simplecov-html (0.10.0) 74 | slop (3.6.0) 75 | thread_safe (0.3.6) 76 | tzinfo (1.2.2) 77 | thread_safe (~> 0.1) 78 | unicode-display_width (1.1.3) 79 | 80 | PLATFORMS 81 | ruby 82 | 83 | DEPENDENCIES 84 | awesome_print 85 | better_errors 86 | brakeman 87 | hash_plus (>= 1.3) 88 | oink 89 | pry 90 | pry-nav 91 | require_all 92 | rspec 93 | rubocop 94 | simplecov 95 | 96 | BUNDLED WITH 97 | 1.14.6 98 | -------------------------------------------------------------------------------- /spec/helpers/greek_calculation_shorthand_helpers.rb: -------------------------------------------------------------------------------- 1 | 2 | module Math 3 | module GreekCalculationShorthandHelpers 4 | include Math 5 | include Math::GreekCalculations 6 | 7 | def var_price_ratio_log_less_rates 8 | misc_price_ratio_log_less_rates( 9 | :stock_price => stock_price, 10 | :option_strike => option_strike, 11 | :option_expires_pct_year => option_expires_pct_year, 12 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f, 13 | :stock_dividend_rate_f => stock_dividend_rate_f 14 | ) 15 | end 16 | 17 | def var_price_vs_rate_vs_expires 18 | misc_price_vs_rate_vs_expires( 19 | :stock_price => stock_price, 20 | :option_expires_pct_year => option_expires_pct_year, 21 | :stock_dividend_rate_f => stock_dividend_rate_f 22 | ) 23 | end 24 | 25 | def var_vega 26 | iv_vega(stock_price, option_strike, option_expires_pct_year, volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, var_price_ratio_log_less_rates, var_price_vs_rate_vs_expires) 27 | end 28 | 29 | def var_vega 30 | iv_vega(stock_price, option_strike, option_expires_pct_year, Math::sqrt(option_expires_pct_year), volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, var_price_ratio_log_less_rates, var_price_vs_rate_vs_expires) 31 | end 32 | 33 | def var_option_price 34 | iv_option_price(stock_price, option_strike, option_expires_pct_year, Math::sqrt(option_expires_pct_year), volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, option_type, var_price_ratio_log_less_rates, var_price_vs_rate_vs_expires, misc_strike_vs_fed_vs_expires(:option_strike => option_strike, :option_expires_pct_year => option_expires_pct_year, :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f)) 35 | end 36 | 37 | def var_iv 38 | iv( 39 | :stock_price => stock_price, 40 | :option_strike => option_strike, 41 | :option_expires_pct_year => option_expires_pct_year, 42 | :option_expires_pct_year_sqrt => Math::sqrt(option_expires_pct_year), 43 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f, 44 | :stock_dividend_rate_f => stock_dividend_rate_f, 45 | :option_type => option_type, 46 | :option_price => option_price, 47 | :rate_vs_expires => misc_rate_vs_expires(:option_expires_pct_year => option_expires_pct_year, :stock_dividend_rate_f => stock_dividend_rate_f), 48 | :price_vs_rate_vs_expires => var_price_vs_rate_vs_expires, 49 | :strike_vs_fed_vs_expires => misc_strike_vs_fed_vs_expires(:option_strike => option_strike, :option_expires_pct_year => option_expires_pct_year, :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f), 50 | :price_ratio_log_less_rates => var_price_ratio_log_less_rates 51 | ) 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /spec/greeks/calculations/time_values_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::misc_price_ratio_log_less_rates" do 4 | include Math 5 | include Math::GreekCalculations 6 | 7 | let(:stock_price) { 10.00 } 8 | let(:stock_dividend_rate_f) { 0.00 } 9 | let(:option_expires_pct_year) { 1.00 } 10 | 11 | it "Break Even Call" do 12 | value = break_even({:option_type => :call, :option_expires_pct_year => 1.0, :option_expires_pct_year_sqrt => 1.0, :option_price => 2.0, :option_strike => 3.0, :stock_price => 4.0, :stock_dividend_rate_f => 5.0, :federal_reserve_interest_rate_f => 6.0, :iv => 7.0}) 13 | value.round(5).should === 0.000350766161827831.round(5) 14 | end 15 | 16 | it "Break Even Put" do 17 | value = break_even({:option_type => :put, :option_expires_pct_year => 1.0, :option_expires_pct_year_sqrt => 1.0, :option_price => 2.0, :option_strike => 3.0, :stock_price => 4.0, :stock_dividend_rate_f => 5.0, :federal_reserve_interest_rate_f => 6.0, :iv => 7.0}) 18 | value.round(5).should === 0.999208650294576.round(5) 19 | end 20 | 21 | context "exactly at the money" do 22 | let(:option_strike) { 10.00 } 23 | 24 | context "0% interest" do 25 | let(:federal_reserve_interest_rate_f) { 0.00 } 26 | let(:expected) { 0.00 } 27 | 28 | it { var_price_ratio_log_less_rates().should === expected } 29 | end 30 | 31 | context "0.02% interest" do 32 | let(:federal_reserve_interest_rate_f) { 0.0002 } 33 | let(:expected) { 0.0002 } 34 | 35 | it { var_price_ratio_log_less_rates().should === expected } 36 | end 37 | end 38 | 39 | context "out of the money" do 40 | let(:option_strike) { 15.00 } 41 | 42 | context "0% interest" do 43 | let(:federal_reserve_interest_rate_f) { 0.00 } 44 | let(:expected) { -0.40546510810816444 } 45 | 46 | it { var_price_ratio_log_less_rates().should === expected } 47 | end 48 | 49 | context "0.02% interest" do 50 | let(:federal_reserve_interest_rate_f) { 0.0002 } 51 | let(:expected) { -0.40526510810816446 } 52 | 53 | it { var_price_ratio_log_less_rates().should === expected } 54 | end 55 | end 56 | 57 | context "in of the money" do 58 | let(:option_strike) { 5.00 } 59 | 60 | context "0% interest" do 61 | let(:federal_reserve_interest_rate_f) { 0.00 } 62 | let(:expected) { 0.6931471805599453 } 63 | 64 | it { var_price_ratio_log_less_rates().should === expected } 65 | end 66 | 67 | context "0.02% interest" do 68 | let(:federal_reserve_interest_rate_f) { 0.0002 } 69 | let(:expected) { 0.6933471805599453 } 70 | 71 | it { var_price_ratio_log_less_rates().should === expected } 72 | end 73 | end 74 | end 75 | 76 | 77 | describe "Math::GreekCalculations::misc_price_vs_rate_vs_expires" do 78 | include Math 79 | include Math::GreekCalculations 80 | 81 | let(:stock_price) { 10.00 } 82 | let(:option_expires_pct_year) { 1.00 } 83 | let(:stock_dividend_rate_f) { 0.05 } 84 | let(:expected) { 9.51229424500714 } 85 | subject { misc_price_vs_rate_vs_expires(:stock_price => stock_price, :option_expires_pct_year => option_expires_pct_year, :stock_dividend_rate_f => stock_dividend_rate_f) } 86 | 87 | it { should === expected } 88 | end -------------------------------------------------------------------------------- /spec/greeks/calculations/iv_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe "Math::GreekCalculations::iv" do 4 | extend Math::GreekCalculations 5 | include Math::GreekCalculations 6 | 7 | ## 8 | # General behavior tests 9 | ## 10 | it { opts = {:a => :b}; expect { iv(opts) }.to raise_error ArgumentError, "Missing keys=option_price in opts={:a=>:b}" } 11 | 12 | it { iv(:option_price => nil).should be_nil } 13 | 14 | it { 15 | iv( 16 | :federal_reserve_interest_rate_f => 0.0, 17 | :stock_price => 10.00, 18 | :stock_dividend_rate_f => 0.0, 19 | :option_type => :call, 20 | :option_price => 1.0, 21 | :option_strike => 10.00, 22 | :option_expires_pct_year => 1.0, 23 | :option_expires_pct_year_sqrt => 1.0, 24 | :rate_vs_expires => 1.0, 25 | :price_vs_rate_vs_expires => 1.0, 26 | :strike_vs_fed_vs_expires => 1.0, 27 | :price_ratio_log_less_rates => 1.0, 28 | ).should === 21453795590575736000000.0 29 | } 30 | 31 | it { 32 | iv(:stock_price=>1558.86, :stock_dividend_rate_f=>0.0, :federal_reserve_interest_rate_f=>0.0, :option_type=>:put, :option_price=>0.0, :option_strike=>800.0, :option_expires_pct_year=>0.00821917808219178, :option_expires_pct_year_sqrt=>0.09065968278232492, :iv=>nil).should be_nil 33 | } 34 | 35 | it { 36 | iv( 37 | :federal_reserve_interest_rate_f => 0.0, 38 | :stock_price => 10.00, 39 | :stock_dividend_rate_f => 0.0, 40 | :option_type => :put, 41 | :option_price => 1.0, 42 | :option_strike => 10.00, 43 | :option_expires_pct_year => 1.0, 44 | :option_expires_pct_year_sqrt => 1.0, 45 | :rate_vs_expires => 1.0, 46 | :price_vs_rate_vs_expires => 1.0, 47 | :strike_vs_fed_vs_expires => 1.0, 48 | :price_ratio_log_less_rates => 1.0, 49 | ).should === 21453795590575736000000.0 50 | } 51 | 52 | 53 | ## 54 | # More specific examples 55 | ## 56 | let(:stock_price) { 10.00 } 57 | let(:stock_dividend_rate) { 0.0 } 58 | let(:stock_dividend_rate_f) { 0.0 } 59 | 60 | let(:option_strike) { 10.00 } 61 | let(:option_price) { 1.00 } 62 | let(:option_expires_in_days) { 364.0 } 63 | let(:option_expires_pct_year) { 1.0 } 64 | 65 | let(:federal_reserve_interest_rate) { 0.0 } 66 | let(:federal_reserve_interest_rate_f) { 0.00 } 67 | 68 | describe "call options" do 69 | let(:option_type) { :call } 70 | 71 | context "exactly at the money" do 72 | let(:option_strike) { 10.00 } 73 | it { var_iv().should === 0.25089263455361754 } 74 | end 75 | 76 | context "out of the money" do 77 | let(:option_strike) { 15.00 } 78 | it { var_iv().should === 0.5819996182323802 } 79 | end 80 | 81 | context "in the money" do 82 | let(:option_strike) { 5.00 } 83 | it { var_iv().should === nil } 84 | end 85 | end 86 | 87 | describe "put options" do 88 | let(:option_type) { :put } 89 | 90 | context "exactly at the money" do 91 | let(:option_strike) { 10.00 } 92 | it { var_iv().should === 0.25089263455361754 } 93 | end 94 | 95 | context "out of the money" do 96 | let(:option_strike) { 15.00 } 97 | it { var_iv().should === nil } 98 | end 99 | 100 | context "in the money" do 101 | let(:option_strike) { 5.00 } 102 | it { var_iv().should === 1.0245859277769118 } 103 | end 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /lib/greeks/calculations/iv.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | def iv(opts) 4 | opts.requires_keys_are_present(:option_price) 5 | return nil if opts[:option_price].nil? 6 | return nil if opts[:option_price] <= 0 7 | 8 | opts.requires_keys_are_not_nil(:stock_price, :option_strike, :option_expires_pct_year, :option_expires_pct_year_sqrt, :federal_reserve_interest_rate_f, :stock_dividend_rate_f, :option_type, :option_price, :rate_vs_expires, :price_vs_rate_vs_expires, :strike_vs_fed_vs_expires, :price_ratio_log_less_rates) 9 | 10 | iv_calc( 11 | opts[:stock_price], 12 | opts[:option_strike], 13 | opts[:option_expires_pct_year], 14 | opts[:option_expires_pct_year_sqrt], 15 | opts[:federal_reserve_interest_rate_f], 16 | opts[:stock_dividend_rate_f], 17 | opts[:option_type], 18 | opts[:option_price], 19 | opts[:price_vs_rate_vs_expires], 20 | opts[:price_ratio_log_less_rates], 21 | opts[:strike_vs_fed_vs_expires] 22 | ) 23 | end 24 | 25 | 26 | def iv_vega(stock_price, option_strike, option_expires_pct_year, option_expires_pct_year_sqrt, volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, price_ratio_log_less_rates, price_vs_rate_vs_expires) 27 | var_d1 = (price_ratio_log_less_rates + volatility_guess * volatility_guess * option_expires_pct_year / 2) / (volatility_guess * option_expires_pct_year_sqrt) 28 | var_nd = Math.exp(-var_d1 * var_d1 / 2) / Math::sqrt(2 * Math::PI) 29 | return price_vs_rate_vs_expires * option_expires_pct_year_sqrt * var_nd 30 | end 31 | 32 | 33 | def iv_option_price(stock_price, option_strike, option_expires_pct_year, option_expires_pct_year_sqrt, volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, option_type, price_ratio_log_less_rates, price_vs_rate_vs_expires, strike_vs_fed_vs_expires) 34 | var_d1 = (price_ratio_log_less_rates + volatility_guess * volatility_guess * option_expires_pct_year / 2) / (volatility_guess * option_expires_pct_year_sqrt) 35 | var_d2 = var_d1 - volatility_guess * option_expires_pct_year_sqrt 36 | 37 | case option_type 38 | when :call 39 | return price_vs_rate_vs_expires * normal_distribution(var_d1) - strike_vs_fed_vs_expires * normal_distribution(var_d2) 40 | when :put 41 | return strike_vs_fed_vs_expires * normal_distribution(-var_d2) - price_vs_rate_vs_expires * normal_distribution(-var_d1) 42 | else 43 | raise "Invalid option_type = #{option_type.inspect}" 44 | end 45 | end 46 | 47 | 48 | def iv_volatility_guess0(stock_price, option_strike, option_expires_pct_year, federal_reserve_interest_rate_f, stock_dividend_rate_f) 49 | Math.sqrt( 50 | (Math.log(stock_price / option_strike) + (federal_reserve_interest_rate_f - stock_dividend_rate_f) * option_expires_pct_year).abs * 2 / option_expires_pct_year) 51 | end 52 | 53 | 54 | def iv_calc(stock_price, option_strike, option_expires_pct_year, option_expires_pct_year_sqrt, federal_reserve_interest_rate_f, stock_dividend_rate_f, option_type, option_price, price_vs_rate_vs_expires, price_ratio_log_less_rates, strike_vs_fed_vs_expires) 55 | # Contstant values for the calculations 56 | price_limit = [0.005, 0.01 * option_price].min 57 | 58 | # Lambda for short-hand calculations 59 | calc_option_price = lambda { |volatility_guess| iv_option_price(stock_price, option_strike, option_expires_pct_year, option_expires_pct_year_sqrt, volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, option_type, price_ratio_log_less_rates, price_vs_rate_vs_expires, strike_vs_fed_vs_expires) } 60 | 61 | # Lambda for short-hand calculations 62 | calc_vega = lambda { |volatility_guess| iv_vega(stock_price, option_strike, option_expires_pct_year, option_expires_pct_year_sqrt, volatility_guess, federal_reserve_interest_rate_f, stock_dividend_rate_f, price_ratio_log_less_rates, price_vs_rate_vs_expires) } 63 | 64 | # Lambda for short-hand calculations 65 | calc_volatility_guess1 = lambda { |var_volatility_guess, var_option_price, var_vega| var_volatility_guess - (var_option_price - option_price) / var_vega } 66 | 67 | # Lambda for short-hand calculations 68 | is_terminal_volatility_guess = lambda { |var_option_price| ((option_price - var_option_price).abs < price_limit) } 69 | 70 | # Lambda for short-hand calculations 71 | cleanup_volatility_guess = lambda { |volatility_guess| volatility_guess.nil? || volatility_guess <= 0 ? nil : volatility_guess.to_f } 72 | 73 | var_volatility_guess = iv_volatility_guess0(stock_price, option_strike, option_expires_pct_year, federal_reserve_interest_rate_f, stock_dividend_rate_f) 74 | var_volatility_guess = 0.1 if var_volatility_guess <= 0 75 | var_option_price = calc_option_price.call(var_volatility_guess) 76 | 77 | if is_terminal_volatility_guess.call(var_option_price) 78 | return cleanup_volatility_guess.call(var_volatility_guess) 79 | end 80 | 81 | var_vega = calc_vega.call(var_volatility_guess) 82 | 83 | var_volatility_guess1 = calc_volatility_guess1.call(var_volatility_guess, var_option_price, var_vega) 84 | 85 | var_step = 1 86 | max_steps = 13 87 | while ((var_volatility_guess - var_volatility_guess1).abs > 0.0001 && var_step < max_steps) 88 | var_volatility_guess = var_volatility_guess1 89 | var_option_price = calc_option_price.call(var_volatility_guess) 90 | 91 | if is_terminal_volatility_guess.call(var_option_price) 92 | return cleanup_volatility_guess.call(var_volatility_guess) 93 | end 94 | 95 | var_vega = calc_vega.call(var_volatility_guess) 96 | 97 | var_volatility_guess1 = calc_volatility_guess1.call(var_volatility_guess, var_option_price, var_vega) 98 | if (var_volatility_guess1 < 0) 99 | return cleanup_volatility_guess.call(var_volatility_guess1) 100 | end 101 | 102 | var_step += 1 103 | end 104 | 105 | if (var_step < max_steps) 106 | return cleanup_volatility_guess.call(var_volatility_guess1) 107 | end 108 | 109 | var_option_price = calc_option_price.call(var_volatility_guess1) 110 | 111 | if is_terminal_volatility_guess.call(var_option_price) 112 | return cleanup_volatility_guess.call(var_volatility_guess1) 113 | else 114 | return nil 115 | end 116 | end 117 | 118 | end 119 | end 120 | -------------------------------------------------------------------------------- /lib/greeks/calculations/time_values.rb: -------------------------------------------------------------------------------- 1 | module Math 2 | module GreekCalculations 3 | 4 | def nil_or_gte0(value) 5 | value.nil? || value.to_f < 0.0 ? nil : value 6 | end 7 | 8 | 9 | # Intrinsic Value 10 | # The value that the option would pay if it were executed today. For example, if a stock is trading at $40, 11 | # a call on that stock with a strike price of $35 would have $5 of intrinsic value ($40-$35) if it were 12 | # exercised today. However, the call should actually be worth more than $5 to account for the value of the 13 | # chance of any further appreciation until expiration, and the difference between the price and the 14 | # intrinsic value would be the time value. 15 | def premium_value(opts) 16 | opts.requires_fields(:option_type, :option_strike, :stock_price) 17 | 18 | value = case opts[:option_type] 19 | when :call 20 | [opts[:stock_price] - opts[:option_strike], 0].max 21 | when :put 22 | [opts[:option_strike] - opts[:stock_price], 0].max 23 | else 24 | raise ArgumentError, "Invalid option_type = #{opts[:option_type]}" 25 | end 26 | 27 | nil_or_gte0(value) 28 | end 29 | 30 | 31 | # Time Value 32 | # The value of an option that captures the chance of further appreciation before expiration. 33 | # The value of an option can be broken down into intrinsic value, or the value of the option 34 | # if it were exercised today, and time value, or the added value of the option over and above 35 | # the intrinsic value. For example, if a stock is trading at $40 and a call with a strike price 36 | # of $35 were trading for $7, the call would have a $5 intrinsic value ($40-$35) and a $2 time value ($7-$5). 37 | # Time value will decay by expiration assuming the underlying security stays at the same price. 38 | def time_value(opts) 39 | return nil if opts[:option_price].nil? || opts[:option_price] < 0 40 | return nil if opts[:premium_value].nil? || opts[:premium_value] < 0 41 | 42 | nil_or_gte0(opts[:option_price] - opts[:premium_value]) 43 | end 44 | 45 | 46 | # Annualized Premium 47 | # The annualized premium is the value of the option divided by the strike price. You can use annualized 48 | # premium to develop an intuitive understanding of how much the market is "paying" for a dollar of risk. 49 | # For example, if a stock is trading at $50 and you sell a $50 strike 6 month call for $4, you are getting 50 | # paid 8% in 6 months, or about 16% annualized, in exchange for being willing to buy at $50, the current price. 51 | def annualized_premium_value(opts) 52 | return nil if opts[:option_price].nil? 53 | return nil if opts[:option_price] < 0 54 | opts.requires_fields(:option_price, :option_strike, :option_expires_pct_year) 55 | 56 | value = 100.0 * Math.log(1 + opts[:option_price] / opts[:option_strike]) / opts[:option_expires_pct_year] 57 | 58 | nil_or_gte0(value) 59 | end 60 | 61 | 62 | # Annualized Time Value 63 | # The time value of the option divided by the strike price, then annualized. You can use annualized 64 | # time value to develop an intuitive understanding of how much value the option market is adding to 65 | # an in-the-money option beyond the intrinsic value. For example, if a stock is trading at $40 and a 66 | # six month call on that stock with a strike price of $35 has an intrinsic value of $5 and a total 67 | # value of $7, the time value ($2) divided by the strike is ($2/$40) = 5%. Annualizing that time value 68 | # to a one year horizon on a continuously compounded basis yields 9.76% (2 × ln(1 + 0.05)). 69 | def annualized_time_value(opts) 70 | return nil if opts[:time_value].nil? || opts[:time_value] < 0 71 | opts.requires_fields(:option_strike, :option_expires_pct_year, :time_value) 72 | 73 | value = 100.0 * Math.log(1.0 + opts[:time_value] / opts[:option_strike]) / opts[:option_expires_pct_year] 74 | 75 | nil_or_gte0(value) 76 | end 77 | 78 | 79 | # Chance of Breakeven 80 | # The probability that a stock will be trading beyond the breakeven price as implied by the option price. 81 | # Chance of Breakeven can be used to get a sense for the valuation of the option by comparing the markets' 82 | # estimate of Chance of Breakeven to estimates derived from your own fundamental research. 83 | # If you believe the Chance of Breakeven is less than the probability that a stock will be beyond the 84 | # breakeven price at option expiration, then you believe the option is undervalued, and visa versa. 85 | def break_even(opts) 86 | opts.requires_keys_are_present(:option_price, :iv) 87 | return nil if opts[:option_price].nil? 88 | return nil if opts[:option_price] < 0 89 | return nil if opts[:iv].nil? 90 | 91 | opts.requires_keys_are_not_nil(:option_type, :option_price, :option_strike, :option_expires_pct_year, :option_expires_pct_year_sqrt, :stock_price, :stock_dividend_rate_f, :federal_reserve_interest_rate_f, :iv) 92 | 93 | part1 = (opts[:federal_reserve_interest_rate_f] - opts[:stock_dividend_rate_f] - opts[:iv] * opts[:iv] / 2) * opts[:option_expires_pct_year] 94 | part2 = opts[:iv] * opts[:option_expires_pct_year_sqrt] 95 | 96 | case opts[:option_type] 97 | when :call 98 | return normal_distribution((Math.log(opts[:stock_price] / (opts[:option_strike] + opts[:option_price])) + part1) / part2) 99 | when :put 100 | return normal_distribution(-(Math.log(opts[:stock_price] / (opts[:option_strike] - opts[:option_price])) + part1) / part2) 101 | else 102 | raise ArgumentError, "Invalid option_type = #{opts[:option_type]}" 103 | end 104 | end 105 | 106 | 107 | ##### 108 | # Misc calculations 109 | ##### 110 | 111 | 112 | def misc_price_ratio_log_less_rates(opts) 113 | opts.requires_fields(:stock_price, :option_strike, :option_expires_pct_year, :federal_reserve_interest_rate_f, :stock_dividend_rate_f) 114 | 115 | Math.log(opts[:stock_price] / opts[:option_strike]) + (opts[:federal_reserve_interest_rate_f] - opts[:stock_dividend_rate_f]) * opts[:option_expires_pct_year] 116 | end 117 | 118 | 119 | def misc_rate_vs_expires(opts) 120 | opts.requires_fields(:option_expires_pct_year, :stock_dividend_rate_f) 121 | 122 | Math.exp(opts[:option_expires_pct_year] * -opts[:stock_dividend_rate_f]) 123 | end 124 | 125 | 126 | def misc_price_vs_rate_vs_expires(opts) 127 | opts.requires_fields(:stock_price, :option_expires_pct_year, :stock_dividend_rate_f) 128 | 129 | opts[:stock_price] * misc_rate_vs_expires(opts) 130 | end 131 | 132 | 133 | def misc_strike_vs_fed_vs_expires(opts) 134 | opts.requires_fields(:option_strike, :option_expires_pct_year, :federal_reserve_interest_rate_f) 135 | 136 | opts[:option_strike] * Math.exp(opts[:option_expires_pct_year] * -opts[:federal_reserve_interest_rate_f]) 137 | end 138 | 139 | 140 | def misc_nd1(opts) 141 | opts.requires_keys_are_present(:d1) 142 | return nil if opts[:d1].nil? 143 | 144 | opts.requires_keys_are_not_nil(:d1) 145 | 146 | Math.exp(-0.5 * opts[:d1] * opts[:d1]) / Math.sqrt(2 * Math::PI) 147 | end 148 | 149 | 150 | def misc_d1(opts) 151 | opts.requires_keys_are_present(:iv) 152 | return nil if opts[:iv].nil? 153 | 154 | opts.requires_keys_are_not_nil(:price_ratio_log_less_rates, :iv, :option_expires_pct_year, :option_expires_pct_year_sqrt) 155 | 156 | (opts[:price_ratio_log_less_rates] + opts[:iv] * opts[:iv] * opts[:option_expires_pct_year] / 2) / (opts[:iv] * opts[:option_expires_pct_year_sqrt]) 157 | end 158 | 159 | 160 | def misc_d2(opts) 161 | opts.requires_keys_are_present(:iv) 162 | return nil if opts[:iv].nil? 163 | 164 | opts.requires_keys_are_not_nil(:d1, :iv, :option_expires_pct_year_sqrt) 165 | 166 | opts[:d1] - opts[:iv] * opts[:option_expires_pct_year_sqrt] 167 | end 168 | 169 | def misc_d_normal_distribution(opts) 170 | opts.requires_keys_are_present(:d_value) 171 | return nil if opts[:d_value].nil? 172 | 173 | opts.requires_keys_are_not_nil(:option_type, :d_value) 174 | 175 | multiplier = case opts[:option_type] 176 | when :call 177 | 1.0 178 | when :put 179 | -1.0 180 | else 181 | raise ArgumentError, "Invalid option_type = #{opts[:option_type]}" 182 | end 183 | 184 | normal_distribution(multiplier * opts[:d_value]) 185 | end 186 | 187 | end 188 | end -------------------------------------------------------------------------------- /spec/greeks/greeks_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path("../spec_helper.rb", File.dirname(__FILE__)) 2 | 3 | describe Math::Greeks::Calculator do 4 | # Helper method to iterate the sample data 5 | def compare_csv(days, option_type) 6 | table = CSV.table(File.join(File.dirname(__FILE__), "#{days}days.#{option_type}s.csv")) 7 | 8 | table.each do |row| 9 | # Convert to a hash 10 | row = row.to_hash 11 | 12 | # Strip empty/nil values 13 | row.each do |k,v| 14 | if v.to_s === "nil" || v.to_s.strip.empty? 15 | row[k] = nil 16 | else 17 | row[k] = row[k].to_f 18 | end 19 | end 20 | 21 | # Calculate the options 22 | row.merge!(:option_type => option_type) 23 | Math::Greeks::Calculator.new(row).should be_a_greeks_hash row 24 | end 25 | end 26 | 27 | it "compute call options @ 22 days" do 28 | skip # compare_csv(22, :call) 29 | end 30 | 31 | it "compute put options @ 22 days" do 32 | skip # compare_csv(22, :put) 33 | end 34 | 35 | it "compute call options @ 50 days" do 36 | skip # compare_csv(50, :call) 37 | end 38 | 39 | it "compute put options @ 50 days" do 40 | skip # compare_csv(50, :put) 41 | end 42 | 43 | describe 'Haliburton at 24 days' do 44 | let(:last_price) { 50.75 } 45 | let(:day_change) { 0.35 } 46 | let(:day_change_pct) { 0.69 } 47 | let(:interest_rate_assumption_pct) { 0.01 } 48 | let(:dividends_until_expiration) { 0.00 } 49 | let(:expires_in_days) { 24 } 50 | let(:expires_in_year_pct) { (option_expires_in_days + 1.0) / 365.0 } 51 | 52 | # Shared examples for a range of strike prices 53 | shared_examples 'options' do |option_type, rows| 54 | rows.each do |row| 55 | context "#{option_type.to_s} @ #{row.first} ->" do 56 | before(:each) do 57 | @opts = { 58 | stock_price: last_price, 59 | stock_dividend_rate: dividends_until_expiration / last_price, 60 | option_type: option_type, 61 | option_strike: row[0], 62 | option_price: (row[2] + row[4]) / 2.0, # Mid, 63 | option_expires_in_days: expires_in_days, 64 | federal_reserve_interest_rate: interest_rate_assumption_pct, 65 | option_volume: row[9], 66 | option_open_interest: row[10] 67 | } 68 | @greek = Math::Greeks::Calculator.new(@opts) 69 | end 70 | 71 | it 'break_even' do 72 | @greek.break_even.should nilable_equals_pct row[-2], 2 73 | end 74 | 75 | it 'premium_value' do 76 | @greek.premium_value.should strict_equals row[-5], 2 77 | end 78 | 79 | it 'time_value' do 80 | @greek.time_value.should strict_equals row[-4], 2 81 | end 82 | 83 | it 'annualized_premium_value' do 84 | @greek.annualized_premium_value.should strict_equals row[-6], 2 85 | end 86 | 87 | it 'annualized_time_value' do 88 | @greek.annualized_time_value.should strict_equals row[-3], 2 89 | end 90 | 91 | it 'iv' do 92 | @greek.iv.should nilable_equals_pct row[11], 1 93 | end 94 | end 95 | end 96 | end 97 | 98 | context '>>' do 99 | # Strike, Last Trade, Bid, Mid, Ask, Change, Change (Price), Change (IV), Change (Time), Volume, Open Interest, Implied Volatility, Delta Implied Volatility, Delta (%/%), Delta/ Theta, MOE, Strike/ Stock, Annualized Premium, Intrinsic Value, Time Value, Annualized Time Value, Chance of Breakeven, Break Even Return % 100 | @option_calls = [ 101 | [38.00,12.50,12.75,12.80,12.85,0.00,0.33,0.33,0.03,1,64,55.2,-24.7,3.9,-73.50,0.20,75,423.85,12.75,0.05,1.92,46.85,0.10], 102 | [39.00,12.25,11.75,11.80,11.85,0.00,0.32,0.33,0.03,39,39,50.8,-23.3,4.2,-75.04,0.20,77,385.93,11.75,0.05,1.87,47.06,0.10], 103 | [40.00,'N/A',10.75,10.80,10.85,0.00,0.32,0.33,0.03,0,0,46.5,-21.9,4.6,-76.76,0.20,79,348.96,10.75,0.05,1.82,47.25,0.10], 104 | [41.00,'N/A',9.75,9.80,9.85,0.00,0.32,0.33,0.03,0,0,42.3,-20.6,5.1,-78.69,0.20,81,312.91,9.75,0.05,1.78,47.44,0.10], 105 | [42.00,'N/A',8.75,8.83,8.90,0.00,0.32,0.33,0.03,0,0,40.8,-17.5,5.6,-59.81,0.31,83,278.45,8.75,0.08,2.60,47.32,0.15], 106 | [43.00,'N/A',7.80,7.85,7.90,0.00,0.31,0.32,0.03,0,0,38.6,-15.1,6.2,-49.24,0.21,85,244.81,7.75,0.10,3.39,47.21,0.20], 107 | [44.00,'N/A',6.80,6.85,6.90,0.00,0.31,0.32,0.03,0,0,34.2,-13.9,7.0,-50.74,0.21,87,211.25,6.75,0.10,3.31,47.34,0.20], 108 | [45.00,5.30,5.85,5.90,5.95,0.00,0.30,0.30,0.03,41,30,33.0,-11.1,8.0,-37.61,0.21,89,179.87,5.75,0.15,4.86,46.92,0.30], 109 | [46.00,5.60,4.95,5.00,5.05,0.00,0.29,0.29,0.03,3,5,32.4,-8.7,9.0,-26.85,0.22,91,150.65,4.75,0.25,7.91,46.01,0.49], 110 | [47.00,3.75,4.05,4.10,4.15,0.00,0.28,0.27,0.03,10,10,30.5,-7.1,10.4,-21.78,0.23,93,122.11,3.75,0.35,10.83,44.99,0.69], 111 | [48.00,3.10,3.20,3.25,3.30,0.00,0.26,0.24,0.03,324,209,29.0,-5.4,12.2,-17.38,0.25,95,95.65,2.75,0.50,15.13,43.36,0.99], 112 | [49.00,2.30,2.47,2.49,2.50,0.00,0.23,0.21,0.03,58,185,27.8,-4.3,14.3,-13.79,0.08,97,72.23,1.75,0.74,21.74,40.74,1.45], 113 | [50.00,1.66,1.81,1.83,1.84,0.00,0.20,0.17,0.03,24,559,27.0,-3.3,16.6,-10.93,0.10,99,52.34,0.75,1.08,31.06,36.99,2.12], 114 | [51.00,1.21,1.28,1.29,1.29,0.00,0.17,0.14,0.03,128,300,26.5,-2.6,19.2,-8.78,0.04,100,36.33,0.00,1.29,36.33,32.12,3.02], 115 | [52.00,0.81,0.86,0.87,0.88,0.00,0.13,0.10,0.03,115,559,26.2,-2.0,21.8,-7.19,0.11,102,24.22,0.00,0.87,24.22,26.43,4.18], 116 | [53.00,0.56,0.57,0.58,0.58,0.00,0.10,0.07,0.02,7,330,26.4,-1.6,24.4,-5.98,0.07,104,15.75,0.00,0.58,15.75,20.64,5.57], 117 | [54.00,0.33,0.36,0.37,0.38,0.00,0.07,0.05,0.02,25,33,26.6,-1.3,26.8,-5.09,0.20,106,9.97,0.00,0.37,9.97,15.25,7.13], 118 | [55.00,0.20,0.23,0.24,0.24,0.00,0.05,0.03,0.01,11,160,26.9,-1.1,29.0,-4.40,0.15,108,6.22,0.00,0.24,6.22,10.82,8.84], 119 | [56.00,0.21,0.14,0.15,0.16,0.00,0.03,0.02,0.01,1,21,27.5,-0.9,30.8,-3.87,0.43,110,3.91,0.00,0.15,3.91,7.45,10.64], 120 | [57.00,0.14,0.09,0.10,0.11,0.00,0.02,0.01,0.01,5,22,28.3,-0.8,32.0,-3.43,0.62,112,2.56,0.00,0.10,2.56,5.18,12.51], 121 | [58.00,0.11,0.06,0.07,0.08,0.00,0.02,0.01,0.01,11,11,29.4,-0.7,32.5,-3.08,0.88,114,1.76,0.00,0.07,1.76,3.68,14.42], 122 | [59.00,0.09,0.04,0.05,0.06,0.00,0.01,0.01,0.01,14,18,30.5,-0.6,32.9,-2.80,1.22,116,1.24,0.00,0.05,1.24,2.64,16.35], 123 | [60.00,0.06,0.02,0.03,0.04,0.00,0.01,0.00,0.00,4,34,30.7,-0.5,34.9,-2.58,1.91,118,0.73,0.00,0.03,0.73,1.67,18.29], 124 | [61.00,'N/A',0.01,0.03,0.04,0.00,0.01,0.00,0.00,0,0,32.4,-0.4,33.8,-2.37,3.55,120,0.60,0.00,0.03,0.60,1.33,20.25] 125 | ] 126 | 127 | it_behaves_like 'options', :call, @option_calls 128 | end 129 | 130 | context '>>' do 131 | @option_puts = [ 132 | [38.00,0.04,0.03,0.04,0.05,0.00,0.01,0.01,0.00,10,0,52.9,2.1,-19.5,1.44,2.57,75,1.54,0.00,0.04,1.54,2.12,-25.20], 133 | # [39.00,0.09,0.04,0.05,0.06,0.00,nil,nil,nil,370,333,nil,nil,nil,nil,nil,77,nil,0.00,nil,nil,nil,nil], 134 | [40.00,0.09,0.04,0.05,0.06,0.00,0.01,0.02,0.01,10,12,46.2,2.0,-21.5,1.72,1.86,79,1.82,0.00,0.05,1.82,2.74,-21.28], 135 | [41.00,0.07,0.05,0.06,0.07,0.00,0.01,0.02,0.01,7,48,43.3,2.0,-22.3,1.90,1.50,81,2.14,0.00,0.06,2.14,3.31,-19.33], 136 | [42.00,0.08,0.06,0.07,0.08,0.00,0.01,0.02,0.01,39,144,40.3,1.9,-23.4,2.12,1.22,83,2.43,0.00,0.07,2.43,3.92,-17.38], 137 | [43.00,0.10,0.08,0.09,0.10,0.00,0.01,0.03,0.01,59,117,37.9,2.0,-24.0,2.37,0.93,85,3.05,0.00,0.09,3.05,5.01,-15.45], 138 | [44.00,0.11,0.11,0.12,0.12,0.00,0.02,0.03,0.01,16,41,35.3,2.0,-24.6,2.68,0.35,87,3.81,0.00,0.12,3.81,6.33,-13.53], 139 | [45.00,0.16,0.15,0.16,0.16,0.00,0.03,0.04,0.01,10,20,33.1,2.0,-24.9,3.07,0.26,89,5.02,0.00,0.16,5.02,8.28,-11.64], 140 | [46.00,0.21,0.21,0.22,0.23,0.00,0.04,0.06,0.01,15,28,31.3,2.1,-24.7,3.55,0.37,91,6.97,0.00,0.22,6.97,11.14,-9.79], 141 | [47.00,0.34,0.31,0.32,0.33,0.00,0.05,0.08,0.02,1,235,29.6,2.3,-24.0,4.17,0.26,93,9.91,0.00,0.32,9.91,14.90,-8.02], 142 | [48.00,0.56,0.47,0.48,0.49,0.00,0.07,0.11,0.02,38,80,28.5,2.5,-22.9,4.95,0.18,95,14.53,0.00,0.48,14.53,19.90,-6.36], 143 | [49.00,0.75,0.70,0.71,0.72,0.00,0.11,0.14,0.02,13,360,27.2,2.8,-21.3,6.04,0.13,97,21.00,0.00,0.71,21.00,25.40,-4.85], 144 | [50.00,1.23,1.04,1.05,1.06,0.00,0.14,0.17,0.02,654,527,26.5,3.3,-19.4,7.49,0.10,99,30.34,0.00,1.05,30.34,31.34,-3.55], 145 | [51.00,1.58,1.50,1.51,1.52,0.00,0.19,0.21,0.02,72,506,26.0,4.0,-17.3,9.49,0.08,100,42.60,0.25,1.26,35.63,36.87,-2.48], 146 | [52.00,2.18,2.09,2.10,2.11,0.00,0.24,0.25,0.02,34,134,25.9,5.2,-15.2,12.26,0.06,102,57.80,1.25,0.85,23.67,41.45,-1.67], 147 | [53.00,3.10,2.78,2.81,2.83,0.00,0.29,0.28,0.01,1,32,25.9,7.4,-13.2,16.13,0.14,104,75.29,2.25,0.56,15.21,44.90,-1.09], 148 | [54.00,4.05,3.55,3.60,3.65,0.00,0.35,0.31,0.00,6,82,26.0,16.1,-11.4,21.92,0.24,106,94.23,3.25,0.35,9.43,47.30,-0.69], 149 | [55.00,4.50,4.40,4.45,4.50,0.00,nil,nil,nil,34,35,25.7,nil,-10.0,32.10,0.22,108,113.59,4.25,0.20,5.30,49.00,-0.39], 150 | [56.00,5.70,5.30,5.38,5.45,0.00,nil,nil,nil,4,33,26.5,nil,-8.7,43.23,0.32,110,133.81,5.25,0.13,3.26,49.96,-0.25], 151 | [57.00,6.20,6.25,6.33,6.40,0.00,nil,nil,nil,44,44,26.7,nil,-7.6,63.70,0.31,112,153.63,6.25,0.08,1.92,50.55,-0.15], 152 | [58.00,'N/A',7.25,7.30,7.35,0.00,nil,nil,nil,0,0,27.8,nil,-6.7,83.53,0.20,114,173.08,7.25,0.05,1.26,50.91,-0.10], 153 | [59.00,'N/A',8.25,8.30,8.35,0.00,nil,nil,nil,0,0,30.7,nil,-5.9,80.81,0.20,116,192.17,8.25,0.05,1.24,51.11,-0.10], 154 | [60.00,'N/A',9.20,9.28,9.35,0.00,nil,nil,nil,0,0,30.0,nil,-5.4,140.41,0.30,118,209.86,9.25,0.03,0.61,51.31,-0.05], 155 | [61.00,11.40,10.20,10.28,10.35,0.00,nil,nil,nil,23,23,32.5,nil,-4.9,137.37,0.30,120,227.28,10.25,0.03,0.60,51.46,-0.05] 156 | ] 157 | 158 | it_behaves_like 'options', :put, @option_puts 159 | end 160 | 161 | end 162 | end -------------------------------------------------------------------------------- /spec/ed.csv: -------------------------------------------------------------------------------- 1 | ED,Consolidated Edison 2 | Last Price:,$59.93 3 | 4 | 5 | 6 | Expiration Days,21 7 | Interest Rate Assumption,0.02% 8 | Dividends Until Expiration,$0.00 9 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 10 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 11 | 7.9,8.8,9.45,10.1,10,15,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,268.97,9.93,N/A,N/A,N/A,-1.89,50,0.03,0,0.03,0.05,20,436,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A, 12 | 4.9,6.4,6.95,7.5,2,5,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,190.84,7.43,N/A,N/A,N/A,-1.72,52.5,0.2,0,0.05,0.1,525,1181,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,-12.4 13 | 4.93,4,4.5,5,10,31,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,116.48,4.93,N/A,N/A,N/A,-1.55,55,0.05,0.05,0.08,0.1,1,1177,0,20.3,-48.6,-43,5.22,-2.99,-11.85,4.1,1.51,0,0.05,1.51,4.34,-8.31 14 | 1.8,2.4,2.48,2.55,6,586,-1,N/A,N/A,N/A,N/A,N/A,N/A,N/A,67.84,2.43,N/A,N/A,N/A,-0.05,57.5,0.29,0.2,0.23,0.25,34,806,66,16.8,-45.8,-37.5,2.92,-2.82,-6.63,6.91,5.76,0,0.2,5.76,14.28,-4.39 15 | 0.45,0.55,0.6,0.65,11,2480,9,9.9,53,33.6,1.06,3.13,-2.41,-21.94,15.14,0,0.55,15.14,33.24,1.03,60,1.35,1.1,1.15,1.2,8,507,0,18.1,-27.3,-17.9,0.97,-1.71,-2.2,12.43,30.14,0.07,1.03,28.24,35.67,-1.72 16 | 0.05,0,0.05,0.1,201,982,145,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,4.29,62.5,3.5,3.1,3.55,4,12,56,0,24.6,-14.4,-7.1,0.37,-0.93,-0.85,16.99,80.32,2.57,0.53,14.01,45.35,-0.88 17 | 0.05,0,0.03,0.05,104,388,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A,N/A,65,3.35,5.6,6.1,6.6,5,3,0,35.9,-8.7,-3.8,0.26,-0.58,-0.58,14.9,137.11,5.07,0.53,13.47,47.73,-0.88 18 | 0.01,0,0.03,0.05,1,1,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A,N/A,70,10.35,9.8,11,12.2,3,5,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,217.39,10.07,N/A,N/A,N/A,0.45 19 | 20 | 21 | 22 | Expiration Days,56 23 | Interest Rate Assumption,0.02% 24 | Dividends Until Expiration,$0.00 25 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 26 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 27 | N/A,9,9.5,10,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,105.99,9.93,N/A,N/A,N/A,-1.55,50,N/A,0,0.05,0.1,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,-16.57 28 | N/A,6.5,7,7.5,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,74.74,7.43,N/A,N/A,N/A,-1.55,52.5,N/A,0.05,0.1,0.15,0,0,0,18.1,-35.3,-31.8,5.74,-5.67,-5.04,7.02,0.61,0,0.05,0.61,3.36,-12.48 29 | N/A,4,4.55,5.1,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,44.96,4.93,N/A,N/A,N/A,-1.55,55,0.3,0.2,0.23,0.25,8,27,22,17.4,-30,-25.5,3.63,-4.84,-3.18,9.44,2.32,0,0.2,2.32,10.3,-8.56 30 | 2.2,2.55,2.63,2.7,2,21,10,8.8,20.8,6.3,0.16,3.09,-0.14,-147.77,27.79,2.43,0.12,1.33,47.07,0.2,57.5,0.7,0.55,0.6,0.65,86,110,80,15.7,-26.5,-20.7,2.12,-4.29,-1.86,14.24,6.1,0,0.55,6.1,21.5,-4.97 31 | 0.7,0.85,0.93,1,3,246,3,9.3,34.9,21.8,1.04,5.3,-0.91,-38.22,9.01,0,0.85,9.01,33.36,1.54,60,1.68,1.55,1.58,1.6,17,106,16,16,-19.1,-12.7,0.98,-3.14,-0.86,22.33,16.33,0.07,1.48,15.6,35.81,-2.47 32 | 0.25,0.15,0.2,0.25,16,18,0,9.5,54,43,3.25,8.27,-2.85,-18.93,1.54,0,0.15,1.54,11.43,4.54,62.5,N/A,3.3,3.4,3.5,0,0,N/A,17.8,-12.9,-6.8,0.44,-2.18,-0.38,33.83,32.95,2.57,0.73,7.44,44.47,-1.22 33 | N/A,0,0.05,0.1,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,8.46,65,N/A,5.6,6.15,6.7,0,0,0,22.3,-8.7,-3.8,0.26,-1.51,-0.22,38.6,52.92,5.07,0.53,5.2,47.73,-0.88 34 | N/A,0,0.03,0.05,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A,N/A,67.5,N/A,8.1,8.65,9.2,0,0,N/A,28.5,-6.2,-2.6,0.2,-1.13,-0.18,35.4,72.57,7.57,0.53,5.01,49.08,-0.88 35 | N/A,0,0.03,0.05,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A,N/A,70,N/A,9.9,11.4,12.9,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,84.71,10.07,N/A,N/A,N/A,0.28 36 | 37 | 38 | 39 | Expiration Days,112 40 | Interest Rate Assumption,0.04% 41 | Dividends Until Expiration,$0.62 42 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 43 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 44 | 8.1,9,9.5,10,20,20,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,53.46,9.93,N/A,N/A,N/A,-1.55,50,0.2,0.15,0.18,0.2,8,145,0,19.2,-21.3,-19,4.61,-6.89,-2.33,9.14,0.97,0,0.15,0.97,6.33,-16.82 45 | N/A,6.5,7,7.5,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,37.7,7.43,N/A,N/A,N/A,-1.55,52.5,0.32,0.3,0.33,0.35,3,309,3,17.5,-20.7,-17.8,3.48,-6.72,-1.82,11.36,1.84,0,0.3,1.84,11.24,-12.9 46 | 3.3,4.2,4.65,5.1,7,47,0,10.5,12.5,3.6,0.15,3.57,0.1,122.16,23.77,4.93,N/A,N/A,46.71,-1.22,55,0.65,0.6,0.68,0.75,148,850,0,15.8,-19.6,-16,2.41,-6.37,-1.33,14.67,3.5,0,0.6,3.5,18.88,-9.23 47 | 2.59,2.85,2.93,3,50,157,1,15.5,13.1,6.9,0.67,3.76,-0.12,-111.65,15.63,2.43,0.42,2.35,38.11,0.7,57.5,1.6,1.25,1.3,1.35,10,482,0,14.8,-17,-12.6,1.46,-5.58,-0.88,19.44,6.95,0,1.25,6.95,29.4,-6.14 48 | 1.35,1.35,1.4,1.45,10,1111,20,13.6,18.7,12.1,1.3,5.49,-0.32,-58.39,7.19,0,1.35,7.19,29.13,2.37,60,2.65,2.4,2.48,2.55,10,367,0,14.1,-14,-8.8,0.76,-4.63,-0.53,26.53,12.67,0.07,2.33,12.31,39.38,-3.89 49 | 0.5,0.5,0.55,0.6,6,1652,0,12.6,25.7,19.2,2.44,7.65,-0.73,-35.1,2.57,0,0.5,2.57,16.77,5.12,62.5,4.2,4.1,4.2,4.3,10,21,0,13.8,-10.9,-5.3,0.34,-3.7,-0.3,36.38,20.52,2.57,1.53,7.81,46.1,-2.55 50 | 0.15,0.1,0.15,0.2,2,156,0,11.2,37.9,31.4,4.61,11.41,-1.52,-24.83,0.5,0,0.1,0.5,5.39,8.63,65,6.15,6.3,6.8,7.3,2,4,0,15,-8.1,-3,0.17,-2.82,-0.18,43.99,29.88,5.07,1.23,6.06,49.1,-2.05 51 | 0.05,0,0.05,0.1,15,716,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,12.63,67.5,N/A,8.7,9.2,9.7,0,11,0,17.2,-6.2,-1.8,0.1,-2.23,-0.13,47.84,39.16,7.57,1.13,5.36,50.37,-1.89 52 | N/A,0,0.03,0.05,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,N/A,N/A,N/A,N/A,70,N/A,11.1,11.7,12.3,0,0,0,18,-5.1,-1.1,0.05,-1.87,-0.09,54.45,47.54,10.07,1.03,4.72,51.22,-1.72 53 | 54 | 55 | 56 | Expiration Days,175 57 | Interest Rate Assumption,0.07% 58 | Dividends Until Expiration,$0.62 59 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 60 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 61 | 8.11,9,9.5,10,4,9,0,20,5.8,1.6,0.18,2.29,0.03,203.61,34.33,9.93,N/A,N/A,44.9,-1.55,50,0.48,0.35,0.4,0.45,30,1001,0,18.2,-16,-14,3.6,-8.21,-1.24,12.92,1.45,0,0.35,1.45,10.85,-17.15 62 | 5.6,6.6,7.1,7.6,1,3,0,16.5,7.5,2.5,0.24,3.12,0.03,234.43,24.56,7.43,N/A,N/A,44.3,-1.38,52.5,0.6,0.6,0.65,0.7,5,952,0,16.7,-15.6,-13.1,2.74,-7.99,-0.99,15.73,2.36,0,0.6,2.36,16.37,-13.4 63 | 5.53,4.9,5.1,5.3,2,139,0,17.8,8.5,3.9,0.5,3.63,-0.03,-312.11,17.7,4.93,N/A,N/A,40.12,-0.05,55,1.06,1,1.05,1.1,21,2162,0,15,-15.1,-12,1.97,-7.77,-0.76,19.8,3.74,0,1,3.74,23.57,-9.89 64 | 3,3.1,3.2,3.3,2,1464,0,15.9,11,6,0.81,4.84,-0.08,-134.57,10.89,2.43,0.67,2.4,35.54,1.12,57.5,2.05,1.75,1.8,1.85,3,881,0,13.9,-13.7,-9.9,1.25,-7.07,-0.54,25.3,6.22,0,1.75,6.22,32.45,-6.97 65 | 1.6,1.7,1.78,1.85,7,6054,3,14.4,14.5,9.3,1.35,6.5,-0.19,-77.54,5.79,0,1.7,5.79,28.15,2.95,60,2.95,2.9,2.95,3,9,1802,0,12.7,-12,-7.4,0.69,-6.27,-0.36,33.57,9.79,0.07,2.83,9.56,40.69,-4.72 66 | 0.75,0.8,0.85,0.9,19,1210,0,13.5,18.7,13.4,2.2,8.54,-0.37,-50.27,2.64,0,0.8,2.64,18.79,5.62,62.5,4.2,4.5,4.6,4.7,169,296,0,11.2,-10.3,-4.7,0.29,-5.43,-0.22,46.35,14.42,2.57,1.93,6.31,46.98,-3.22 67 | 0.4,0.3,0.35,0.4,3,2023,0,12.6,24.1,18.9,3.48,11.13,-0.66,-36.35,0.95,0,0.3,0.95,9.72,8.96,65,9.6,6.5,7,7.5,11,927,0,7.5,-8.8,-1.1,0.03,-4.72,-0.13,69.77,19.77,5.07,1.43,4.51,50.77,-2.39 68 | 0.15,0.1,0.15,0.2,4,417,0,12.2,29.3,24.3,5.12,13.66,-1.06,-27.73,0.31,0,0.1,0.31,4.04,12.8,67.5,6,8.8,9.3,9.8,2,116,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,25.41,7.57,1.23,3.75,N/A,-2.05 69 | 0.05,0,0.05,0.1,1,210,-1,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,16.8,70,9.68,11.2,11.7,12.2,6,151,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,30.78,10.07,1.13,3.32,N/A,-1.89 70 | 71 | 72 | 73 | Expiration Days,210 74 | Interest Rate Assumption,0.08% 75 | Dividends Until Expiration,$1.23 76 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 77 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 78 | N/A,9,9.5,10,0,0,0,20.8,5.5,1.7,0.24,2.61,0.02,296.53,28.63,9.93,N/A,N/A,43.63,-1.55,50,0.55,0.5,0.55,0.6,6,49,0,18.1,-13.9,-12.1,3.2,-8.62,-0.95,14.72,1.72,0,0.5,1.72,13.29,-17.4 79 | 5.4,6.7,7.15,7.6,20,20,0,17.8,6.9,2.6,0.33,3.43,0.02,459.92,20.78,7.43,N/A,N/A,42.56,-1.22,52.5,0.95,0.85,0.9,0.95,14,46,0,17,-13.2,-11,2.42,-8.2,-0.75,17.55,2.78,0,0.85,2.78,19.31,-13.82 80 | 3.21,5.1,5.2,5.3,2,22,0,18.8,7.8,3.7,0.58,3.92,-0.03,-239.69,15.34,4.93,0.17,0.53,38.56,0.28,55,2.05,1.4,1.45,1.5,2,89,0,15.9,-12.3,-9.7,1.73,-7.69,-0.58,21.35,4.35,0,1.4,4.35,26.46,-10.56 81 | 2.2,3.3,3.35,3.4,84,109,0,16.6,10,5.5,0.88,5.19,-0.07,-137.14,9.65,2.43,0.87,2.6,34.35,1.45,57.5,2.35,2.25,2.3,2.35,8,11,0,14.9,-11.2,-8,1.15,-7.04,-0.42,26.42,6.64,0,2.25,6.64,34.06,-7.81 82 | 1.85,1.9,1.95,2,2,59,0,15,12.9,8.2,1.36,6.85,-0.15,-85.87,5.39,0,1.9,5.39,27.74,3.29,60,3.55,3.4,3.55,3.7,5,5,0,13.5,-10.2,-6.4,0.68,-6.45,-0.3,34.01,9.53,0.07,3.33,9.34,41,-5.56 83 | 1.08,0.95,1,1.05,5,38,0,13.8,16.5,11.7,2.13,8.93,-0.28,-58.48,2.61,0,0.95,2.61,19.33,5.87,62.5,N/A,5.1,5.2,5.3,0,0,0,13.1,-8.5,-4.3,0.37,-5.49,-0.2,42.16,13.57,2.57,2.53,6.86,46.15,-4.22 84 | 0.43,0.4,0.48,0.55,6,29,6,12.9,20.8,16.1,3.23,11.44,-0.48,-43,1.06,0,0.4,1.06,10.97,9.13,65,N/A,7.1,7.5,7.9,0,0,0,12.4,-7.1,-2.6,0.17,-4.69,-0.14,52.67,17.93,5.07,2.03,5.32,49.36,-3.39 85 | N/A,0.15,0.2,0.25,0,0,0,12.4,25.2,20.7,4.64,13.99,-0.76,-33.18,0.38,0,0.15,0.38,5.13,12.88,67.5,N/A,9.4,9.5,9.6,0,0,0,12.4,-5.8,-1.4,0.07,-3.93,-0.1,60.57,22.55,7.57,1.83,4.63,50.82,-3.05 86 | N/A,0,0.08,0.15,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,0,0,0,0,N/A,16.8,70,N/A,11.7,12,12.3,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,26.74,10.07,1.63,3.98,N/A,-2.72 87 | 88 | 89 | 90 | Expiration Days,539 91 | Interest Rate Assumption,0.21% 92 | Dividends Until Expiration,$3.08 93 | Calls,,,,,,,,,,,,,,,,,,,,,Puts,,,,,,,,,,,,,,,,,,, 94 | Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return %,Strike,Last Trade,Bid,Mid,Ask,Volume,Open Interest,Open Interest Delta,Implied Volatility,Delta(%/%),Gamma(pp/pp),Vega(%/pp),Rho(%/pp),Theta(%/day),Delta/Theta,Annualized Premium,Intrinsic Value,Time Value,Annualized Time Value,Chance of Breakeven,Break Even Return % 95 | 6.9,9.5,9.8,10.1,3,4,0,24.2,4.1,1.7,0.6,4.58,0,-3345.41,11.76,9.93,N/A,N/A,35.8,-0.72,50,2.1,2.1,2.15,2.2,10,1102,0,17.3,-7,-5.9,1.82,-11.85,-0.26,26.93,2.78,0,2.1,2.78,26.64,-20.07 96 | 8.2,7.7,7.8,7.9,8,148,0,22.6,4.6,2.1,0.74,5.37,-0.01,-636.9,9.25,7.43,0.27,0.35,34.01,0.45,52.5,3.1,2.8,2.88,2.95,40,204,0,16.3,-6.8,-5.4,1.44,-11.51,-0.22,30.53,3.51,0,2.8,3.51,31.26,-17.07 97 | 5.73,5.9,6,6.1,10,223,0,20.5,5.4,2.7,0.92,6.52,-0.01,-393,6.89,4.93,0.97,1.18,31.78,1.62,55,3.61,3.7,3.8,3.9,12,286,0,15.3,-6.5,-4.9,1.1,-11.08,-0.19,34.76,4.4,0,3.7,4.4,35.91,-14.4 98 | 4.61,4.4,4.5,4.6,6,171,0,19,6.3,3.5,1.17,7.78,-0.03,-250,4.98,2.43,1.97,2.28,28.68,3.29,57.5,5.15,4.9,5,5.1,1,390,0,14.6,-6,-4.2,0.8,-10.4,-0.15,39.34,5.53,0,4.9,5.53,40.34,-12.23 99 | 2.87,3.2,3.25,3.3,5,396,0,17.9,7.2,4.3,1.48,9.13,-0.04,-171.31,3.51,0,3.2,3.51,24.88,5.46,60,6.24,6.2,6.3,6.4,1,102,0,13.4,-5.8,-3.6,0.55,-9.99,-0.13,45.71,6.65,0.07,6.13,6.58,44.26,-10.23 100 | 2.21,2.2,2.25,2.3,2,548,0,16.9,8.3,5.4,1.87,10.76,-0.06,-129.09,2.34,0,2.2,2.34,20.56,7.96,62.5,9.9,7.9,8,8.1,3,25,0,12.8,-5.2,-2.8,0.35,-9.21,-0.1,51.79,8.05,2.57,5.33,5.53,47.42,-8.89 101 | 1.72,1.5,1.55,1.6,10,554,0,16.3,9.3,6.4,2.34,12.3,-0.09,-99.88,1.54,0,1.5,1.54,16.25,10.96,65,9.6,9.7,9.8,9.9,6,125,0,11.3,-4.9,-2,0.18,-8.71,-0.08,60.67,9.4,5.07,4.63,4.65,49.99,-7.73 102 | 1.28,0.95,1.03,1.1,1,40,0,15.5,10.6,7.7,2.91,14.22,-0.13,-81.72,0.94,0,0.95,0.94,12.02,14.22,67.5,11.3,11.7,11.8,11.9,3,18,0,8.1,-4.6,-0.7,0.03,-8.31,-0.06,73.19,10.8,7.57,4.13,4.01,51.8,-6.89 103 | 1.1,0.6,0.68,0.75,56,56,0,15.1,11.8,8.9,3.56,16,-0.17,-68.11,0.58,0,0.6,0.58,8.55,17.8,70,0,13.8,14.25,14.7,0,0,0,N/A,N/A,N/A,N/A,N/A,N/A,N/A,12.16,10.07,3.73,3.51,N/A,-6.22 -------------------------------------------------------------------------------- /lib/greeks.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'hash_plus' 3 | 4 | require_relative 'greeks/calculations/delta' 5 | require_relative 'greeks/calculations/gamma' 6 | require_relative 'greeks/calculations/iv' 7 | require_relative 'greeks/calculations/normal_distribution' 8 | require_relative 'greeks/calculations/theta' 9 | require_relative 'greeks/calculations/rho' 10 | require_relative 'greeks/calculations/vega' 11 | require_relative 'greeks/calculations/time_values' 12 | 13 | 14 | module Math 15 | module Greeks 16 | class Calculator 17 | class GreekCalculations 18 | extend Math::GreekCalculations 19 | end 20 | 21 | attr_reader :stock_price 22 | attr_reader :stock_dividend_rate 23 | attr_reader :option_type # :call, or :put 24 | attr_reader :option_price # bid, mid, or ask 25 | attr_reader :option_strike 26 | attr_reader :option_expires_in_days 27 | attr_reader :federal_reserve_interest_rate 28 | 29 | attr_reader :option_expires_pct_year 30 | attr_reader :option_expires_pct_year_sqrt 31 | attr_reader :stock_dividend_rate_f 32 | attr_reader :federal_reserve_interest_rate_f 33 | attr_reader :rate_vs_expires 34 | attr_reader :price_vs_rate_vs_expires 35 | attr_reader :strike_vs_fed_vs_expires 36 | attr_reader :price_ratio_log_less_rates 37 | 38 | # Optional fields 39 | attr_reader :option_volume 40 | attr_reader :option_open_interest 41 | 42 | 43 | def initialize(opts) 44 | @stock_price = opts[:stock_price] 45 | @stock_dividend_rate = opts[:stock_dividend_rate] 46 | @option_type = opts[:option_type] 47 | @option_price = opts[:option_price] 48 | @option_strike = opts[:option_strike] 49 | @option_expires_in_days = opts[:option_expires_in_days] 50 | @federal_reserve_interest_rate = opts[:federal_reserve_interest_rate] 51 | 52 | @federal_reserve_interest_rate_f = federal_reserve_interest_rate / 100.0 53 | @stock_dividend_rate_f = stock_dividend_rate / 100.0 54 | @option_expires_pct_year = (option_expires_in_days + 1.0) / 365.0 55 | @option_expires_pct_year_sqrt = Math.sqrt(option_expires_pct_year) 56 | 57 | @option_volume = opts[:option_volume] 58 | @option_open_interest = opts[:option_open_interest] 59 | 60 | 61 | @price_vs_rate_vs_expires = GreekCalculations.misc_price_vs_rate_vs_expires( 62 | :stock_price => stock_price, 63 | :stock_dividend_rate_f => stock_dividend_rate_f, 64 | :option_expires_pct_year => option_expires_pct_year 65 | ) 66 | 67 | @rate_vs_expires = GreekCalculations.misc_rate_vs_expires( 68 | :option_expires_pct_year => option_expires_pct_year, 69 | :stock_dividend_rate_f => stock_dividend_rate_f 70 | ) 71 | 72 | @strike_vs_fed_vs_expires = GreekCalculations.misc_strike_vs_fed_vs_expires( 73 | :option_strike => option_strike, 74 | :option_expires_pct_year => option_expires_pct_year, 75 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f 76 | ) 77 | 78 | @price_ratio_log_less_rates = GreekCalculations.misc_price_ratio_log_less_rates( 79 | :stock_price => stock_price, 80 | :stock_dividend_rate_f => stock_dividend_rate_f, 81 | :option_strike => option_strike, 82 | :option_expires_pct_year => option_expires_pct_year, 83 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f 84 | ) 85 | end 86 | 87 | 88 | # Chance of Breakeven 89 | # The probability that a stock will be trading beyond the breakeven price as implied by the option price. 90 | # Chance of Breakeven can be used to get a sense for the valuation of the option by comparing the markets' 91 | # estimate of Chance of Breakeven to estimates derived from your own fundamental research. 92 | # If you believe the Chance of Breakeven is less than the probability that a stock will be beyond the 93 | # breakeven price at option expiration, then you believe the option is undervalued, and visa versa. 94 | def break_even 95 | @break_even ||= GreekCalculations.break_even( 96 | :stock_price => stock_price, 97 | :stock_dividend_rate_f => stock_dividend_rate_f, 98 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f, 99 | :option_type => option_type, 100 | :option_price => option_price, 101 | :option_strike => option_strike, 102 | :option_expires_pct_year => option_expires_pct_year, 103 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 104 | :iv => iv 105 | ) 106 | end 107 | 108 | 109 | # Intrinsic Value 110 | # The value that the option would pay if it were executed today. For example, if a stock is trading at $40, 111 | # a call on that stock with a strike price of $35 would have $5 of intrinsic value ($40-$35) if it were 112 | # exercised today. However, the call should actually be worth more than $5 to account for the value of the 113 | # chance of any further appreciation until expiration, and the difference between the price and the 114 | # intrinsic value would be the time value. 115 | def premium_value 116 | @premium_value ||= GreekCalculations.premium_value( 117 | :option_type => option_type, 118 | :option_strike => option_strike, 119 | :stock_price => stock_price 120 | ) 121 | end 122 | 123 | 124 | # Time Value 125 | # The value of an option that captures the chance of further appreciation before expiration. 126 | # The value of an option can be broken down into intrinsic value, or the value of the option 127 | # if it were exercised today, and time value, or the added value of the option over and above 128 | # the intrinsic value. For example, if a stock is trading at $40 and a call with a strike price 129 | # of $35 were trading for $7, the call would have a $5 intrinsic value ($40-$35) and a $2 time value ($7-$5). 130 | # Time value will decay by expiration assuming the underlying security stays at the same price. 131 | def time_value 132 | @time_value ||= GreekCalculations.time_value( 133 | :option_price => option_price, 134 | :premium_value => premium_value 135 | ) 136 | end 137 | 138 | 139 | # Annualized Premium 140 | # The annualized premium is the value of the option divided by the strike price. You can use annualized 141 | # premium to develop an intuitive understanding of how much the market is "paying" for a dollar of risk. 142 | # For example, if a stock is trading at $50 and you sell a $50 strike 6 month call for $4, you are getting 143 | # paid 8% in 6 months, or about 16% annualized, in exchange for being willing to buy at $50, the current price. 144 | def annualized_premium_value 145 | @annualized_premium_value ||= GreekCalculations.annualized_premium_value( 146 | :option_price => option_price, 147 | :option_strike => option_strike, 148 | :option_expires_pct_year => option_expires_pct_year 149 | ) 150 | end 151 | 152 | 153 | # Annualized Time Value 154 | # The time value of the option divided by the strike price, then annualized. You can use annualized 155 | # time value to develop an intuitive understanding of how much value the option market is adding to 156 | # an in-the-money option beyond the intrinsic value. For example, if a stock is trading at $40 and a 157 | # six month call on that stock with a strike price of $35 has an intrinsic value of $5 and a total 158 | # value of $7, the time value ($2) divided by the strike is ($2/$40) = 5%. Annualizing that time value 159 | # to a one year horizon on a continuously compounded basis yields 9.76% (2 × ln(1 + 0.05)). 160 | def annualized_time_value 161 | @annualized_time_value ||= GreekCalculations.annualized_time_value( 162 | :time_value => time_value, 163 | :option_strike => option_strike, 164 | :option_expires_pct_year => option_expires_pct_year 165 | ) 166 | end 167 | 168 | 169 | # Implied Volatility 170 | # A measure of the "riskiness" of the underlying security. Implied volatility is the primary measure of 171 | # the "price" of an option--how expensive it is relative to other options. It is the "plug" value in option 172 | # pricing models (the only variable in the equation that isn't precisely known). The remaining variables are 173 | # option price, stock price, strike price, time to expiration, interest rate, and estimated dividends. 174 | # Therefore, the implied volatility is the component of the option price that is determined by the market. 175 | # Implied volatility is greater if the future outcome of the underlying stock price is more uncertain. 176 | # All else equal, the wider the market expects the range of possible outcomes to be for a stock's price, 177 | # the higher the implied volatility, and the more expensive the option. 178 | def iv 179 | @iv ||= GreekCalculations.iv( 180 | :stock_price => stock_price, 181 | :stock_dividend_rate => stock_dividend_rate, 182 | :stock_dividend_rate_f => stock_dividend_rate_f, 183 | :option_type => option_type, 184 | :option_price => option_price, 185 | :option_strike => option_strike, 186 | :option_expires_in_days => option_expires_in_days, 187 | :option_expires_pct_year => option_expires_pct_year, 188 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 189 | :federal_reserve_interest_rate => federal_reserve_interest_rate, 190 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f, 191 | :price_ratio_log_less_rates => price_ratio_log_less_rates, 192 | :rate_vs_expires => rate_vs_expires, 193 | :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires, 194 | :price_vs_rate_vs_expires => price_vs_rate_vs_expires, 195 | ) 196 | end 197 | 198 | 199 | # Delta 200 | # A measurement of the change in the price of an option resulting from a change in the price of the underlying security. 201 | # Delta is positive for calls and negative for puts. Delta can be calculated as the dollar change of the option that an 202 | # investor can expect for a one-dollar change in the underlying security. For example, let's say an option on a stock 203 | # trading at $50 costs $1 and has a delta of $0.50 per dollar of underlying stock price change. If the stock price rises 204 | # to $52, the price of the option will increase by $1 (the $2 price change times the $0.50 delta). After the stock price 205 | # movement, the option will be worth $2 ($1 initial cost plus $1 delta). Delta can also be calculated as a percentage 206 | # change in the option price for a one-percent change in the underlying security; this method of viewing the delta value 207 | # is also known as "leverage." 208 | def delta 209 | @delta ||= GreekCalculations.delta( 210 | :option_type => option_type, 211 | :iv => iv, 212 | :rate_vs_expires => rate_vs_expires, 213 | :d1_normal_distribution => d1_normal_distribution 214 | ) 215 | end 216 | 217 | 218 | # Gamma 219 | # A measurement of the change in delta as the price of the underlying stock changes. As the underlying stock price changes, 220 | # the delta of the option changes, too. Gamma indicates how quickly your exposure to the price movement of the underlying 221 | # security changes as the price of the underlying security varies. For example, if you have a call with a strike of $50 222 | # and the stock price is $50, the delta likely will be approximately $0.50 for a one-dollar movement of the stock. 223 | # At a stock price of $60, the delta will be greater, closer to $0.75. At a stock price of $40, the delta will be less, 224 | # closer to $0.25. In this example, if the stock price changes from $50 to $60, then the delta will change from $0.50 to $0.75. 225 | # The $10 change in stock price caused a $0.25 change in delta, so gamma is approximately $0.25/10, or $0.025, in this case. 226 | def gamma 227 | @gamma ||= GreekCalculations.gamma( 228 | :stock_price => stock_price, 229 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 230 | :iv => iv, 231 | :nd1 => nd1, 232 | :rate_vs_expires => rate_vs_expires 233 | ) 234 | end 235 | 236 | 237 | # Vega 238 | # The change in the price of an option for a change in the implied volatility of the option, all else held equal. 239 | # In general, as the options market thinks it is more difficult to value a stock, implied volatility and therefore 240 | # the price of the options will increase. For example, if an option is trading for $1, the implied volatility is 20%, 241 | # and the vega is $0.05, then a one-percentage-point increase in implied volatility to 21% would correspond to an increase in 242 | # the price of the option to $1.05. In percentage terms, the vega in this case would be ($0.05/$1.00)/(1 percentage point) = 5%. 243 | def vega 244 | @vega ||= GreekCalculations.vega( 245 | :price_vs_rate_vs_expires => price_vs_rate_vs_expires, 246 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 247 | :nd1 => nd1, 248 | :iv => iv 249 | ) 250 | end 251 | 252 | 253 | # Rho 254 | # The change in the value of an option for a change in the prevailing interest rate that matches the duration of the option, 255 | # all else held equal. Generally rho is not a big driver of price changes for options, as interest rates tend to be relatively stable. 256 | def rho 257 | @rho ||= GreekCalculations.rho( 258 | :option_type => option_type, 259 | :option_expires_pct_year => option_expires_pct_year, 260 | :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires, 261 | :d2_normal_distribution => d2_normal_distribution, 262 | :iv => iv 263 | ) 264 | end 265 | 266 | 267 | # Theta 268 | # The change in an option's value that an investor can expect from the passage of one day, assuming nothing else changes. 269 | # Theta can be calculated in two ways, as the dollar change of the option that an investor can expect for a one-day passage of time, 270 | # all else remaining equal, or as a percentage change in the option price for a one-day passage of time, all else remaining equal. 271 | # For example, if an option trades at $1 on Monday morning and it has a theta of -$0.10 per day, you can expect the option to trade 272 | # at $0.90 on Tuesday morning. Another way of measuring theta for that option is ($0.90 - $1)/$1 or -10% per day. 273 | def theta 274 | @theta ||= GreekCalculations.theta( 275 | :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f, 276 | :stock_dividend_rate_f => stock_dividend_rate_f, 277 | :option_type => option_type, 278 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 279 | :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires, 280 | :price_vs_rate_vs_expires => price_vs_rate_vs_expires, 281 | :price_ratio_log_less_rates => price_ratio_log_less_rates, 282 | :iv => iv, 283 | :nd1 => nd1, 284 | :d1_normal_distribution => d1_normal_distribution, 285 | :d2_normal_distribution => d2_normal_distribution 286 | ) 287 | end 288 | 289 | 290 | def to_hash 291 | return @hash if @hash 292 | @hash = { 293 | :federal_reserve_interest_rate => federal_reserve_interest_rate, 294 | :stock_dividend_rate => stock_dividend_rate, 295 | :stock_price => stock_price, 296 | :option_expires_in_days => option_expires_in_days, 297 | :option_type => option_type, 298 | :option_strike => option_strike, 299 | :option_price => option_price, 300 | :option_volume => option_volume, 301 | :option_open_interest => option_open_interest, 302 | :premium_value => premium_value, 303 | :time_value => time_value, 304 | :annualized_premium_value => annualized_premium_value, 305 | :annualized_time_value => annualized_time_value, 306 | :iv => (NilMath.new(iv) * 100.0).to_f, # iv * 100 307 | :delta => (NilMath.new(delta) * stock_price / option_price).to_f, # delta * stock_price / option_price 308 | :gamma => (NilMath.new(gamma) * stock_price / delta).to_f, # gamma * stock_price / delta 309 | :vega => (NilMath.new(vega) * 100.0 * iv / option_price).to_f, # vega * iv * 100 / option_price 310 | :rho => (NilMath.new(rho) * 100.0 / option_price).to_f, # rho * 100 / option_price 311 | :theta => (NilMath.new(theta) * 100.0 / option_price).to_f, # theta * 100 / option_price 312 | :delta_vs_theta => nil, 313 | :break_even => (NilMath.new(break_even) * 100.0).to_f, # break_even * 100 314 | } 315 | 316 | # Delta/Theta 317 | # A measure of the “bang for the buck” of an option. 318 | # By dividing the dimensionless Delta or leverage of an option by the dimensionless Theta or 319 | # decay rate, the trend in the Delta/Theta column indicates which options give the most exposure 320 | # to the movement of the underlying stock or index for a given decay rate of the option value. 321 | # The highest numbers indicate the most bang for the buck for the least decay rate. 322 | @hash[:delta_vs_theta] = (NilMath.new(@hash[:delta]) / @hash[:theta]).to_f 323 | 324 | # Iterate the generated columns and round the output 325 | # Skip all the fields related to the input data: Federal, Stock, & Option 326 | @hash.keys.reject do |key| 327 | key = key.to_s 328 | key.start_with?('federal_') || key.start_with?('stock_') || key.start_with?('option_') 329 | end.each do |key| 330 | @hash[key] &&= @hash[key].round(2) 331 | end 332 | 333 | @hash 334 | end 335 | 336 | 337 | private 338 | 339 | 340 | def d1 341 | @d1 ||= GreekCalculations.misc_d1( 342 | :price_ratio_log_less_rates => price_ratio_log_less_rates, 343 | :option_expires_pct_year => option_expires_pct_year, 344 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 345 | :iv => iv 346 | ) 347 | end 348 | 349 | 350 | def d2 351 | @d2 ||= GreekCalculations.misc_d2( 352 | :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt, 353 | :d1 => d1, 354 | :iv => iv 355 | ) 356 | end 357 | 358 | 359 | def d1_normal_distribution 360 | @d1_normal_distribution ||= GreekCalculations.misc_d_normal_distribution( 361 | :option_type => option_type, 362 | :d_value => d1 363 | ) 364 | end 365 | 366 | 367 | def d2_normal_distribution 368 | @d2_normal_distribution ||= GreekCalculations.misc_d_normal_distribution( 369 | :option_type => option_type, 370 | :d_value => d2 371 | ) 372 | end 373 | 374 | 375 | def nd1 376 | @nd1 ||= GreekCalculations.misc_nd1(:d1 => d1) 377 | end 378 | 379 | class NilMath 380 | def initialize(value) 381 | @value = value 382 | end 383 | 384 | def to_f 385 | @value 386 | end 387 | 388 | def *(input) 389 | multiply(input) 390 | end 391 | 392 | def /(input) 393 | divide(input) 394 | end 395 | 396 | def multiply(input) 397 | if (@value.nil? || input.nil?) 398 | @value = nil 399 | else 400 | @value *= input 401 | end 402 | self 403 | end 404 | 405 | def multiply100() 406 | multiply(100.0) 407 | end 408 | 409 | def divide(input) 410 | if (@value.nil? || input.nil?) 411 | @value = nil 412 | else 413 | @value /= input 414 | end 415 | self 416 | end 417 | end 418 | 419 | end 420 | end 421 | end 422 | -------------------------------------------------------------------------------- /spec/greeks/24days.haliburton.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 |
11 | Last Price: $50.75  Day Change: 0.35 (0.69%)  03:00 PM CT 12 |
16 | 17 | 18 | 19 | 22 | 25 | 26 | 27 | 30 | 33 | 34 | 35 | 38 | 41 | 42 | 43 |
20 | Interest Rate Assumption: 21 | 23 |  % 24 |
28 | Dividends Until Expiration: 29 | 31 | $  32 |
36 | Highlighted options are in-the-money: 37 | 39 | 40 |
44 |

45 | Calls 46 |

47 | 48 | 49 | 50 | 53 | 56 | 59 | 62 | 65 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 98 | 101 | 104 | 107 | 110 | 113 | 116 | 119 | 120 | 121 | 124 | 127 | 130 | 133 | 136 | 139 | 142 | 145 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 175 | 178 | 181 | 184 | 187 | 190 | 191 | 192 | 195 | 198 | 201 | 204 | 207 | 210 | 213 | 216 | 219 | 222 | 225 | 228 | 231 | 234 | 237 | 240 | 243 | 246 | 249 | 252 | 255 | 258 | 261 | 262 | 263 | 266 | 269 | 272 | 275 | 278 | 281 | 284 | 287 | 290 | 293 | 296 | 299 | 302 | 305 | 308 | 311 | 314 | 317 | 320 | 323 | 326 | 329 | 332 | 333 | 334 | 337 | 340 | 343 | 346 | 349 | 352 | 355 | 358 | 361 | 364 | 367 | 370 | 373 | 376 | 379 | 382 | 385 | 388 | 391 | 394 | 397 | 400 | 403 | 404 | 405 | 408 | 411 | 414 | 417 | 420 | 423 | 426 | 429 | 432 | 435 | 438 | 441 | 444 | 447 | 450 | 453 | 456 | 459 | 462 | 465 | 468 | 471 | 474 | 475 | 476 | 479 | 482 | 485 | 488 | 491 | 494 | 497 | 500 | 503 | 506 | 509 | 512 | 515 | 518 | 521 | 524 | 527 | 530 | 533 | 536 | 539 | 542 | 545 | 546 | 547 | 550 | 553 | 556 | 559 | 562 | 565 | 568 | 571 | 574 | 577 | 580 | 583 | 586 | 589 | 592 | 595 | 598 | 601 | 604 | 607 | 610 | 613 | 616 | 617 | 618 | 621 | 624 | 627 | 630 | 633 | 636 | 639 | 642 | 645 | 648 | 651 | 654 | 657 | 660 | 663 | 666 | 669 | 672 | 675 | 678 | 681 | 684 | 687 | 688 | 689 | 692 | 695 | 698 | 701 | 704 | 707 | 710 | 713 | 716 | 719 | 722 | 725 | 728 | 731 | 734 | 737 | 740 | 743 | 746 | 749 | 752 | 755 | 758 | 759 | 760 | 763 | 766 | 769 | 772 | 775 | 778 | 781 | 784 | 787 | 790 | 793 | 796 | 799 | 802 | 805 | 808 | 811 | 814 | 817 | 820 | 823 | 826 | 829 | 830 | 831 | 834 | 837 | 840 | 843 | 846 | 849 | 852 | 855 | 858 | 861 | 864 | 867 | 870 | 873 | 876 | 879 | 882 | 885 | 888 | 891 | 894 | 897 | 900 | 901 | 902 | 905 | 908 | 911 | 914 | 917 | 920 | 923 | 926 | 929 | 932 | 935 | 938 | 941 | 944 | 947 | 950 | 953 | 956 | 959 | 962 | 965 | 968 | 971 | 972 | 973 | 976 | 979 | 982 | 985 | 988 | 991 | 994 | 997 | 1000 | 1003 | 1006 | 1009 | 1012 | 1015 | 1018 | 1021 | 1024 | 1027 | 1030 | 1033 | 1036 | 1039 | 1042 | 1043 | 1044 | 1047 | 1050 | 1053 | 1056 | 1059 | 1062 | 1065 | 1068 | 1071 | 1074 | 1077 | 1080 | 1083 | 1086 | 1089 | 1092 | 1095 | 1098 | 1101 | 1104 | 1107 | 1110 | 1113 | 1114 | 1115 | 1118 | 1121 | 1124 | 1127 | 1130 | 1133 | 1136 | 1139 | 1142 | 1145 | 1148 | 1151 | 1154 | 1157 | 1160 | 1163 | 1166 | 1169 | 1172 | 1175 | 1178 | 1181 | 1184 | 1185 | 1186 | 1189 | 1192 | 1195 | 1198 | 1201 | 1204 | 1207 | 1210 | 1213 | 1216 | 1219 | 1222 | 1225 | 1228 | 1231 | 1234 | 1237 | 1240 | 1243 | 1246 | 1249 | 1252 | 1255 | 1256 | 1257 | 1260 | 1263 | 1266 | 1269 | 1272 | 1275 | 1278 | 1281 | 1284 | 1287 | 1290 | 1293 | 1296 | 1299 | 1302 | 1305 | 1308 | 1311 | 1314 | 1317 | 1320 | 1323 | 1326 | 1327 | 1328 | 1331 | 1334 | 1337 | 1340 | 1343 | 1346 | 1349 | 1352 | 1355 | 1358 | 1361 | 1364 | 1367 | 1370 | 1373 | 1376 | 1379 | 1382 | 1385 | 1388 | 1391 | 1394 | 1397 | 1398 | 1399 | 1402 | 1405 | 1408 | 1411 | 1414 | 1417 | 1420 | 1423 | 1426 | 1429 | 1432 | 1435 | 1438 | 1441 | 1444 | 1447 | 1450 | 1453 | 1456 | 1459 | 1462 | 1465 | 1468 | 1469 | 1470 | 1473 | 1476 | 1479 | 1482 | 1485 | 1488 | 1491 | 1494 | 1497 | 1500 | 1503 | 1506 | 1509 | 1512 | 1515 | 1518 | 1521 | 1524 | 1527 | 1530 | 1533 | 1536 | 1539 | 1540 | 1541 | 1544 | 1547 | 1550 | 1553 | 1556 | 1559 | 1562 | 1565 | 1568 | 1571 | 1574 | 1577 | 1580 | 1583 | 1586 | 1589 | 1592 | 1595 | 1598 | 1601 | 1604 | 1607 | 1610 | 1611 | 1612 | 1615 | 1618 | 1621 | 1624 | 1627 | 1630 | 1633 | 1636 | 1639 | 1642 | 1645 | 1648 | 1651 | 1654 | 1657 | 1660 | 1663 | 1666 | 1669 | 1672 | 1675 | 1678 | 1681 | 1682 | 1683 | 1686 | 1689 | 1692 | 1695 | 1698 | 1701 | 1704 | 1707 | 1710 | 1713 | 1716 | 1719 | 1722 | 1725 | 1728 | 1731 | 1734 | 1737 | 1740 | 1743 | 1746 | 1749 | 1752 | 1753 | 1754 | 1757 | 1760 | 1763 | 1766 | 1769 | 1772 | 1775 | 1778 | 1781 | 1784 | 1787 | 1790 | 1793 | 1796 | 1799 | 1802 | 1805 | 1808 | 1811 | 1814 | 1817 | 1820 | 1823 | 1824 | 1825 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | 1876 | 1877 | 1878 |
51 | Strike 52 | 54 | Last Trade 55 | 57 | Bid 58 | 60 | Mid 61 | 63 | Ask 64 | 66 | Change 67 | 69 | Change (Price) 70 | 72 | Change (IV) 73 | 75 | Change (Time) 76 | 78 | Volume 79 | 81 | Open Interest 82 | 84 | Implied Volatility 85 | 87 | Δ Implied Volatility 88 | 90 | Delta (%/%) 91 | 93 | Delta/ Theta 94 | 96 | MOE 97 | 99 | Strike/ Stock 100 | 102 | Annualized Premium 103 | 105 | Intrinsic Value 106 | 108 | Time Value 109 | 111 | Annualized Time Value 112 | 114 | Chance of Breakeven 115 | 117 | Break Even Return % 118 |
122 | 38.00 123 | 125 | 12.50 126 | 128 | 12.75 129 | 131 | 12.80 132 | 134 | 12.85 135 | 137 | 0.00 138 | 140 | 0.33 141 | 143 | 0.33 144 | 146 | 0.03 147 | 149 | 1 150 | 152 | 64 153 | 155 | 55.2 156 | 158 | -24.7 159 | 161 | 3.9 162 | 164 | -73.50 165 | 167 | 0.20 168 | 170 | 75 171 | 173 | 423.85 174 | 176 | 12.75 177 | 179 | 0.05 180 | 182 | 1.92 183 | 185 | 46.85 186 | 188 | 0.10 189 |
193 | 39.00 194 | 196 | 12.25 197 | 199 | 11.75 200 | 202 | 11.80 203 | 205 | 11.85 206 | 208 | 0.00 209 | 211 | 0.32 212 | 214 | 0.33 215 | 217 | 0.03 218 | 220 | 39 221 | 223 | 39 224 | 226 | 50.8 227 | 229 | -23.3 230 | 232 | 4.2 233 | 235 | -75.04 236 | 238 | 0.20 239 | 241 | 77 242 | 244 | 385.93 245 | 247 | 11.75 248 | 250 | 0.05 251 | 253 | 1.87 254 | 256 | 47.06 257 | 259 | 0.10 260 |
264 | 40.00 265 | 267 | N/A 268 | 270 | 10.75 271 | 273 | 10.80 274 | 276 | 10.85 277 | 279 | 0.00 280 | 282 | 0.32 283 | 285 | 0.33 286 | 288 | 0.03 289 | 291 | 0 292 | 294 | 0 295 | 297 | 46.5 298 | 300 | -21.9 301 | 303 | 4.6 304 | 306 | -76.76 307 | 309 | 0.20 310 | 312 | 79 313 | 315 | 348.96 316 | 318 | 10.75 319 | 321 | 0.05 322 | 324 | 1.82 325 | 327 | 47.25 328 | 330 | 0.10 331 |
335 | 41.00 336 | 338 | N/A 339 | 341 | 9.75 342 | 344 | 9.80 345 | 347 | 9.85 348 | 350 | 0.00 351 | 353 | 0.32 354 | 356 | 0.33 357 | 359 | 0.03 360 | 362 | 0 363 | 365 | 0 366 | 368 | 42.3 369 | 371 | -20.6 372 | 374 | 5.1 375 | 377 | -78.69 378 | 380 | 0.20 381 | 383 | 81 384 | 386 | 312.91 387 | 389 | 9.75 390 | 392 | 0.05 393 | 395 | 1.78 396 | 398 | 47.44 399 | 401 | 0.10 402 |
406 | 42.00 407 | 409 | N/A 410 | 412 | 8.75 413 | 415 | 8.83 416 | 418 | 8.90 419 | 421 | 0.00 422 | 424 | 0.32 425 | 427 | 0.33 428 | 430 | 0.03 431 | 433 | 0 434 | 436 | 0 437 | 439 | 40.8 440 | 442 | -17.5 443 | 445 | 5.6 446 | 448 | -59.81 449 | 451 | 0.31 452 | 454 | 83 455 | 457 | 278.45 458 | 460 | 8.75 461 | 463 | 0.08 464 | 466 | 2.60 467 | 469 | 47.32 470 | 472 | 0.15 473 |
477 | 43.00 478 | 480 | N/A 481 | 483 | 7.80 484 | 486 | 7.85 487 | 489 | 7.90 490 | 492 | 0.00 493 | 495 | 0.31 496 | 498 | 0.32 499 | 501 | 0.03 502 | 504 | 0 505 | 507 | 0 508 | 510 | 38.6 511 | 513 | -15.1 514 | 516 | 6.2 517 | 519 | -49.24 520 | 522 | 0.21 523 | 525 | 85 526 | 528 | 244.81 529 | 531 | 7.75 532 | 534 | 0.10 535 | 537 | 3.39 538 | 540 | 47.21 541 | 543 | 0.20 544 |
548 | 44.00 549 | 551 | N/A 552 | 554 | 6.80 555 | 557 | 6.85 558 | 560 | 6.90 561 | 563 | 0.00 564 | 566 | 0.31 567 | 569 | 0.32 570 | 572 | 0.03 573 | 575 | 0 576 | 578 | 0 579 | 581 | 34.2 582 | 584 | -13.9 585 | 587 | 7.0 588 | 590 | -50.74 591 | 593 | 0.21 594 | 596 | 87 597 | 599 | 211.25 600 | 602 | 6.75 603 | 605 | 0.10 606 | 608 | 3.31 609 | 611 | 47.34 612 | 614 | 0.20 615 |
619 | 45.00 620 | 622 | 5.30 623 | 625 | 5.85 626 | 628 | 5.90 629 | 631 | 5.95 632 | 634 | 0.00 635 | 637 | 0.30 638 | 640 | 0.30 641 | 643 | 0.03 644 | 646 | 41 647 | 649 | 30 650 | 652 | 33.0 653 | 655 | -11.1 656 | 658 | 8.0 659 | 661 | -37.61 662 | 664 | 0.21 665 | 667 | 89 668 | 670 | 179.87 671 | 673 | 5.75 674 | 676 | 0.15 677 | 679 | 4.86 680 | 682 | 46.92 683 | 685 | 0.30 686 |
690 | 46.00 691 | 693 | 5.60 694 | 696 | 4.95 697 | 699 | 5.00 700 | 702 | 5.05 703 | 705 | 0.00 706 | 708 | 0.29 709 | 711 | 0.29 712 | 714 | 0.03 715 | 717 | 3 718 | 720 | 5 721 | 723 | 32.4 724 | 726 | -8.7 727 | 729 | 9.0 730 | 732 | -26.85 733 | 735 | 0.22 736 | 738 | 91 739 | 741 | 150.65 742 | 744 | 4.75 745 | 747 | 0.25 748 | 750 | 7.91 751 | 753 | 46.01 754 | 756 | 0.49 757 |
761 | 47.00 762 | 764 | 3.75 765 | 767 | 4.05 768 | 770 | 4.10 771 | 773 | 4.15 774 | 776 | 0.00 777 | 779 | 0.28 780 | 782 | 0.27 783 | 785 | 0.03 786 | 788 | 10 789 | 791 | 10 792 | 794 | 30.5 795 | 797 | -7.1 798 | 800 | 10.4 801 | 803 | -21.78 804 | 806 | 0.23 807 | 809 | 93 810 | 812 | 122.11 813 | 815 | 3.75 816 | 818 | 0.35 819 | 821 | 10.83 822 | 824 | 44.99 825 | 827 | 0.69 828 |
832 | 48.00 833 | 835 | 3.10 836 | 838 | 3.20 839 | 841 | 3.25 842 | 844 | 3.30 845 | 847 | 0.00 848 | 850 | 0.26 851 | 853 | 0.24 854 | 856 | 0.03 857 | 859 | 324 860 | 862 | 209 863 | 865 | 29.0 866 | 868 | -5.4 869 | 871 | 12.2 872 | 874 | -17.38 875 | 877 | 0.25 878 | 880 | 95 881 | 883 | 95.65 884 | 886 | 2.75 887 | 889 | 0.50 890 | 892 | 15.13 893 | 895 | 43.36 896 | 898 | 0.99 899 |
903 | 49.00 904 | 906 | 2.30 907 | 909 | 2.47 910 | 912 | 2.49 913 | 915 | 2.50 916 | 918 | 0.00 919 | 921 | 0.23 922 | 924 | 0.21 925 | 927 | 0.03 928 | 930 | 58 931 | 933 | 185 934 | 936 | 27.8 937 | 939 | -4.3 940 | 942 | 14.3 943 | 945 | -13.79 946 | 948 | 0.08 949 | 951 | 97 952 | 954 | 72.23 955 | 957 | 1.75 958 | 960 | 0.74 961 | 963 | 21.74 964 | 966 | 40.74 967 | 969 | 1.45 970 |
974 | 50.00 975 | 977 | 1.66 978 | 980 | 1.81 981 | 983 | 1.83 984 | 986 | 1.84 987 | 989 | 0.00 990 | 992 | 0.20 993 | 995 | 0.17 996 | 998 | 0.03 999 | 1001 | 24 1002 | 1004 | 559 1005 | 1007 | 27.0 1008 | 1010 | -3.3 1011 | 1013 | 16.6 1014 | 1016 | -10.93 1017 | 1019 | 0.10 1020 | 1022 | 99 1023 | 1025 | 52.34 1026 | 1028 | 0.75 1029 | 1031 | 1.08 1032 | 1034 | 31.06 1035 | 1037 | 36.99 1038 | 1040 | 2.12 1041 |
1045 | 51.00 1046 | 1048 | 1.21 1049 | 1051 | 1.28 1052 | 1054 | 1.29 1055 | 1057 | 1.29 1058 | 1060 | 0.00 1061 | 1063 | 0.17 1064 | 1066 | 0.14 1067 | 1069 | 0.03 1070 | 1072 | 128 1073 | 1075 | 300 1076 | 1078 | 26.5 1079 | 1081 | -2.6 1082 | 1084 | 19.2 1085 | 1087 | -8.78 1088 | 1090 | 0.04 1091 | 1093 | 100 1094 | 1096 | 36.33 1097 | 1099 | 0.00 1100 | 1102 | 1.29 1103 | 1105 | 36.33 1106 | 1108 | 32.12 1109 | 1111 | 3.02 1112 |
1116 | 52.00 1117 | 1119 | 0.81 1120 | 1122 | 0.86 1123 | 1125 | 0.87 1126 | 1128 | 0.88 1129 | 1131 | 0.00 1132 | 1134 | 0.13 1135 | 1137 | 0.10 1138 | 1140 | 0.03 1141 | 1143 | 115 1144 | 1146 | 559 1147 | 1149 | 26.2 1150 | 1152 | -2.0 1153 | 1155 | 21.8 1156 | 1158 | -7.19 1159 | 1161 | 0.11 1162 | 1164 | 102 1165 | 1167 | 24.22 1168 | 1170 | 0.00 1171 | 1173 | 0.87 1174 | 1176 | 24.22 1177 | 1179 | 26.43 1180 | 1182 | 4.18 1183 |
1187 | 53.00 1188 | 1190 | 0.56 1191 | 1193 | 0.57 1194 | 1196 | 0.58 1197 | 1199 | 0.58 1200 | 1202 | 0.00 1203 | 1205 | 0.10 1206 | 1208 | 0.07 1209 | 1211 | 0.02 1212 | 1214 | 7 1215 | 1217 | 330 1218 | 1220 | 26.4 1221 | 1223 | -1.6 1224 | 1226 | 24.4 1227 | 1229 | -5.98 1230 | 1232 | 0.07 1233 | 1235 | 104 1236 | 1238 | 15.75 1239 | 1241 | 0.00 1242 | 1244 | 0.58 1245 | 1247 | 15.75 1248 | 1250 | 20.64 1251 | 1253 | 5.57 1254 |
1258 | 54.00 1259 | 1261 | 0.33 1262 | 1264 | 0.36 1265 | 1267 | 0.37 1268 | 1270 | 0.38 1271 | 1273 | 0.00 1274 | 1276 | 0.07 1277 | 1279 | 0.05 1280 | 1282 | 0.02 1283 | 1285 | 25 1286 | 1288 | 33 1289 | 1291 | 26.6 1292 | 1294 | -1.3 1295 | 1297 | 26.8 1298 | 1300 | -5.09 1301 | 1303 | 0.20 1304 | 1306 | 106 1307 | 1309 | 9.97 1310 | 1312 | 0.00 1313 | 1315 | 0.37 1316 | 1318 | 9.97 1319 | 1321 | 15.25 1322 | 1324 | 7.13 1325 |
1329 | 55.00 1330 | 1332 | 0.20 1333 | 1335 | 0.23 1336 | 1338 | 0.24 1339 | 1341 | 0.24 1342 | 1344 | 0.00 1345 | 1347 | 0.05 1348 | 1350 | 0.03 1351 | 1353 | 0.01 1354 | 1356 | 11 1357 | 1359 | 160 1360 | 1362 | 26.9 1363 | 1365 | -1.1 1366 | 1368 | 29.0 1369 | 1371 | -4.40 1372 | 1374 | 0.15 1375 | 1377 | 108 1378 | 1380 | 6.22 1381 | 1383 | 0.00 1384 | 1386 | 0.24 1387 | 1389 | 6.22 1390 | 1392 | 10.82 1393 | 1395 | 8.84 1396 |
1400 | 56.00 1401 | 1403 | 0.21 1404 | 1406 | 0.14 1407 | 1409 | 0.15 1410 | 1412 | 0.16 1413 | 1415 | 0.00 1416 | 1418 | 0.03 1419 | 1421 | 0.02 1422 | 1424 | 0.01 1425 | 1427 | 1 1428 | 1430 | 21 1431 | 1433 | 27.5 1434 | 1436 | -0.9 1437 | 1439 | 30.8 1440 | 1442 | -3.87 1443 | 1445 | 0.43 1446 | 1448 | 110 1449 | 1451 | 3.91 1452 | 1454 | 0.00 1455 | 1457 | 0.15 1458 | 1460 | 3.91 1461 | 1463 | 7.45 1464 | 1466 | 10.64 1467 |
1471 | 57.00 1472 | 1474 | 0.14 1475 | 1477 | 0.09 1478 | 1480 | 0.10 1481 | 1483 | 0.11 1484 | 1486 | 0.00 1487 | 1489 | 0.02 1490 | 1492 | 0.01 1493 | 1495 | 0.01 1496 | 1498 | 5 1499 | 1501 | 22 1502 | 1504 | 28.3 1505 | 1507 | -0.8 1508 | 1510 | 32.0 1511 | 1513 | -3.43 1514 | 1516 | 0.62 1517 | 1519 | 112 1520 | 1522 | 2.56 1523 | 1525 | 0.00 1526 | 1528 | 0.10 1529 | 1531 | 2.56 1532 | 1534 | 5.18 1535 | 1537 | 12.51 1538 |
1542 | 58.00 1543 | 1545 | 0.11 1546 | 1548 | 0.06 1549 | 1551 | 0.07 1552 | 1554 | 0.08 1555 | 1557 | 0.00 1558 | 1560 | 0.02 1561 | 1563 | 0.01 1564 | 1566 | 0.01 1567 | 1569 | 11 1570 | 1572 | 11 1573 | 1575 | 29.4 1576 | 1578 | -0.7 1579 | 1581 | 32.5 1582 | 1584 | -3.08 1585 | 1587 | 0.88 1588 | 1590 | 114 1591 | 1593 | 1.76 1594 | 1596 | 0.00 1597 | 1599 | 0.07 1600 | 1602 | 1.76 1603 | 1605 | 3.68 1606 | 1608 | 14.42 1609 |
1613 | 59.00 1614 | 1616 | 0.09 1617 | 1619 | 0.04 1620 | 1622 | 0.05 1623 | 1625 | 0.06 1626 | 1628 | 0.00 1629 | 1631 | 0.01 1632 | 1634 | 0.01 1635 | 1637 | 0.01 1638 | 1640 | 14 1641 | 1643 | 18 1644 | 1646 | 30.5 1647 | 1649 | -0.6 1650 | 1652 | 32.9 1653 | 1655 | -2.80 1656 | 1658 | 1.22 1659 | 1661 | 116 1662 | 1664 | 1.24 1665 | 1667 | 0.00 1668 | 1670 | 0.05 1671 | 1673 | 1.24 1674 | 1676 | 2.64 1677 | 1679 | 16.35 1680 |
1684 | 60.00 1685 | 1687 | 0.06 1688 | 1690 | 0.02 1691 | 1693 | 0.03 1694 | 1696 | 0.04 1697 | 1699 | 0.00 1700 | 1702 | 0.01 1703 | 1705 | 0.00 1706 | 1708 | 0.00 1709 | 1711 | 4 1712 | 1714 | 34 1715 | 1717 | 30.7 1718 | 1720 | -0.5 1721 | 1723 | 34.9 1724 | 1726 | -2.58 1727 | 1729 | 1.91 1730 | 1732 | 118 1733 | 1735 | 0.73 1736 | 1738 | 0.00 1739 | 1741 | 0.03 1742 | 1744 | 0.73 1745 | 1747 | 1.67 1748 | 1750 | 18.29 1751 |
1755 | 61.00 1756 | 1758 | N/A 1759 | 1761 | 0.01 1762 | 1764 | 0.03 1765 | 1767 | 0.04 1768 | 1770 | 0.00 1771 | 1773 | 0.01 1774 | 1776 | 0.00 1777 | 1779 | 0.00 1780 | 1782 | 0 1783 | 1785 | 0 1786 | 1788 | 32.4 1789 | 1791 | -0.4 1792 | 1794 | 33.8 1795 | 1797 | -2.37 1798 | 1800 | 3.55 1801 | 1803 | 120 1804 | 1806 | 0.60 1807 | 1809 | 0.00 1810 | 1812 | 0.03 1813 | 1815 | 0.60 1816 | 1818 | 1.33 1819 | 1821 | 20.25 1822 |
1826 | 1827 |
1879 |

1880 | Puts 1881 |

1882 | 1883 | 1884 | 1885 | 1888 | 1891 | 1894 | 1897 | 1900 | 1903 | 1906 | 1909 | 1912 | 1915 | 1918 | 1921 | 1924 | 1927 | 1930 | 1933 | 1936 | 1939 | 1942 | 1945 | 1948 | 1951 | 1954 | 1955 | 1956 | 1959 | 1962 | 1965 | 1968 | 1971 | 1974 | 1977 | 1980 | 1983 | 1986 | 1989 | 1992 | 1995 | 1998 | 2001 | 2004 | 2007 | 2010 | 2013 | 2016 | 2019 | 2022 | 2025 | 2026 | 2027 | 2030 | 2033 | 2036 | 2039 | 2042 | 2045 | 2048 | 2051 | 2054 | 2057 | 2060 | 2063 | 2066 | 2069 | 2072 | 2075 | 2078 | 2081 | 2084 | 2087 | 2090 | 2093 | 2096 | 2097 | 2098 | 2101 | 2104 | 2107 | 2110 | 2113 | 2116 | 2119 | 2122 | 2125 | 2128 | 2131 | 2134 | 2137 | 2140 | 2143 | 2146 | 2149 | 2152 | 2155 | 2158 | 2161 | 2164 | 2167 | 2168 | 2169 | 2172 | 2175 | 2178 | 2181 | 2184 | 2187 | 2190 | 2193 | 2196 | 2199 | 2202 | 2205 | 2208 | 2211 | 2214 | 2217 | 2220 | 2223 | 2226 | 2229 | 2232 | 2235 | 2238 | 2239 | 2240 | 2243 | 2246 | 2249 | 2252 | 2255 | 2258 | 2261 | 2264 | 2267 | 2270 | 2273 | 2276 | 2279 | 2282 | 2285 | 2288 | 2291 | 2294 | 2297 | 2300 | 2303 | 2306 | 2309 | 2310 | 2311 | 2314 | 2317 | 2320 | 2323 | 2326 | 2329 | 2332 | 2335 | 2338 | 2341 | 2344 | 2347 | 2350 | 2353 | 2356 | 2359 | 2362 | 2365 | 2368 | 2371 | 2374 | 2377 | 2380 | 2381 | 2382 | 2385 | 2388 | 2391 | 2394 | 2397 | 2400 | 2403 | 2406 | 2409 | 2412 | 2415 | 2418 | 2421 | 2424 | 2427 | 2430 | 2433 | 2436 | 2439 | 2442 | 2445 | 2448 | 2451 | 2452 | 2453 | 2456 | 2459 | 2462 | 2465 | 2468 | 2471 | 2474 | 2477 | 2480 | 2483 | 2486 | 2489 | 2492 | 2495 | 2498 | 2501 | 2504 | 2507 | 2510 | 2513 | 2516 | 2519 | 2522 | 2523 | 2524 | 2527 | 2530 | 2533 | 2536 | 2539 | 2542 | 2545 | 2548 | 2551 | 2554 | 2557 | 2560 | 2563 | 2566 | 2569 | 2572 | 2575 | 2578 | 2581 | 2584 | 2587 | 2590 | 2593 | 2594 | 2595 | 2598 | 2601 | 2604 | 2607 | 2610 | 2613 | 2616 | 2619 | 2622 | 2625 | 2628 | 2631 | 2634 | 2637 | 2640 | 2643 | 2646 | 2649 | 2652 | 2655 | 2658 | 2661 | 2664 | 2665 | 2666 | 2669 | 2672 | 2675 | 2678 | 2681 | 2684 | 2687 | 2690 | 2693 | 2696 | 2699 | 2702 | 2705 | 2708 | 2711 | 2714 | 2717 | 2720 | 2723 | 2726 | 2729 | 2732 | 2735 | 2736 | 2737 | 2740 | 2743 | 2746 | 2749 | 2752 | 2755 | 2758 | 2761 | 2764 | 2767 | 2770 | 2773 | 2776 | 2779 | 2782 | 2785 | 2788 | 2791 | 2794 | 2797 | 2800 | 2803 | 2806 | 2807 | 2808 | 2811 | 2814 | 2817 | 2820 | 2823 | 2826 | 2829 | 2832 | 2835 | 2838 | 2841 | 2844 | 2847 | 2850 | 2853 | 2856 | 2859 | 2862 | 2865 | 2868 | 2871 | 2874 | 2877 | 2878 | 2879 | 2882 | 2885 | 2888 | 2891 | 2894 | 2897 | 2900 | 2903 | 2906 | 2909 | 2912 | 2915 | 2918 | 2921 | 2924 | 2927 | 2930 | 2933 | 2936 | 2939 | 2942 | 2945 | 2948 | 2949 | 2950 | 2953 | 2956 | 2959 | 2962 | 2965 | 2968 | 2971 | 2974 | 2977 | 2980 | 2983 | 2986 | 2989 | 2992 | 2995 | 2998 | 3001 | 3004 | 3007 | 3010 | 3013 | 3016 | 3019 | 3020 | 3021 | 3024 | 3027 | 3030 | 3033 | 3036 | 3039 | 3042 | 3045 | 3048 | 3051 | 3054 | 3057 | 3060 | 3063 | 3066 | 3069 | 3072 | 3075 | 3078 | 3081 | 3084 | 3087 | 3090 | 3091 | 3092 | 3095 | 3098 | 3101 | 3104 | 3107 | 3110 | 3113 | 3116 | 3119 | 3122 | 3125 | 3128 | 3131 | 3134 | 3137 | 3140 | 3143 | 3146 | 3149 | 3152 | 3155 | 3158 | 3161 | 3162 | 3163 | 3166 | 3169 | 3172 | 3175 | 3178 | 3181 | 3184 | 3187 | 3190 | 3193 | 3196 | 3199 | 3202 | 3205 | 3208 | 3211 | 3214 | 3217 | 3220 | 3223 | 3226 | 3229 | 3232 | 3233 | 3234 | 3237 | 3240 | 3243 | 3246 | 3249 | 3252 | 3255 | 3258 | 3261 | 3264 | 3267 | 3270 | 3273 | 3276 | 3279 | 3282 | 3285 | 3288 | 3291 | 3294 | 3297 | 3300 | 3303 | 3304 | 3305 | 3308 | 3311 | 3314 | 3317 | 3320 | 3323 | 3326 | 3329 | 3332 | 3335 | 3338 | 3341 | 3344 | 3347 | 3350 | 3353 | 3356 | 3359 | 3362 | 3365 | 3368 | 3371 | 3374 | 3375 | 3376 | 3379 | 3382 | 3385 | 3388 | 3391 | 3394 | 3397 | 3400 | 3403 | 3406 | 3409 | 3412 | 3415 | 3418 | 3421 | 3424 | 3427 | 3430 | 3433 | 3436 | 3439 | 3442 | 3445 | 3446 | 3447 | 3450 | 3453 | 3456 | 3459 | 3462 | 3465 | 3468 | 3471 | 3474 | 3477 | 3480 | 3483 | 3486 | 3489 | 3492 | 3495 | 3498 | 3501 | 3504 | 3507 | 3510 | 3513 | 3516 | 3517 | 3518 | 3521 | 3524 | 3527 | 3530 | 3533 | 3536 | 3539 | 3542 | 3545 | 3548 | 3551 | 3554 | 3557 | 3560 | 3563 | 3566 | 3569 | 3572 | 3575 | 3578 | 3581 | 3584 | 3587 | 3588 | 3589 | 3592 | 3595 | 3598 | 3601 | 3604 | 3607 | 3610 | 3613 | 3616 | 3619 | 3622 | 3625 | 3628 | 3631 | 3634 | 3637 | 3640 | 3643 | 3646 | 3649 | 3652 | 3655 | 3658 | 3659 | 3660 |
1886 | Strike 1887 | 1889 | Last Trade 1890 | 1892 | Bid 1893 | 1895 | Mid 1896 | 1898 | Ask 1899 | 1901 | Change 1902 | 1904 | Change (Price) 1905 | 1907 | Change (IV) 1908 | 1910 | Change (Time) 1911 | 1913 | Volume 1914 | 1916 | Open Interest 1917 | 1919 | Implied Volatility 1920 | 1922 | Δ Implied Volatility 1923 | 1925 | Delta (%/%) 1926 | 1928 | Delta/ Theta 1929 | 1931 | MOE 1932 | 1934 | Strike/ Stock 1935 | 1937 | Annualized Premium 1938 | 1940 | Intrinsic Value 1941 | 1943 | Time Value 1944 | 1946 | Annualized Time Value 1947 | 1949 | Chance of Breakeven 1950 | 1952 | Break Even Return % 1953 |
1957 | 38.00 1958 | 1960 | 0.04 1961 | 1963 | 0.03 1964 | 1966 | 0.04 1967 | 1969 | 0.05 1970 | 1972 | 0.00 1973 | 1975 | 0.01 1976 | 1978 | 0.01 1979 | 1981 | 0.00 1982 | 1984 | 10 1985 | 1987 | 0 1988 | 1990 | 52.9 1991 | 1993 | 2.1 1994 | 1996 | -19.5 1997 | 1999 | 1.44 2000 | 2002 | 2.57 2003 | 2005 | 75 2006 | 2008 | 1.54 2009 | 2011 | 0.00 2012 | 2014 | 0.04 2015 | 2017 | 1.54 2018 | 2020 | 2.12 2021 | 2023 | -25.20 2024 |
2028 | 39.00 2029 | 2031 | 0.09 2032 | 2034 | 0.04 2035 | 2037 | 0.05 2038 | 2040 | 0.06 2041 | 2043 | 0.00 2044 | 2046 |   2047 | 2049 |   2050 | 2052 |   2053 | 2055 | 370 2056 | 2058 | 333 2059 | 2061 |   2062 | 2064 |   2065 | 2067 |   2068 | 2070 |   2071 | 2073 |   2074 | 2076 | 77 2077 | 2079 |   2080 | 2082 | 0.00 2083 | 2085 |   2086 | 2088 |   2089 | 2091 |   2092 | 2094 |   2095 |
2099 | 40.00 2100 | 2102 | 0.09 2103 | 2105 | 0.04 2106 | 2108 | 0.05 2109 | 2111 | 0.06 2112 | 2114 | 0.00 2115 | 2117 | 0.01 2118 | 2120 | 0.02 2121 | 2123 | 0.01 2124 | 2126 | 10 2127 | 2129 | 12 2130 | 2132 | 46.2 2133 | 2135 | 2.0 2136 | 2138 | -21.5 2139 | 2141 | 1.72 2142 | 2144 | 1.86 2145 | 2147 | 79 2148 | 2150 | 1.82 2151 | 2153 | 0.00 2154 | 2156 | 0.05 2157 | 2159 | 1.82 2160 | 2162 | 2.74 2163 | 2165 | -21.28 2166 |
2170 | 41.00 2171 | 2173 | 0.07 2174 | 2176 | 0.05 2177 | 2179 | 0.06 2180 | 2182 | 0.07 2183 | 2185 | 0.00 2186 | 2188 | 0.01 2189 | 2191 | 0.02 2192 | 2194 | 0.01 2195 | 2197 | 7 2198 | 2200 | 48 2201 | 2203 | 43.3 2204 | 2206 | 2.0 2207 | 2209 | -22.3 2210 | 2212 | 1.90 2213 | 2215 | 1.50 2216 | 2218 | 81 2219 | 2221 | 2.14 2222 | 2224 | 0.00 2225 | 2227 | 0.06 2228 | 2230 | 2.14 2231 | 2233 | 3.31 2234 | 2236 | -19.33 2237 |
2241 | 42.00 2242 | 2244 | 0.08 2245 | 2247 | 0.06 2248 | 2250 | 0.07 2251 | 2253 | 0.08 2254 | 2256 | 0.00 2257 | 2259 | 0.01 2260 | 2262 | 0.02 2263 | 2265 | 0.01 2266 | 2268 | 39 2269 | 2271 | 144 2272 | 2274 | 40.3 2275 | 2277 | 1.9 2278 | 2280 | -23.4 2281 | 2283 | 2.12 2284 | 2286 | 1.22 2287 | 2289 | 83 2290 | 2292 | 2.43 2293 | 2295 | 0.00 2296 | 2298 | 0.07 2299 | 2301 | 2.43 2302 | 2304 | 3.92 2305 | 2307 | -17.38 2308 |
2312 | 43.00 2313 | 2315 | 0.10 2316 | 2318 | 0.08 2319 | 2321 | 0.09 2322 | 2324 | 0.10 2325 | 2327 | 0.00 2328 | 2330 | 0.01 2331 | 2333 | 0.03 2334 | 2336 | 0.01 2337 | 2339 | 59 2340 | 2342 | 117 2343 | 2345 | 37.9 2346 | 2348 | 2.0 2349 | 2351 | -24.0 2352 | 2354 | 2.37 2355 | 2357 | 0.93 2358 | 2360 | 85 2361 | 2363 | 3.05 2364 | 2366 | 0.00 2367 | 2369 | 0.09 2370 | 2372 | 3.05 2373 | 2375 | 5.01 2376 | 2378 | -15.45 2379 |
2383 | 44.00 2384 | 2386 | 0.11 2387 | 2389 | 0.11 2390 | 2392 | 0.12 2393 | 2395 | 0.12 2396 | 2398 | 0.00 2399 | 2401 | 0.02 2402 | 2404 | 0.03 2405 | 2407 | 0.01 2408 | 2410 | 16 2411 | 2413 | 41 2414 | 2416 | 35.3 2417 | 2419 | 2.0 2420 | 2422 | -24.6 2423 | 2425 | 2.68 2426 | 2428 | 0.35 2429 | 2431 | 87 2432 | 2434 | 3.81 2435 | 2437 | 0.00 2438 | 2440 | 0.12 2441 | 2443 | 3.81 2444 | 2446 | 6.33 2447 | 2449 | -13.53 2450 |
2454 | 45.00 2455 | 2457 | 0.16 2458 | 2460 | 0.15 2461 | 2463 | 0.16 2464 | 2466 | 0.16 2467 | 2469 | 0.00 2470 | 2472 | 0.03 2473 | 2475 | 0.04 2476 | 2478 | 0.01 2479 | 2481 | 10 2482 | 2484 | 20 2485 | 2487 | 33.1 2488 | 2490 | 2.0 2491 | 2493 | -24.9 2494 | 2496 | 3.07 2497 | 2499 | 0.26 2500 | 2502 | 89 2503 | 2505 | 5.02 2506 | 2508 | 0.00 2509 | 2511 | 0.16 2512 | 2514 | 5.02 2515 | 2517 | 8.28 2518 | 2520 | -11.64 2521 |
2525 | 46.00 2526 | 2528 | 0.21 2529 | 2531 | 0.21 2532 | 2534 | 0.22 2535 | 2537 | 0.23 2538 | 2540 | 0.00 2541 | 2543 | 0.04 2544 | 2546 | 0.06 2547 | 2549 | 0.01 2550 | 2552 | 15 2553 | 2555 | 28 2556 | 2558 | 31.3 2559 | 2561 | 2.1 2562 | 2564 | -24.7 2565 | 2567 | 3.55 2568 | 2570 | 0.37 2571 | 2573 | 91 2574 | 2576 | 6.97 2577 | 2579 | 0.00 2580 | 2582 | 0.22 2583 | 2585 | 6.97 2586 | 2588 | 11.14 2589 | 2591 | -9.79 2592 |
2596 | 47.00 2597 | 2599 | 0.34 2600 | 2602 | 0.31 2603 | 2605 | 0.32 2606 | 2608 | 0.33 2609 | 2611 | 0.00 2612 | 2614 | 0.05 2615 | 2617 | 0.08 2618 | 2620 | 0.02 2621 | 2623 | 1 2624 | 2626 | 235 2627 | 2629 | 29.6 2630 | 2632 | 2.3 2633 | 2635 | -24.0 2636 | 2638 | 4.17 2639 | 2641 | 0.26 2642 | 2644 | 93 2645 | 2647 | 9.91 2648 | 2650 | 0.00 2651 | 2653 | 0.32 2654 | 2656 | 9.91 2657 | 2659 | 14.90 2660 | 2662 | -8.02 2663 |
2667 | 48.00 2668 | 2670 | 0.56 2671 | 2673 | 0.47 2674 | 2676 | 0.48 2677 | 2679 | 0.49 2680 | 2682 | 0.00 2683 | 2685 | 0.07 2686 | 2688 | 0.11 2689 | 2691 | 0.02 2692 | 2694 | 38 2695 | 2697 | 80 2698 | 2700 | 28.5 2701 | 2703 | 2.5 2704 | 2706 | -22.9 2707 | 2709 | 4.95 2710 | 2712 | 0.18 2713 | 2715 | 95 2716 | 2718 | 14.53 2719 | 2721 | 0.00 2722 | 2724 | 0.48 2725 | 2727 | 14.53 2728 | 2730 | 19.90 2731 | 2733 | -6.36 2734 |
2738 | 49.00 2739 | 2741 | 0.75 2742 | 2744 | 0.70 2745 | 2747 | 0.71 2748 | 2750 | 0.72 2751 | 2753 | 0.00 2754 | 2756 | 0.11 2757 | 2759 | 0.14 2760 | 2762 | 0.02 2763 | 2765 | 13 2766 | 2768 | 360 2769 | 2771 | 27.2 2772 | 2774 | 2.8 2775 | 2777 | -21.3 2778 | 2780 | 6.04 2781 | 2783 | 0.13 2784 | 2786 | 97 2787 | 2789 | 21.00 2790 | 2792 | 0.00 2793 | 2795 | 0.71 2796 | 2798 | 21.00 2799 | 2801 | 25.40 2802 | 2804 | -4.85 2805 |
2809 | 50.00 2810 | 2812 | 1.23 2813 | 2815 | 1.04 2816 | 2818 | 1.05 2819 | 2821 | 1.06 2822 | 2824 | 0.00 2825 | 2827 | 0.14 2828 | 2830 | 0.17 2831 | 2833 | 0.02 2834 | 2836 | 654 2837 | 2839 | 527 2840 | 2842 | 26.5 2843 | 2845 | 3.3 2846 | 2848 | -19.4 2849 | 2851 | 7.49 2852 | 2854 | 0.10 2855 | 2857 | 99 2858 | 2860 | 30.34 2861 | 2863 | 0.00 2864 | 2866 | 1.05 2867 | 2869 | 30.34 2870 | 2872 | 31.34 2873 | 2875 | -3.55 2876 |
2880 | 51.00 2881 | 2883 | 1.58 2884 | 2886 | 1.50 2887 | 2889 | 1.51 2890 | 2892 | 1.52 2893 | 2895 | 0.00 2896 | 2898 | 0.19 2899 | 2901 | 0.21 2902 | 2904 | 0.02 2905 | 2907 | 72 2908 | 2910 | 506 2911 | 2913 | 26.0 2914 | 2916 | 4.0 2917 | 2919 | -17.3 2920 | 2922 | 9.49 2923 | 2925 | 0.08 2926 | 2928 | 100 2929 | 2931 | 42.60 2932 | 2934 | 0.25 2935 | 2937 | 1.26 2938 | 2940 | 35.63 2941 | 2943 | 36.87 2944 | 2946 | -2.48 2947 |
2951 | 52.00 2952 | 2954 | 2.18 2955 | 2957 | 2.09 2958 | 2960 | 2.10 2961 | 2963 | 2.11 2964 | 2966 | 0.00 2967 | 2969 | 0.24 2970 | 2972 | 0.25 2973 | 2975 | 0.02 2976 | 2978 | 34 2979 | 2981 | 134 2982 | 2984 | 25.9 2985 | 2987 | 5.2 2988 | 2990 | -15.2 2991 | 2993 | 12.26 2994 | 2996 | 0.06 2997 | 2999 | 102 3000 | 3002 | 57.80 3003 | 3005 | 1.25 3006 | 3008 | 0.85 3009 | 3011 | 23.67 3012 | 3014 | 41.45 3015 | 3017 | -1.67 3018 |
3022 | 53.00 3023 | 3025 | 3.10 3026 | 3028 | 2.78 3029 | 3031 | 2.81 3032 | 3034 | 2.83 3035 | 3037 | 0.00 3038 | 3040 | 0.29 3041 | 3043 | 0.28 3044 | 3046 | 0.01 3047 | 3049 | 1 3050 | 3052 | 32 3053 | 3055 | 25.9 3056 | 3058 | 7.4 3059 | 3061 | -13.2 3062 | 3064 | 16.13 3065 | 3067 | 0.14 3068 | 3070 | 104 3071 | 3073 | 75.29 3074 | 3076 | 2.25 3077 | 3079 | 0.56 3080 | 3082 | 15.21 3083 | 3085 | 44.90 3086 | 3088 | -1.09 3089 |
3093 | 54.00 3094 | 3096 | 4.05 3097 | 3099 | 3.55 3100 | 3102 | 3.60 3103 | 3105 | 3.65 3106 | 3108 | 0.00 3109 | 3111 | 0.35 3112 | 3114 | 0.31 3115 | 3117 | 0.00 3118 | 3120 | 6 3121 | 3123 | 82 3124 | 3126 | 26.0 3127 | 3129 | 16.1 3130 | 3132 | -11.4 3133 | 3135 | 21.92 3136 | 3138 | 0.24 3139 | 3141 | 106 3142 | 3144 | 94.23 3145 | 3147 | 3.25 3148 | 3150 | 0.35 3151 | 3153 | 9.43 3154 | 3156 | 47.30 3157 | 3159 | -0.69 3160 |
3164 | 55.00 3165 | 3167 | 4.50 3168 | 3170 | 4.40 3171 | 3173 | 4.45 3174 | 3176 | 4.50 3177 | 3179 | 0.00 3180 | 3182 |   3183 | 3185 |   3186 | 3188 |   3189 | 3191 | 34 3192 | 3194 | 35 3195 | 3197 | 25.7 3198 | 3200 |   3201 | 3203 | -10.0 3204 | 3206 | 32.10 3207 | 3209 | 0.22 3210 | 3212 | 108 3213 | 3215 | 113.59 3216 | 3218 | 4.25 3219 | 3221 | 0.20 3222 | 3224 | 5.30 3225 | 3227 | 49.00 3228 | 3230 | -0.39 3231 |
3235 | 56.00 3236 | 3238 | 5.70 3239 | 3241 | 5.30 3242 | 3244 | 5.38 3245 | 3247 | 5.45 3248 | 3250 | 0.00 3251 | 3253 |   3254 | 3256 |   3257 | 3259 |   3260 | 3262 | 4 3263 | 3265 | 33 3266 | 3268 | 26.5 3269 | 3271 |   3272 | 3274 | -8.7 3275 | 3277 | 43.23 3278 | 3280 | 0.32 3281 | 3283 | 110 3284 | 3286 | 133.81 3287 | 3289 | 5.25 3290 | 3292 | 0.13 3293 | 3295 | 3.26 3296 | 3298 | 49.96 3299 | 3301 | -0.25 3302 |
3306 | 57.00 3307 | 3309 | 6.20 3310 | 3312 | 6.25 3313 | 3315 | 6.33 3316 | 3318 | 6.40 3319 | 3321 | 0.00 3322 | 3324 |   3325 | 3327 |   3328 | 3330 |   3331 | 3333 | 44 3334 | 3336 | 44 3337 | 3339 | 26.7 3340 | 3342 |   3343 | 3345 | -7.6 3346 | 3348 | 63.70 3349 | 3351 | 0.31 3352 | 3354 | 112 3355 | 3357 | 153.63 3358 | 3360 | 6.25 3361 | 3363 | 0.08 3364 | 3366 | 1.92 3367 | 3369 | 50.55 3370 | 3372 | -0.15 3373 |
3377 | 58.00 3378 | 3380 | N/A 3381 | 3383 | 7.25 3384 | 3386 | 7.30 3387 | 3389 | 7.35 3390 | 3392 | 0.00 3393 | 3395 |   3396 | 3398 |   3399 | 3401 |   3402 | 3404 | 0 3405 | 3407 | 0 3408 | 3410 | 27.8 3411 | 3413 |   3414 | 3416 | -6.7 3417 | 3419 | 83.53 3420 | 3422 | 0.20 3423 | 3425 | 114 3426 | 3428 | 173.08 3429 | 3431 | 7.25 3432 | 3434 | 0.05 3435 | 3437 | 1.26 3438 | 3440 | 50.91 3441 | 3443 | -0.10 3444 |
3448 | 59.00 3449 | 3451 | N/A 3452 | 3454 | 8.25 3455 | 3457 | 8.30 3458 | 3460 | 8.35 3461 | 3463 | 0.00 3464 | 3466 |   3467 | 3469 |   3470 | 3472 |   3473 | 3475 | 0 3476 | 3478 | 0 3479 | 3481 | 30.7 3482 | 3484 |   3485 | 3487 | -5.9 3488 | 3490 | 80.81 3491 | 3493 | 0.20 3494 | 3496 | 116 3497 | 3499 | 192.17 3500 | 3502 | 8.25 3503 | 3505 | 0.05 3506 | 3508 | 1.24 3509 | 3511 | 51.11 3512 | 3514 | -0.10 3515 |
3519 | 60.00 3520 | 3522 | N/A 3523 | 3525 | 9.20 3526 | 3528 | 9.28 3529 | 3531 | 9.35 3532 | 3534 | 0.00 3535 | 3537 |   3538 | 3540 |   3541 | 3543 |   3544 | 3546 | 0 3547 | 3549 | 0 3550 | 3552 | 30.0 3553 | 3555 |   3556 | 3558 | -5.4 3559 | 3561 | 140.41 3562 | 3564 | 0.30 3565 | 3567 | 118 3568 | 3570 | 209.86 3571 | 3573 | 9.25 3574 | 3576 | 0.03 3577 | 3579 | 0.61 3580 | 3582 | 51.31 3583 | 3585 | -0.05 3586 |
3590 | 61.00 3591 | 3593 | 11.40 3594 | 3596 | 10.20 3597 | 3599 | 10.28 3600 | 3602 | 10.35 3603 | 3605 | 0.00 3606 | 3608 |   3609 | 3611 |   3612 | 3614 |   3615 | 3617 | 23 3618 | 3620 | 23 3621 | 3623 | 32.5 3624 | 3626 |   3627 | 3629 | -4.9 3630 | 3632 | 137.37 3633 | 3635 | 0.30 3636 | 3638 | 120 3639 | 3641 | 227.28 3642 | 3644 | 10.25 3645 | 3647 | 0.03 3648 | 3650 | 0.60 3651 | 3653 | 51.46 3654 | 3656 | -0.05 3657 |
3661 | 3662 | 3663 | --------------------------------------------------------------------------------