greeks 1.2 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ce6ee63e7be1cf00d2a33bf5fabc7384edbd151
4
- data.tar.gz: 319eddb79151564febe9384bb402057f78e3c4d6
3
+ metadata.gz: 2ed185ec81ab234f6465a7a78a435ddfcd7055d6
4
+ data.tar.gz: 624f32c01e177d5cb626f081f5ed7068bc1d31bd
5
5
  SHA512:
6
- metadata.gz: cc93e88a7ef6f8096a0c18c003faf6005ee46f11e7eb7d77b0539b367c8fecb99266a315896d18b0ab866860f471cfd8073ef0de9167f1a64ae6829b092aaa64
7
- data.tar.gz: 359124006d77696012957a0c4633632ef62ab1dd67c64041b67d41fb93b6e481f2bedeb15cd370e11ff1ec5991f5a2fd2417c6029f66eed7fa788ebb1ecfcef3
6
+ metadata.gz: 3f0accecffdf8324a71297cc584b1d6fb53100c9a4f1cf9b48a52b0bf1c657e6cdce8d5a4ad12d82ca0ca0cd6af601ce833f33bf2b9c79a1db39a08a2e48e509
7
+ data.tar.gz: edafcc4521dbb21879e0ed7a575f61fb5616b818f03620d7054d47d5181383f09dbcfcb4d234c1d9347c034defa0dd84298f80350026f53328df534a3e5db32b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- greeks (1.1)
4
+ greeks (1.2)
5
5
  hash_plus (>= 1.3)
6
6
  require_all
7
7
 
data/greeks-1.1.gem ADDED
Binary file
data/greeks.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = "greeks"
5
- gem.version = '1.2'
5
+ gem.version = '1.3'
6
6
  gem.authors = ["Glenn Nagel"]
7
7
  gem.email = ["glenn@mercury-wireless.com"]
8
8
  gem.homepage = "https://github.com/gnagel/greeks"
@@ -2,7 +2,7 @@ module Math
2
2
  module GreekCalculations
3
3
 
4
4
  def nil_or_gte0(value)
5
- value.nil? || value.to_f < 0 ? nil : value
5
+ value.nil? || value.to_f < 0.0 ? nil : value
6
6
  end
7
7
 
8
8
 
@@ -15,14 +15,16 @@ module Math
15
15
  def premium_value(opts)
16
16
  opts.requires_fields(:option_type, :option_strike, :stock_price)
17
17
 
18
- case opts[:option_type]
18
+ value = case opts[:option_type]
19
19
  when :call
20
- return [opts[:stock_price] - opts[:option_strike], 0].max
20
+ [opts[:stock_price] - opts[:option_strike], 0].max
21
21
  when :put
22
- return [opts[:option_strike] - opts[:stock_price], 0].max
22
+ [opts[:option_strike] - opts[:stock_price], 0].max
23
23
  else
24
24
  raise ArgumentError, "Invalid option_type = #{opts[:option_type]}"
25
25
  end
26
+
27
+ nil_or_gte0(value)
26
28
  end
27
29
 
28
30
 
@@ -34,10 +36,8 @@ module Math
34
36
  # of $35 were trading for $7, the call would have a $5 intrinsic value ($40-$35) and a $2 time value ($7-$5).
35
37
  # Time value will decay by expiration assuming the underlying security stays at the same price.
36
38
  def time_value(opts)
37
- opts.requires_fields(:option_price, :premium_value)
38
-
39
- return nil if opts[:option_price].nil?
40
- return nil if opts[:option_price] < 0
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
41
 
42
42
  nil_or_gte0(opts[:option_price] - opts[:premium_value])
43
43
  end
@@ -48,11 +48,10 @@ module Math
48
48
  # premium to develop an intuitive understanding of how much the market is "paying" for a dollar of risk.
49
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
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
52
- opts.requires_fields(:option_price, :option_strike, :option_expires_pct_year)
53
-
51
+ def annualized_premium_value(opts)
54
52
  return nil if opts[:option_price].nil?
55
53
  return nil if opts[:option_price] < 0
54
+ opts.requires_fields(:option_price, :option_strike, :option_expires_pct_year)
56
55
 
57
56
  nil_or_gte0(100 * Math.log(1 + opts[:option_price] / opts[:option_strike]) / opts[:option_expires_pct_year])
58
57
  end
@@ -65,10 +64,9 @@ module Math
65
64
  # six month call on that stock with a strike price of $35 has an intrinsic value of $5 and a total
66
65
  # value of $7, the time value ($2) divided by the strike is ($2/$40) = 5%. Annualizing that time value
