greeks 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/greeks.rb ADDED
@@ -0,0 +1,371 @@
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
+ require_relative 'greeks/version'
13
+
14
+
15
+ module Math
16
+ module Greeks
17
+ class Calculator
18
+ class GreekCalculations
19
+ extend Math::GreekCalculations
20
+ end
21
+
22
+ attr_reader :stock_price
23
+ attr_reader :stock_dividend_rate
24
+ attr_reader :option_type # :call, or :put
25
+ attr_reader :option_price # bid, mid, or ask
26
+ attr_reader :option_strike
27
+ attr_reader :option_expires_in_days
28
+ attr_reader :federal_reserve_interest_rate
29
+
30
+ attr_reader :option_expires_pct_year
31
+ attr_reader :option_expires_pct_year_sqrt
32
+ attr_reader :stock_dividend_rate_f
33
+ attr_reader :federal_reserve_interest_rate_f
34
+ attr_reader :rate_vs_expires
35
+ attr_reader :price_vs_rate_vs_expires
36
+ attr_reader :strike_vs_fed_vs_expires
37
+ attr_reader :price_ratio_log_less_rates
38
+
39
+
40
+ def initialize(opts)
41
+ @stock_price = opts[:stock_price]
42
+ @stock_dividend_rate = opts[:stock_dividend_rate]
43
+ @option_type = opts[:option_type]
44
+ @option_price = opts[:option_price]
45
+ @option_strike = opts[:option_strike]
46
+ @option_expires_in_days = opts[:option_expires_in_days]
47
+ @federal_reserve_interest_rate = opts[:federal_reserve_interest_rate]
48
+
49
+ @federal_reserve_interest_rate_f = federal_reserve_interest_rate / 100.0
50
+ @stock_dividend_rate_f = stock_dividend_rate / 100.0
51
+ @option_expires_pct_year = (option_expires_in_days + 1.0) / 365.0
52
+ @option_expires_pct_year_sqrt = Math.sqrt(option_expires_pct_year)
53
+
54
+
55
+ @price_vs_rate_vs_expires = GreekCalculations.misc_price_vs_rate_vs_expires(
56
+ :stock_price => stock_price,
57
+ :stock_dividend_rate_f => stock_dividend_rate_f,
58
+ :option_expires_pct_year => option_expires_pct_year
59
+ )
60
+
61
+ @rate_vs_expires = GreekCalculations.misc_rate_vs_expires(
62
+ :option_expires_pct_year => option_expires_pct_year,
63
+ :stock_dividend_rate_f => stock_dividend_rate_f
64
+ )
65
+
66
+ @strike_vs_fed_vs_expires = GreekCalculations.misc_strike_vs_fed_vs_expires(
67
+ :option_strike => option_strike,
68
+ :option_expires_pct_year => option_expires_pct_year,
69
+ :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f
70
+ )
71
+
72
+ @price_ratio_log_less_rates = GreekCalculations.misc_price_ratio_log_less_rates(
73
+ :stock_price => stock_price,
74
+ :stock_dividend_rate_f => stock_dividend_rate_f,
75
+ :option_strike => option_strike,
76
+ :option_expires_pct_year => option_expires_pct_year,
77
+ :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f
78
+ )
79
+ end
80
+
81
+
82
+ # Chance of Breakeven
83
+ # The probability that a stock will be trading beyond the breakeven price as implied by the option price.
84
+ # Chance of Breakeven can be used to get a sense for the valuation of the option by comparing the markets'
85
+ # estimate of Chance of Breakeven to estimates derived from your own fundamental research.
86
+ # If you believe the Chance of Breakeven is less than the probability that a stock will be beyond the
87
+ # breakeven price at option expiration, then you believe the option is undervalued, and visa versa.
88
+ def break_even
89
+ @break_even ||= GreekCalculations.break_even(
90
+ :stock_price => stock_price,
91
+ :stock_dividend_rate_f => stock_dividend_rate_f,
92
+ :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f,
93
+ :option_type => option_type,
94
+ :option_price => option_price,
95
+ :option_strike => option_strike,
96
+ :option_expires_pct_year => option_expires_pct_year,
97
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
98
+ :iv => iv
99
+ )
100
+ end
101
+
102
+
103
+ # Intrinsic Value
104
+ # The value that the option would pay if it were executed today. For example, if a stock is trading at $40,
105
+ # a call on that stock with a strike price of $35 would have $5 of intrinsic value ($40-$35) if it were
106
+ # exercised today. However, the call should actually be worth more than $5 to account for the value of the
107
+ # chance of any further appreciation until expiration, and the difference between the price and the
108
+ # intrinsic value would be the time value.
109
+ def premium_value
110
+ @premium_value ||= GreekCalculations.premium_value(
111
+ :option_type => option_type,
112
+ :option_strike => option_strike,
113
+ :stock_price => stock_price
114
+ )
115
+ end
116
+
117
+
118
+ # Time Value
119
+ # The value of an option that captures the chance of further appreciation before expiration.
120
+ # The value of an option can be broken down into intrinsic value, or the value of the option
121
+ # if it were exercised today, and time value, or the added value of the option over and above
122
+ # the intrinsic value. For example, if a stock is trading at $40 and a call with a strike price
123
+ # of $35 were trading for $7, the call would have a $5 intrinsic value ($40-$35) and a $2 time value ($7-$5).
124
+ # Time value will decay by expiration assuming the underlying security stays at the same price.
125
+ def time_value
126
+ @time_value ||= GreekCalculations.time_value(
127
+ :option_price => option_price,
128
+ :premium_value => premium_value
129
+ )
130
+ end
131
+
132
+
133
+ # Annualized Premium
134
+ # The annualized premium is the value of the option divided by the strike price. You can use annualized
135
+ # premium to develop an intuitive understanding of how much the market is "paying" for a dollar of risk.
136
+ # For example, if a stock is trading at $50 and you sell a $50 strike 6 month call for $4, you are getting
137
+ # paid 8% in 6 months, or about 16% annualized, in exchange for being willing to buy at $50, the current price.
138
+ def annualized_premium_value
139
+ @annualized_premium_value ||= GreekCalculations.annualized_premium_value(
140
+ :option_price => option_price,
141
+ :option_strike => option_strike,
142
+ :option_expires_pct_year => option_expires_pct_year
143
+ )
144
+ end
145
+
146
+
147
+ # Annualized Time Value
148
+ # The time value of the option divided by the strike price, then annualized. You can use annualized
149
+ # time value to develop an intuitive understanding of how much value the option market is adding to
150
+ # an in-the-money option beyond the intrinsic value. For example, if a stock is trading at $40 and a
151
+ # six month call on that stock with a strike price of $35 has an intrinsic value of $5 and a total
152
+ # value of $7, the time value ($2) divided by the strike is ($2/$40) = 5%. Annualizing that time value
153
+ # to a one year horizon on a continuously compounded basis yields 9.76% (2 × ln(1 + 0.05)).
154
+ def annualized_time_value
155
+ @annualized_time_value ||= GreekCalculations.annualized_time_value(
156
+ :time_value => time_value,
157
+ :option_strike => option_strike,
158
+ :option_expires_pct_year => option_expires_pct_year
159
+ )
160
+ end
161
+
162
+
163
+ # Implied Volatility
164
+ # A measure of the "riskiness" of the underlying security. Implied volatility is the primary measure of
165
+ # the "price" of an option--how expensive it is relative to other options. It is the "plug" value in option
166
+ # pricing models (the only variable in the equation that isn't precisely known). The remaining variables are
167
+ # option price, stock price, strike price, time to expiration, interest rate, and estimated dividends.
168
+ # Therefore, the implied volatility is the component of the option price that is determined by the market.
169
+ # Implied volatility is greater if the future outcome of the underlying stock price is more uncertain.
170
+ # All else equal, the wider the market expects the range of possible outcomes to be for a stock's price,
171
+ # the higher the implied volatility, and the more expensive the option.
172
+ def iv
173
+ @iv ||= GreekCalculations.iv(
174
+ :stock_price => stock_price,
175
+ :stock_dividend_rate => stock_dividend_rate,
176
+ :stock_dividend_rate_f => stock_dividend_rate_f,
177
+ :option_type => option_type,
178
+ :option_price => option_price,
179
+ :option_strike => option_strike,
180
+ :option_expires_in_days => option_expires_in_days,
181
+ :option_expires_pct_year => option_expires_pct_year,
182
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
183
+ :federal_reserve_interest_rate => federal_reserve_interest_rate,
184
+ :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f,
185
+ :price_ratio_log_less_rates => price_ratio_log_less_rates,
186
+ :rate_vs_expires => rate_vs_expires,
187
+ :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires,
188
+ :price_vs_rate_vs_expires => price_vs_rate_vs_expires,
189
+ )
190
+ end
191
+
192
+
193
+ # Delta
194
+ # A measurement of the change in the price of an option resulting from a change in the price of the underlying security.
195
+ # Delta is positive for calls and negative for puts. Delta can be calculated as the dollar change of the option that an
196
+ # investor can expect for a one-dollar change in the underlying security. For example, let's say an option on a stock
197
+ # trading at $50 costs $1 and has a delta of $0.50 per dollar of underlying stock price change. If the stock price rises
198
+ # to $52, the price of the option will increase by $1 (the $2 price change times the $0.50 delta). After the stock price
199
+ # movement, the option will be worth $2 ($1 initial cost plus $1 delta). Delta can also be calculated as a percentage
200
+ # change in the option price for a one-percent change in the underlying security; this method of viewing the delta value
201
+ # is also known as "leverage."
202
+ def delta
203
+ @delta ||= GreekCalculations.delta(
204
+ :option_type => option_type,
205
+ :iv => iv,
206
+ :rate_vs_expires => rate_vs_expires,
207
+ :d1_normal_distribution => d1_normal_distribution
208
+ )
209
+ end
210
+
211
+
212
+ # Gamma
213
+ # A measurement of the change in delta as the price of the underlying stock changes. As the underlying stock price changes,
214
+ # the delta of the option changes, too. Gamma indicates how quickly your exposure to the price movement of the underlying
215
+ # security changes as the price of the underlying security varies. For example, if you have a call with a strike of $50
216
+ # and the stock price is $50, the delta likely will be approximately $0.50 for a one-dollar movement of the stock.
217
+ # 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,
218
+ # 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.
219
+ # 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.
220
+ def gamma
221
+ @gamma ||= GreekCalculations.gamma(
222
+ :stock_price => stock_price,
223
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
224
+ :iv => iv,
225
+ :nd1 => nd1,
226
+ :rate_vs_expires => rate_vs_expires
227
+ )
228
+ end
229
+
230
+
231
+ # Vega
232
+ # The change in the price of an option for a change in the implied volatility of the option, all else held equal.
233
+ # In general, as the options market thinks it is more difficult to value a stock, implied volatility and therefore
234
+ # the price of the options will increase. For example, if an option is trading for $1, the implied volatility is 20%,
235
+ # and the vega is $0.05, then a one-percentage-point increase in implied volatility to 21% would correspond to an increase in
236
+ # 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%.
237
+ def vega
238
+ @vega ||= GreekCalculations.vega(
239
+ :price_vs_rate_vs_expires => price_vs_rate_vs_expires,
240
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
241
+ :nd1 => nd1,
242
+ :iv => iv
243
+ )
244
+ end
245
+
246
+
247
+ # Rho
248
+ # The change in the value of an option for a change in the prevailing interest rate that matches the duration of the option,
249
+ # all else held equal. Generally rho is not a big driver of price changes for options, as interest rates tend to be relatively stable.
250
+ def rho
251
+ @rho ||= GreekCalculations.rho(
252
+ :option_type => option_type,
253
+ :option_expires_pct_year => option_expires_pct_year,
254
+ :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires,
255
+ :d2_normal_distribution => d2_normal_distribution,
256
+ :iv => iv
257
+ )
258
+ end
259
+
260
+
261
+ # Theta
262
+ # The change in an option's value that an investor can expect from the passage of one day, assuming nothing else changes.
263
+ # 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,
264
+ # all else remaining equal, or as a percentage change in the option price for a one-day passage of time, all else remaining equal.
265
+ # 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
266
+ # at $0.90 on Tuesday morning. Another way of measuring theta for that option is ($0.90 - $1)/$1 or -10% per day.
267
+ def theta
268
+ @theta ||= GreekCalculations.theta(
269
+ :federal_reserve_interest_rate_f => federal_reserve_interest_rate_f,
270
+ :stock_dividend_rate_f => stock_dividend_rate_f,
271
+ :option_type => option_type,
272
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
273
+ :strike_vs_fed_vs_expires => strike_vs_fed_vs_expires,
274
+ :price_vs_rate_vs_expires => price_vs_rate_vs_expires,
275
+ :price_ratio_log_less_rates => price_ratio_log_less_rates,
276
+ :iv => iv,
277
+ :nd1 => nd1,
278
+ :d1_normal_distribution => d1_normal_distribution,
279
+ :d2_normal_distribution => d2_normal_distribution
280
+ )
281
+ end
282
+
283
+
284
+ def to_hash
285
+ hash = {
286
+ :federal_reserve_interest_rate => federal_reserve_interest_rate,
287
+ :stock_dividend_rate => stock_dividend_rate,
288
+ :stock_price => stock_price,
289
+ :option_expires_in_days => option_expires_in_days,
290
+ :option_type => option_type,
291
+ :option_strike => option_strike,
292
+ :option_price => option_price,
293
+ :break_even => nil,
294
+ :iv => nil,
295
+ :delta => nil,
296
+ :gamma => nil,
297
+ :vega => nil,
298
+ :rho => nil,
299
+ :theta => nil,
300
+ :deta_vs_theta => nil,
301
+ }
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
+
311
+ # Delta/Theta
312
+ # A measure of the “bang for the buck” of an option.
313
+ # By dividing the dimensionless Delta or leverage of an option by the dimensionless Theta or
314
+ # decay rate, the trend in the Delta/Theta column indicates which options give the most exposure
315
+ # to the movement of the underlying stock or index for a given decay rate of the option value.
316
+ # The highest numbers indicate the most bang for the buck for the least decay rate.
317
+ hash[:deta_vs_theta] = hash[:delta] / hash[:theta] unless hash[:delta].nil? || hash[:theta].nil?
318
+
319
+ [:iv, :delta, :gamma, :vega, :rho, :theta, :deta_vs_theta].each do |key|
320
+ hash[key] &&= hash[key].round(2)
321
+ end
322
+
323
+ hash
324
+ end
325
+
326
+
327
+ private
328
+
329
+
330
+ def d1
331
+ @d1 ||= GreekCalculations.misc_d1(
332
+ :price_ratio_log_less_rates => price_ratio_log_less_rates,
333
+ :option_expires_pct_year => option_expires_pct_year,
334
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
335
+ :iv => iv
336
+ )
337
+ end
338
+
339
+
340
+ def d2
341
+ @d2 ||= GreekCalculations.misc_d2(
342
+ :option_expires_pct_year_sqrt => option_expires_pct_year_sqrt,
343
+ :d1 => d1,
344
+ :iv => iv
345
+ )
346
+ end
347
+
348
+
349
+ def d1_normal_distribution
350
+ @d1_normal_distribution ||= GreekCalculations.misc_d_normal_distribution(
351
+ :option_type => option_type,
352
+ :d_value => d1
353
+ )
354
+ end
355
+
356
+
357
+ def d2_normal_distribution
358
+ @d2_normal_distribution ||= GreekCalculations.misc_d_normal_distribution(
359
+ :option_type => option_type,
360
+ :d_value => d2
361
+ )
362
+ end
363
+
364
+
365
+ def nd1
366
+ @nd1 ||= GreekCalculations.misc_nd1(:d1 => d1)
367
+ end
368
+
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,9 @@
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
+ it { delta(:option_type => :call, :rate_vs_expires => 1.0, :d1_normal_distribution => 1.0, :iv => 'any value').should === 1.0 }
8
+ it { delta(:option_type => :put, :rate_vs_expires => 1.0, :d1_normal_distribution => 1.0, :iv => 'any value').should === -1.0 }
9
+ end
@@ -0,0 +1,8 @@
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
+ it { gamma(:stock_price => 1.0, :option_expires_pct_year_sqrt => 2.0, :iv => 3.0, :nd1 => 4.0, :rate_vs_expires => 5.0).round(2).should. === 3.33 }
8
+ end
@@ -0,0 +1,67 @@
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
+ include Math::GreekCalculationHelpers
7
+
8
+ let(:stock_price) { 10.00 }
9
+ let(:stock_dividend_rate_f) { 0.00 }
10
+ let(:option_type) { :call }
11
+ let(:option_expires_pct_year) { 1.00 }
12
+ let(:volatility_guess) { 0.50 }
13
+
14
+ context "exactly at the money" do
15
+ let(:option_strike) { 10.00 }
16
+
17
+ context "0% interest" do
18
+ let(:federal_reserve_interest_rate_f) { 0.00 }
19
+ let(:expected) { 1.9741254870839349 }
20
+
21
+ it { var_option_price().should === expected }
22
+ end
23
+
24
+ context "0.02% interest" do
25
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
26
+ let(:expected) { 1.9749281489443273 }
27
+
28
+ it { var_option_price().should === expected }
29
+ end
30
+ end
31
+
32
+ context "out of the money" do
33
+ let(:option_strike) { 15.00 }
34
+
35
+ context "0% interest" do
36
+ let(:federal_reserve_interest_rate_f) { 0.00 }
37
+ let(:expected) { 0.7088126378267066 }
38
+
39
+ it { var_option_price().should === expected }
40
+ end
41
+
42
+ context "0.02% interest" do
43
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
44
+ let(:expected) { 0.7092458172337008 }
45
+
46
+ it { var_option_price().should === expected }
47
+ end
48
+ end
49
+
50
+ context "in of the money" do
51
+ let(:option_strike) { 5.00 }
52
+
53
+ context "0% interest" do
54
+ let(:federal_reserve_interest_rate_f) { 0.00 }
55
+ let(:expected) { 5.130693877506824 }
56
+
57
+ it { var_option_price().should === expected }
58
+ end
59
+
60
+ context "0.02% interest" do
61
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
62
+ let(:expected) { 5.1315659170286185 }
63
+
64
+ it { var_option_price().should === expected }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,56 @@
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
+ include Math::GreekCalculationHelpers
7
+
8
+ let(:stock_price) { 10.00 }
9
+ let(:stock_dividend_rate) { 0.0 }
10
+ let(:stock_dividend_rate_f) { 0.0 }
11
+
12
+ let(:option_price) { 1.00 }
13
+ let(:option_expires_in_days) { 364.0 }
14
+ let(:option_expires_pct_year) { 1.0 }
15
+
16
+ let(:federal_reserve_interest_rate) { 0.0 }
17
+ let(:federal_reserve_interest_rate_f) { 0.00 }
18
+
19
+ describe "call options" do
20
+ let(:option_type) { :call }
21
+
22
+ context "exactly at the money" do
23
+ let(:option_strike) { 10.00 }
24
+ it { var_iv().should === 0.25089263455361754 }
25
+ end
26
+
27
+ context "out of the money" do
28
+ let(:option_strike) { 15.00 }
29
+ it { var_iv().should === 0.5819996182323802 }
30
+ end
31
+
32
+ context "in the money" do
33
+ let(:option_strike) { 5.00 }
34
+ it { var_iv().should === nil }
35
+ end
36
+ end
37
+
38
+ describe "put options" do
39
+ let(:option_type) { :put }
40
+
41
+ context "exactly at the money" do
42
+ let(:option_strike) { 10.00 }
43
+ it { var_iv().should === 0.25089263455361754 }
44
+ end
45
+
46
+ context "out of the money" do
47
+ let(:option_strike) { 15.00 }
48
+ it { var_iv().should === nil }
49
+ end
50
+
51
+ context "in the money" do
52
+ let(:option_strike) { 5.00 }
53
+ it { var_iv().should === 1.0245859277769118 }
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,66 @@
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
+ include Math::GreekCalculationHelpers
7
+
8
+ let(:stock_price) { 10.00 }
9
+ let(:stock_dividend_rate_f) { 0.00 }
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) { 3.866681168028493 }
19
+
20
+ it { var_vega().should === expected }
21
+ end
22
+
23
+ context "0.02% interest" do
24
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
25
+ let(:expected) { 3.866294209940902 }
26
+
27
+ it { var_vega().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) { 3.4086802947730774 }
37
+
38
+ it { var_vega().should === expected }
39
+ end
40
+
41
+ context "0.02% interest" do
42
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
43
+ let(:expected) { 3.4094449205351056 }
44
+
45
+ it { var_vega().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) { 1.045940982192684 }
55
+
56
+ it { var_vega().should === expected }
57
+ end
58
+
59
+ context "0.02% interest" do
60
+ let(:federal_reserve_interest_rate_f) { 0.0002 }
61
+ let(:expected) { 1.045256535627944 }
62
+
63
+ it { var_vega().should === expected }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,22 @@
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
@@ -0,0 +1,9 @@
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
+ it { rho(:option_type => :call, :option_expires_pct_year => 1.0, :strike_vs_fed_vs_expires => 2.0, :d2_normal_distribution => 3.0, :iv => 'any value').should === 0.06 }
8
+ it { rho(:option_type => :put, :option_expires_pct_year => 1.0, :strike_vs_fed_vs_expires => 2.0, :d2_normal_distribution => 3.0, :iv => 'any value').should === -0.06 }
9
+ end
@@ -0,0 +1,10 @@
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
+ 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
+
9
+ 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 }
10
+ end