greeks 1.0

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.
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