67
66
  # to a one year horizon on a continuously compounded basis yields 9.76% (2 × ln(1 + 0.05)).
68
- def annualized_time_value
67
+ def annualized_time_value(opts)
68
+ return nil if opts[:time_value].nil? || opts[:time_value] < 0
69
69
  opts.requires_fields(:option_strike, :option_expires_pct_year, :time_value)
70
-
71
- return nil if opts[:time_value].nil?
72
70
 
73
71
  nil_or_gte0(100 * Math.log(1.0 + opts[:time_value] / opts[:option_strike]) / opts[:option_expires_pct_year])
74
72
  end
data/lib/greeks.rb CHANGED
@@ -34,6 +34,10 @@ module Math
34
34
  attr_reader :price_vs_rate_vs_expires
35
35
  attr_reader :strike_vs_fed_vs_expires
36
36
  attr_reader :price_ratio_log_less_rates
37
+
38
+ # Optional fields
39
+ attr_reader :option_volume
40
+ attr_reader :option_open_interest
37
41
 
38
42
 
39
43
  def initialize(opts)
@@ -50,6 +54,9 @@ module Math
50
54
  @option_expires_pct_year = (option_expires_in_days + 1.0) / 365.0
51
55
  @option_expires_pct_year_sqrt = Math.sqrt(option_expires_pct_year)
52
56
 
57
+ @option_volume = opts[:option_volume]
58
+ @option_open_interest = opts[:option_open_interest]
59
+
53
60
 
54
61
  @price_vs_rate_vs_expires = GreekCalculations.misc_price_vs_rate_vs_expires(
55
62
  :stock_price => stock_price,
@@ -281,7 +288,8 @@ module Math
281
288
 
282
289
 
283
290
  def to_hash
284
- hash = {
291
+ return @hash if @hash
292
+ @hash = {
285
293
  :federal_reserve_interest_rate => federal_reserve_interest_rate,
286
294
  :stock_dividend_rate => stock_dividend_rate,
287
295
  :stock_price => stock_price,
@@ -289,13 +297,19 @@ module Math
289
297
  :option_type => option_type,
290
298
  :option_strike => option_strike,
291
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,
292
306
  :iv => (NilMath.new(iv) * 100.0).to_f, # iv * 100
293
307
  :delta => (NilMath.new(delta) * stock_price / option_price).to_f, # delta * stock_price / option_price
294
308
  :gamma => (NilMath.new(gamma) * stock_price / delta).to_f, # gamma * stock_price / delta
295
309
  :vega => (NilMath.new(vega) * 100.0 * iv / option_price).to_f, # vega * iv * 100 / option_price
296
310
  :rho => (NilMath.new(rho) * 100.0 / option_price).to_f, # rho * 100 / option_price
297
311
  :theta => (NilMath.new(theta) * 100.0 / option_price).to_f, # theta * 100 / option_price
298
- :deta_vs_theta => nil,
312
+ :delta_vs_theta => nil,
299
313
  :break_even => (NilMath.new(break_even) * 100.0).to_f, # break_even * 100
300
314
  }
301
315
 
@@ -305,14 +319,18 @@ module Math
305
319
  # decay rate, the trend in the Delta/Theta column indicates which options give the most exposure
306
320
  # to the movement of the underlying stock or index for a given decay rate of the option value.
307
321
  # The highest numbers indicate the most bang for the buck for the least decay rate.
308
- hash[:deta_vs_theta] = (NilMath.new(hash[:delta]) / hash[:theta]).to_f
322
+ @hash[:delta_vs_theta] = (NilMath.new(@hash[:delta]) / @hash[:theta]).to_f
309
323
 
310
324
  # Iterate the generated columns and round the output
311
- [:break_even, :iv, :delta, :gamma, :vega, :rho, :theta, :deta_vs_theta].each do |key|
312
- hash[key] &&= hash[key].round(2)
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)
313
331
  end
314
332
 
315
- hash
333
+ @hash
316
334
  end
317
335
 
318
336
 
@@ -0,0 +1 @@
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
@@ -0,0 +1 @@
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
@@ -0,0 +1 @@
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
@@ -0,0 +1 @@
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
@@ -3,7 +3,6 @@ require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__))
3
3
  describe "Math::GreekCalculations::iv_option_price" do
4
4
  include Math
5
5
  include Math::GreekCalculations
6
- include Math::GreekCalculationHelpers
7
6
 
8
7
  let(:stock_price) { 10.00 }
9
8
  let(:stock_dividend_rate_f) { 0.00 }
@@ -3,7 +3,6 @@ require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__))
3
3
  describe "Math::GreekCalculations::iv" do
