greeks 1.2 → 1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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