greeks 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +47 -0
- data/greeks.gemspec +2 -5
- data/lib/greeks/calculations/delta.rb +4 -2
- data/lib/greeks/calculations/gamma.rb +3 -2
- data/lib/greeks/calculations/iv.rb +5 -3
- data/lib/greeks/calculations/rho.rb +3 -2
- data/lib/greeks/calculations/theta.rb +3 -2
- data/lib/greeks/calculations/vega.rb +3 -2
- data/lib/greeks.rb +52 -20
- data/spec/greeks/calculations/delta_spec.rb +17 -2
- data/spec/greeks/calculations/gamma_spec.rb +15 -1
- data/spec/greeks/calculations/iv_spec.rb +46 -0
- data/spec/greeks/calculations/rho_spec.rb +17 -2
- data/spec/greeks/calculations/theta_spec.rb +14 -0
- data/spec/greeks/calculations/vega_spec.rb +14 -0
- data/spec/spec_helper.rb +0 -1
- metadata +3 -4
- data/lib/greeks/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ad37eae3c2ce021e59725e537dc1b77d8ee2eab
|
4
|
+
data.tar.gz: 555eb9d63d90e5765dada93c6c28d402c6c48298
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 826582e8578e102704518e97a18c4d0d54e3e4bc3dd0f3d53981557b4499c657692d55cc736076623e05082f33be01c7f9e6955e9a5880fe9bd5c876b5ad8d4f
|
7
|
+
data.tar.gz: 7b172c97033ffacc91d37a6d60b934dd6b9e41a33d61285daa4893e2a4f57c881aa09d2092480f69a04ca8e9909965450195b3c709d58a3683ac607eae975d60
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
greeks (1.
|
5
|
-
hash_plus
|
4
|
+
greeks (1.1)
|
5
|
+
hash_plus (>= 1.3)
|
6
6
|
require_all
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
diff-lcs (1.2.4)
|
12
|
-
hash_plus (1.
|
12
|
+
hash_plus (1.3)
|
13
13
|
require_all (1.2.1)
|
14
14
|
rspec (2.13.0)
|
15
15
|
rspec-core (~> 2.13.0)
|
data/README.md
CHANGED
@@ -2,3 +2,50 @@ greeks
|
|
2
2
|
======
|
3
3
|
|
4
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
|
+
```
|
data/greeks.gemspec
CHANGED
@@ -1,17 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "greeks/version"
|
4
2
|
|
5
3
|
Gem::Specification.new do |gem|
|
6
4
|
gem.name = "greeks"
|
7
|
-
gem.version =
|
5
|
+
gem.version = '1.1'
|
8
6
|
gem.authors = ["Glenn Nagel"]
|
9
7
|
gem.email = ["glenn@mercury-wireless.com"]
|
10
8
|
gem.homepage = "https://github.com/gnagel/greeks"
|
11
9
|
gem.summary = %q{Calculate greeks for options trading (Implied Volatility, Delta, Gamma, Vega, Rho, and Theta)}
|
12
10
|
gem.description = %q{Calculate greeks (iv, delta, gamma, vega, rho, theta)}
|
13
11
|
gem.license = 'MIT'
|
14
|
-
|
15
12
|
|
16
13
|
gem.files = `git ls-files`.split($/)
|
17
14
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -20,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
20
17
|
|
21
18
|
# System
|
22
19
|
gem.add_dependency('require_all')
|
23
|
-
gem.add_dependency('hash_plus')
|
20
|
+
gem.add_dependency('hash_plus', '>= 1.3')
|
24
21
|
|
25
22
|
gem.add_development_dependency('rspec')
|
26
23
|
gem.add_development_dependency('rspec-expectations')
|
@@ -10,9 +10,11 @@ module Math
|
|
10
10
|
# change in the option price for a one-percent change in the underlying security; this method of viewing the delta value
|
11
11
|
# is also known as "leverage."
|
12
12
|
def delta(opts)
|
13
|
-
opts.
|
14
|
-
|
13
|
+
opts.requires_keys_are_present(:iv)
|
15
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
|
+
|
16
18
|
|
17
19
|
multiplier = case opts[:option_type]
|
18
20
|
when :call
|
@@ -9,10 +9,11 @@ module Math
|
|
9
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
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
11
|
def gamma(opts = {})
|
12
|
-
opts.
|
13
|
-
|
12
|
+
opts.requires_keys_are_present(:iv)
|
14
13
|
return nil if opts[:iv].nil?
|
15
14
|
|
15
|
+
opts.requires_keys_are_not_nil(:stock_price, :option_expires_pct_year_sqrt, :nd1, :rate_vs_expires, :iv)
|
16
|
+
|
16
17
|
opts[:nd1] * opts[:rate_vs_expires] / (opts[:stock_price] * opts[:iv] * opts[:option_expires_pct_year_sqrt])
|
17
18
|
end
|
18
19
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module Math
|
2
2
|
module GreekCalculations
|
3
3
|
def iv(opts)
|
4
|
-
opts.
|
5
|
-
|
6
|
-
return nil if opts[:option_price]
|
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)
|
7
9
|
|
8
10
|
iv_calc(
|
9
11
|
opts[:stock_price],
|
@@ -4,9 +4,10 @@ module Math
|
|
4
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
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
6
|
def rho(opts = {})
|
7
|
-
opts.
|
8
|
-
|
7
|
+
opts.requires_keys_are_present(:iv)
|
9
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)
|
10
11
|
|
11
12
|
multiplier = case opts[:option_type]
|
12
13
|
when :call
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Math
|
2
2
|
module GreekCalculations
|
3
3
|
def theta(opts = {})
|
4
|
-
opts.
|
5
|
-
|
4
|
+
opts.requires_keys_are_present(:iv)
|
6
5
|
return nil if opts[:iv].nil?
|
7
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
|
+
|
8
9
|
part0 = opts[:price_vs_rate_vs_expires] * opts[:nd1] * opts[:iv]
|
9
10
|
part1 = 2 * opts[:option_expires_pct_year_sqrt]
|
10
11
|
part2 = opts[:stock_dividend_rate_f] * opts[:price_vs_rate_vs_expires] * opts[:d1_normal_distribution]
|
@@ -7,9 +7,10 @@ module Math
|
|
7
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
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
9
|
def vega(opts = {})
|
10
|
-
opts.
|
11
|
-
|
10
|
+
opts.requires_keys_are_present(:iv)
|
12
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)
|
13
14
|
|
14
15
|
opts[:price_vs_rate_vs_expires] * opts[:option_expires_pct_year_sqrt] * opts[:nd1] / 100
|
15
16
|
end
|
data/lib/greeks.rb
CHANGED
@@ -9,7 +9,6 @@ require_relative 'greeks/calculations/theta'
|
|
9
9
|
require_relative 'greeks/calculations/rho'
|
10
10
|
require_relative 'greeks/calculations/vega'
|
11
11
|
require_relative 'greeks/calculations/time_values'
|
12
|
-
require_relative 'greeks/version'
|
13
12
|
|
14
13
|
|
15
14
|
module Math
|
@@ -290,23 +289,15 @@ module Math
|
|
290
289
|
:option_type => option_type,
|
291
290
|
:option_strike => option_strike,
|
292
291
|
:option_price => option_price,
|
293
|
-
:break_even
|
294
|
-
:iv
|
295
|
-
:delta
|
296
|
-
:gamma
|
297
|
-
:vega
|
298
|
-
:rho
|
299
|
-
:theta
|
300
|
-
:deta_vs_theta
|
292
|
+
:break_even => (NilMath.new(break_even) * 100.0).to_f, # break_even * 100
|
293
|
+
:iv => (NilMath.new(iv) * 100.0).to_f, # iv * 100
|
294
|
+
:delta => (NilMath.new(delta) * stock_price / option_price).to_f, # delta * stock_price / option_price
|
295
|
+
:gamma => (NilMath.new(gamma) * stock_price / delta).to_f, # gamma * stock_price / delta
|
296
|
+
:vega => (NilMath.new(vega) * 100.0 * iv / option_price).to_f, # vega * iv * 100 / option_price
|
297
|
+
:rho => (NilMath.new(rho) * 100.0 / option_price).to_f, # rho * 100 / option_price
|
298
|
+
:theta => (NilMath.new(theta) * 100.0 / option_price).to_f, # theta * 100 / option_price
|
299
|
+
:deta_vs_theta => nil,
|
301
300
|
}
|
302
|
-
hash[:break_even] = break_even * 100 unless break_even.nil?
|
303
|
-
hash[:iv] = iv * 100 unless iv.nil?
|
304
|
-
hash[:delta] = delta * stock_price / option_price unless delta.nil?
|
305
|
-
hash[:gamma] = gamma * stock_price / delta unless gamma.nil?
|
306
|
-
hash[:vega] = vega * iv * 100 / option_price unless vega.nil?
|
307
|
-
hash[:rho] = rho * 100 / option_price unless rho.nil?
|
308
|
-
hash[:theta] = theta * 100 / option_price unless theta.nil?
|
309
|
-
|
310
301
|
|
311
302
|
# Delta/Theta
|
312
303
|
# A measure of the “bang for the buck” of an option.
|
@@ -314,9 +305,10 @@ module Math
|
|
314
305
|
# decay rate, the trend in the Delta/Theta column indicates which options give the most exposure
|
315
306
|
# to the movement of the underlying stock or index for a given decay rate of the option value.
|
316
307
|
# The highest numbers indicate the most bang for the buck for the least decay rate.
|
317
|
-
hash[:deta_vs_theta] = hash[:delta] / hash[:theta]
|
318
|
-
|
319
|
-
|
308
|
+
hash[:deta_vs_theta] = (NilMath.new(hash[:delta]) / hash[:theta]).to_f
|
309
|
+
|
310
|
+
# Iterate the generated columns and round the output
|
311
|
+
[:break_even, :iv, :delta, :gamma, :vega, :rho, :theta, :deta_vs_theta].each do |key|
|
320
312
|
hash[key] &&= hash[key].round(2)
|
321
313
|
end
|
322
314
|
|
@@ -366,6 +358,46 @@ module Math
|
|
366
358
|
@nd1 ||= GreekCalculations.misc_nd1(:d1 => d1)
|
367
359
|
end
|
368
360
|
|
361
|
+
class NilMath
|
362
|
+
def initialize(value)
|
363
|
+
@value = value
|
364
|
+
end
|
365
|
+
|
366
|
+
def to_f
|
367
|
+
@value
|
368
|
+
end
|
369
|
+
|
370
|
+
def *(input)
|
371
|
+
multiply(input)
|
372
|
+
end
|
373
|
+
|
374
|
+
def /(input)
|
375
|
+
divide(input)
|
376
|
+
end
|
377
|
+
|
378
|
+
def multiply(input)
|
379
|
+
if (@value.nil? || input.nil?)
|
380
|
+
@value = nil
|
381
|
+
else
|
382
|
+
@value *= input
|
383
|
+
end
|
384
|
+
self
|
385
|
+
end
|
386
|
+
|
387
|
+
def multiply100()
|
388
|
+
multiply(100.0)
|
389
|
+
end
|
390
|
+
|
391
|
+
def divide(input)
|
392
|
+
if (@value.nil? || input.nil?)
|
393
|
+
@value = nil
|
394
|
+
else
|
395
|
+
@value /= input
|
396
|
+
end
|
397
|
+
self
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
369
401
|
end
|
370
402
|
end
|
371
403
|
end
|
@@ -4,6 +4,21 @@ describe "Math::GreekCalculations::delta" do
|
|
4
4
|
extend Math::GreekCalculations
|
5
5
|
include Math::GreekCalculations
|
6
6
|
|
7
|
-
|
8
|
-
|
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
|
9
24
|
end
|
@@ -4,5 +4,19 @@ describe "Math::GreekCalculations::gamma" do
|
|
4
4
|
extend Math::GreekCalculations
|
5
5
|
include Math::GreekCalculations
|
6
6
|
|
7
|
-
|
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
|
8
22
|
end
|
@@ -5,10 +5,56 @@ describe "Math::GreekCalculations::iv" do
|
|
5
5
|
include Math::GreekCalculations
|
6
6
|
include Math::GreekCalculationHelpers
|
7
7
|
|
8
|
+
##
|
9
|
+
# General behavior tests
|
10
|
+
##
|
11
|
+
it { opts = {:a => :b}; expect { iv(opts) }.to raise_error ArgumentError, "Missing keys=option_price in opts={:a=>:b}" }
|
12
|
+
|
13
|
+
it { iv(:option_price => nil).should be_nil }
|
14
|
+
|
15
|
+
it {
|
16
|
+
iv(
|
17
|
+
:federal_reserve_interest_rate_f => 0.0,
|
18
|
+
:stock_price => 10.00,
|
19
|
+
:stock_dividend_rate_f => 0.0,
|
20
|
+
:option_type => :call,
|
21
|
+
:option_price => 1.0,
|
22
|
+
:option_strike => 10.00,
|
23
|
+
:option_expires_pct_year => 1.0,
|
24
|
+
:option_expires_pct_year_sqrt => 1.0,
|
25
|
+
:rate_vs_expires => 1.0,
|
26
|
+
:price_vs_rate_vs_expires => 1.0,
|
27
|
+
:strike_vs_fed_vs_expires => 1.0,
|
28
|
+
:price_ratio_log_less_rates => 1.0,
|
29
|
+
).should === 21453795590575736000000.0
|
30
|
+
}
|
31
|
+
|
32
|
+
it {
|
33
|
+
iv(
|
34
|
+
:federal_reserve_interest_rate_f => 0.0,
|
35
|
+
:stock_price => 10.00,
|
36
|
+
:stock_dividend_rate_f => 0.0,
|
37
|
+
:option_type => :put,
|
38
|
+
:option_price => 1.0,
|
39
|
+
:option_strike => 10.00,
|
40
|
+
:option_expires_pct_year => 1.0,
|
41
|
+
:option_expires_pct_year_sqrt => 1.0,
|
42
|
+
:rate_vs_expires => 1.0,
|
43
|
+
:price_vs_rate_vs_expires => 1.0,
|
44
|
+
:strike_vs_fed_vs_expires => 1.0,
|
45
|
+
:price_ratio_log_less_rates => 1.0,
|
46
|
+
).should === 21453795590575736000000.0
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
##
|
51
|
+
# More specific examples
|
52
|
+
##
|
8
53
|
let(:stock_price) { 10.00 }
|
9
54
|
let(:stock_dividend_rate) { 0.0 }
|
10
55
|
let(:stock_dividend_rate_f) { 0.0 }
|
11
56
|
|
57
|
+
let(:option_strike) { 10.00 }
|
12
58
|
let(:option_price) { 1.00 }
|
13
59
|
let(:option_expires_in_days) { 364.0 }
|
14
60
|
let(:option_expires_pct_year) { 1.0 }
|
@@ -4,6 +4,21 @@ describe "Math::GreekCalculations::rho" do
|
|
4
4
|
extend Math::GreekCalculations
|
5
5
|
include Math::GreekCalculations
|
6
6
|
|
7
|
-
|
8
|
-
|
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
|
9
24
|
end
|
@@ -4,6 +4,20 @@ describe "Math::GreekCalculations::theta" do
|
|
4
4
|
extend Math::GreekCalculations
|
5
5
|
include Math::GreekCalculations
|
6
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
|
+
##
|
7
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 }
|
8
22
|
|
9
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 }
|
@@ -4,6 +4,20 @@ describe "Math::GreekCalculations::vega" do
|
|
4
4
|
extend Math::GreekCalculations
|
5
5
|
include Math::GreekCalculations
|
6
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
|
+
##
|
7
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 }
|
8
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 }
|
9
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 }
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: greeks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Glenn Nagel
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.3'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,7 +87,6 @@ files:
|
|
87
87
|
- lib/greeks/calculations/theta.rb
|
88
88
|
- lib/greeks/calculations/time_values.rb
|
89
89
|
- lib/greeks/calculations/vega.rb
|
90
|
-
- lib/greeks/version.rb
|
91
90
|
- spec/greeks/calculations/delta_spec.rb
|
92
91
|
- spec/greeks/calculations/gamma_spec.rb
|
93
92
|
- spec/greeks/calculations/iv_option_price_spec.rb
|