4
4
  extend Math::GreekCalculations
5
5
  include Math::GreekCalculations
6
- include Math::GreekCalculationHelpers
7
6
 
8
7
  ##
9
8
  # General behavior tests
@@ -3,7 +3,6 @@ require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__))
3
3
  describe "Math::GreekCalculations::iv_vega" do
4
4
  include Math
5
5
  include Math::GreekCalculations
6
- include Math::GreekCalculationHelpers
7
6
 
8
7
  let(:stock_price) { 10.00 }
9
8
  let(:stock_dividend_rate_f) { 0.00 }
@@ -3,7 +3,6 @@ require File.expand_path("../../spec_helper.rb", File.dirname(__FILE__))
3
3
  describe "Math::GreekCalculations::misc_price_ratio_log_less_rates" do
4
4
  include Math
5
5
  include Math::GreekCalculations
6
- include Math::GreekCalculationHelpers
7
6
 
8
7
  let(:stock_price) { 10.00 }
9
8
  let(:stock_dividend_rate_f) { 0.00 }
@@ -1,116 +1,42 @@
1
1
  require File.expand_path("../spec_helper.rb", File.dirname(__FILE__))
2
2
 
3
3
  describe Math::Greeks::Calculator do
4
- let(:entity) do
5
- {
6
- :symbol => 'AMD',
7
- :type => :stock,
8
- :date => '2013-05-19',
9
- }
10
- end
11
-
12
- let(:date) { '2013-06-21' }
13
- let(:days) { 35.0 }
14
-
15
- let(:call) do
16
- {
17
- :strike => 4.50,
18
- :bid => 0.16,
19
- :iv => 61.92,
20
- :delta => 8.59,
21
- :gamma => 5.57,
22
- :vega => 1.81,
23
- :rho => 0.75,
24
- :theta => -2.51,
25
- :break_even => 21.38,
26
- }
27
- end
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
28
11
 
29
- let(:put) do
30
- {
31
- :strike => 4.50,
32
- :bid => 0.59,
33
- :iv => 61.93,
34
- :delta => -4.57,
35
- :gamma => -2.84,
36
- :vega => 0.49,
37
- :rho => -0.55,
38
- :theta => -0.68,
39
- :break_even => 45.66,
40
- }
41
- end
42
-
43
- let(:base_opts) do
44
- {
45
- :stock_price => 4.07,
46
- :stock_dividend_rate => 0.00,
47
- :option_expires_in_days => 35.0,
48
- :federal_reserve_interest_rate => 0.01,
49
- :option_type => nil,
50
- :option_price => nil,
51
- :option_strike => nil,
52
- }
53
- end
54
-
55
- context "call option" do
56
- let(:opts) do
57
- base_opts.merge(
58
- :option_type => :call,
59
- :option_price => call[:bid],
60
- :option_strike => call[:strike],
61
- )
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
62
24
  end
25
+ end
63
26
 
64
- subject(:calc) { Math::Greeks::Calculator.new(opts) }
27
+ it "compute call options @ 22 days" do
28
+ compare_csv(22, :call)
29
+ end
65
30
 
66
- it { calc.stock_price.should === opts[:stock_price] }
67
- it { calc.stock_dividend_rate.should === opts[:stock_dividend_rate] }
68
- it { calc.option_type.should === opts[:option_type] }
69
- it { calc.option_price.should === opts[:option_price] }
70
- it { calc.option_strike.should === opts[:option_strike] }
71
- it { calc.option_expires_in_days.should === opts[:option_expires_in_days] }
72
- it { calc.federal_reserve_interest_rate.should === opts[:federal_reserve_interest_rate] }
73
-
74
- it { calc.to_hash[:iv].should === call[:iv] }
75
- it { calc.to_hash[:delta].should === call[:delta] }
76
- it { calc.to_hash[:gamma].should === call[:gamma] }
77
- it { calc.to_hash[:vega].should === call[:vega] }
78
- it { calc.to_hash[:theta].should === call[:theta] }
79
- it { calc.to_hash[:rho].should === call[:rho] }
80
- it { calc.to_hash[:break_even].round(2).should === call[:break_even] }
31
+ it "compute put options @ 22 days" do
32
+ compare_csv(22, :put)
81
33
  end
82
-
83
- context "put option" do
84
- let(:opts) do
85
- base_opts.merge(
86
- :option_type => :put,
87
- :option_price => put[:bid],
88
- :option_strike => put[:strike],
89
- )
90
- end
91
34
 
92
- subject(:calc) { Math::Greeks::Calculator.new(opts) }
35
+ it "compute call options @ 50 days" do
36
+ compare_csv(50, :call)
37
+ end
93
38
 
94
- it { calc.stock_price.should === opts[:stock_price] }
95
- it { calc.stock_dividend_rate.should === opts[:stock_dividend_rate] }
96
- it { calc.option_type.should === opts[:option_type] }
97
- it { calc.option_price.should === opts[:option_price] }
98
- it { calc.option_strike.should === opts[:option_strike] }
99
- it { calc.option_expires_in_days.should === opts[:option_expires_in_days] }
100
- it { calc.federal_reserve_interest_rate.should === opts[:federal_reserve_interest_rate] }
101
-
102
- it { calc.to_hash[:iv].should === put[:iv] }
103
- it { calc.to_hash[:delta].should === put[:delta] }
104
- it { calc.to_hash[:gamma].should === put[:gamma] }
105
- it { calc.to_hash[:vega].should === put[:vega] }
106
- it { calc.to_hash[:theta].should === put[:theta] }
107
- it { calc.to_hash[:rho].should === put[:rho] }
108
- it { calc.to_hash[:break_even].round(2).should === put[:break_even] }
39
+ it "compute put options @ 50 days" do
40
+ compare_csv(50, :put)
109
41
  end
110
-
111
- it {
112
- calculator = Math::Greeks::Calculator.new(:stock_price=>1558.86, :stock_dividend_rate=>0.0, :federal_reserve_interest_rate=>0.0, :option_type=>:call, :option_price=>751.50, :option_strike=>800.00, :option_expires_in_days=>2)
113
- calculator.iv.should be_nil
114
- calculator.to_hash[:iv].should be_nil
115
- }
116
42
  end
@@ -0,0 +1,54 @@
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
data/spec/spec_helper.rb CHANGED
@@ -2,15 +2,29 @@ require 'rubygems'
2
2
  require 'rspec'
3
3
  require 'rspec-expectations'
4
4
  require 'benchmark'
5
+ require 'require_all'
6
+ require 'csv'
5
7
 
6
8
  $:.push File.expand_path("../lib", File.dirname(__FILE__))
7
9
  require 'greeks'
8
10
 
9
11
  $spec_root = File.dirname(__FILE__)
10
12
 
13
+ require_all File.join($spec_root, 'support')
14
+ require_all File.join($spec_root, 'helpers')
15
+
16
+
11
17
  RSpec.configure do |config|
18
+ config.include Math::GreekCalculationShorthandHelpers
19
+
12
20
  old_verbose, $VERBOSE = $VERBOSE, nil
13
21
 
22
+ def verbose_puts(s)
23
+ return unless $VERBOSE
24
+ file = File.basename(caller(1).first)
25
+ super("puts() from #{file}: #{s}")
26
+ end
27
+
14
28
  def puts(s)
15
29
  file = File.basename(caller(1).first)
16
30
  super("puts() from #{file}: #{s}")
@@ -32,57 +46,3 @@ RSpec.configure do |config|
32
46
  @result
33
47
  end
34
48
  end
35
-
36
- module Math
37
- module GreekCalculationHelpers
38
- include Math
39
- include Math::GreekCalculations
40
-
41
- def var_price_ratio_log_less_rates
42
- misc_price_ratio_log_less_rates(
43
- :stock_price => stock_price,
44
- :option_strike => option_strike,
45
- :option_expires_pct_year => option_expires_pct_year,
46
- :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f,
47
- :stock_dividend_rate_f => stock_dividend_rate_f
48
- )
49
- end
50
-
51
- def var_price_vs_rate_vs_expires
52
- misc_price_vs_rate_vs_expires(
53
- :stock_price => stock_price,
54
- :option_expires_pct_year => option_expires_pct_year,
55
- :stock_dividend_rate_f => stock_dividend_rate_f
56
- )
57
- end
58
-
59
- def var_vega
60
- 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)
61
- end
62
-
63
- def var_vega
64
- 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)
65
- end
66
-
67
- def var_option_price
68
- 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))
69
- end
70
-
71
- def var_iv
72
- iv(
73
- :stock_price => stock_price,
74
- :option_strike => option_strike,
75
- :option_expires_pct_year => option_expires_pct_year,
76
- :option_expires_pct_year_sqrt => Math::sqrt(option_expires_pct_year),
77
- :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f,
78
- :stock_dividend_rate_f => stock_dividend_rate_f,
79
- :option_type => option_type,
80
- :option_price => option_price,
81
- :rate_vs_expires => misc_rate_vs_expires(:option_expires_pct_year => option_expires_pct_year, :stock_dividend_rate_f => stock_dividend_rate_f),
82
- :price_vs_rate_vs_expires => var_price_vs_rate_vs_expires,
83
- :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),
84
- :price_ratio_log_less_rates => var_price_ratio_log_less_rates
85
- )
86
- end
87
- end
88
- end
@@ -0,0 +1,39 @@
1
+ require 'rspec'
2
+ require 'rspec-expectations'
3
+
4
+ RSpec::Matchers.define :be_a_greeks_hash do |expected|
5
+ match do |actual|
6
+ hash = actual.to_hash
7
+ hash.should_not be_nil
8
+ hash.should_not be_empty
9
+
10
+ keys = [hash.keys, expected.keys].flatten.uniq.sort
11
+ verbose_puts "Keys: #{keys.inspect}"
12
+ keys.each do |key|
13
+ verbose_puts "[#{"%30s" % key}] Hash: #{hash[key].inspect} vs Actual: #{expected[key].inspect}"
14
+ end
15
+
16
+ # Delete all the values that match
17
+ # This will leave only the values that differ
18
+ expected.keys.dup.each do |key|
19
+ if hash[key] == expected[key]
20
+ expected.delete(key)
21
+ next
22
+ end
23
+
24
+ if hash[key].class == expected[key].class && !hash[key].nil? && !hash[key].is_a?(Symbol) && hash[key].round(1) == expected[key].round(1)
25
+ expected.delete(key)
26
+ next
27
+ end
28
+
29
+ expected[key] = "#{expected.delete(key).inspect}(e) vs #{hash[key].inspect}(a)"
30
+ end
31
+ verbose_puts "Hash: #{hash}"
32
+ verbose_puts "Expected: #{expected}"
33
+ expected.should be_empty
34
+ end
35
+
36
+ failure_message_for_should do |actual|
37
+ "expected that #{actual.to_hash} would match values of #{expected}"
38
+ end
39
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greeks
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: '1.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Glenn Nagel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-29 00:00:00.000000000 Z
11
+ date: 2013-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: require_all
@@ -77,6 +77,7 @@ files:
77
77
  - Gemfile
78
78
  - Gemfile.lock
79
79
  - README.md
80
+ - greeks-1.1.gem
80
81
  - greeks.gemspec
81
82
  - lib/greeks.rb
82
83
  - lib/greeks/calculations/delta.rb
@@ -87,6 +88,10 @@ files:
87
88
  - lib/greeks/calculations/theta.rb
88
89
  - lib/greeks/calculations/time_values.rb
89
90
  - lib/greeks/calculations/vega.rb
91
+ - spec/greeks/22days.calls.csv
92
+ - spec/greeks/22days.puts.csv
93
+ - spec/greeks/50days.calls.csv
94
+ - spec/greeks/50days.puts.csv
90
95
  - spec/greeks/calculations/delta_spec.rb
91
96
  - spec/greeks/calculations/gamma_spec.rb
92
97
  - spec/greeks/calculations/iv_option_price_spec.rb
@@ -98,7 +103,9 @@ files:
98
103
  - spec/greeks/calculations/time_values_spec.rb
99
104
  - spec/greeks/calculations/vega_spec.rb
100
105
  - spec/greeks/greeks_spec.rb
106
+ - spec/helpers/greek_calculation_shorthand_helpers.rb
101
107
  - spec/spec_helper.rb
108
+ - spec/support/calculate_greeks_hash.rb
102
109
  homepage: https://github.com/gnagel/greeks
103
110
  licenses:
104
111
  - MIT
@@ -126,6 +133,10 @@ specification_version: 4
126
133
  summary: Calculate greeks for options trading (Implied Volatility, Delta, Gamma, Vega,
127
134
  Rho, and Theta)
128
135
  test_files:
136
+ - spec/greeks/22days.calls.csv
137
+ - spec/greeks/22days.puts.csv
138
+ - spec/greeks/50days.calls.csv
139
+ - spec/greeks/50days.puts.csv
129
140
  - spec/greeks/calculations/delta_spec.rb
130
141
  - spec/greeks/calculations/gamma_spec.rb
131
142
  - spec/greeks/calculations/iv_option_price_spec.rb
@@ -137,4 +148,6 @@ test_files:
137
148
  - spec/greeks/calculations/time_values_spec.rb
138
149
  - spec/greeks/calculations/vega_spec.rb
139
150
  - spec/greeks/greeks_spec.rb
151
+ - spec/helpers/greek_calculation_shorthand_helpers.rb
140
152
  - spec/spec_helper.rb
153
+ - spec/support/calculate_greeks_hash.rb