rupee 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/rupee/option.c CHANGED
@@ -9,7 +9,7 @@ is_call(call_put_flag)
9
9
  return (call_put_flag[0] != 'p');
10
10
  }
11
11
 
12
- static double
12
+ double
13
13
  bs(call_put_flag, S, X, T, r, q, v)
14
14
  const char *call_put_flag;
15
15
  double S, X, T, r, q, v;
@@ -25,9 +25,477 @@ bs(call_put_flag, S, X, T, r, q, v)
25
25
  return X * exp(-r * T) * cnd(-d2) - S * exp(-q * T) * cnd(-d1);
26
26
  }
27
27
 
28
- /* call-seq:
29
- * black_scholes(call_put_flag, forward, strike_price, time_to_expiry,
30
- * risk_free_rate, volatility)
28
+ // GREEKS
29
+
30
+ double
31
+ delta(call_put_flag, S, K, T, r, q, v)
32
+ const char *call_put_flag;
33
+ double S, K, T, r, q, v;
34
+ {
35
+ double d1;
36
+
37
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
38
+
39
+ if (is_call(call_put_flag))
40
+ return exp(-q * T) * cnd(d1);
41
+ else
42
+ return -exp(-q * T) * cnd(-d1);
43
+ }
44
+
45
+ double
46
+ vega(call_put_flag, S, K, T, r, q, v)
47
+ const char *call_put_flag;
48
+ double S, K, T, r, q, v;
49
+ {
50
+ double d1;
51
+
52
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
53
+
54
+ return S * exp(-q * T) * pdf(d1) * sqrt(T);
55
+ }
56
+
57
+ double
58
+ theta(call_put_flag, S, K, T, r, q, v)
59
+ const char *call_put_flag;
60
+ double S, K, T, r, q, v;
61
+ {
62
+ double d1, d2;
63
+
64
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
65
+ d2 = d1 - v * sqrt(T);
66
+
67
+ if (is_call(call_put_flag))
68
+ return -exp(-q * T) * (S * pdf(d1) * v) / (2 * sqrt(T)) -
69
+ r * K * exp(-r * T) * cnd(d2) + q * S * exp(-q * T) * cnd(d1);
70
+ else
71
+ return -exp(-q * T) * (S * pdf(d1) * v) / (2 * sqrt(T)) +
72
+ r * K * exp(-r * T) * cnd(-d2) - q * S * exp(-q * T) * cnd(-d1);
73
+ }
74
+
75
+ double
76
+ rho(call_put_flag, S, K, T, r, q, v)
77
+ const char *call_put_flag;
78
+ double S, K, T, r, q, v;
79
+ {
80
+ double d1, d2;
81
+
82
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
83
+ d2 = d1 - v * sqrt(T);
84
+
85
+ if (is_call(call_put_flag))
86
+ return K * T * exp(-r * T) * cnd(d2);
87
+ else
88
+ return -K * T * exp(-r * T) * cnd(-d2);
89
+ }
90
+
91
+ double
92
+ bs_gamma(call_put_flag, S, K, T, r, q, v)
93
+ const char *call_put_flag;
94
+ double S, K, T, r, q, v;
95
+ {
96
+ double d1;
97
+
98
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
99
+
100
+ return exp(-q * T) * pdf(d1) / (S * v * sqrt(T));
101
+ }
102
+
103
+ /* call-seq: delta(call_put_flag, underlying, strike, time, rate, div_yield,
104
+ * volatility)
105
+ *
106
+ * Returns the delta options Greek (sensitivity to changes in the underlying's
107
+ * price
108
+ */
109
+ static VALUE
110
+ rupee_delta(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
111
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
112
+ {
113
+ const char *call_put_flag;
114
+ double S, K, T, r, q, v;
115
+
116
+ call_put_flag = StringValuePtr(_call_put_flag);
117
+ S = NUM2DBL(_S);
118
+ K = NUM2DBL(_K);
119
+ T = NUM2DBL(_T);
120
+ r = NUM2DBL(_r);
121
+ q = NUM2DBL(_q);
122
+ v = NUM2DBL(_v);
123
+
124
+ return rb_float_new(delta(call_put_flag, S, K, T, r, q, v));
125
+ }
126
+
127
+ /* call-seq: vega(call_put_flag, underlying, strike, time, rate, div_yield,
128
+ * volatility)
129
+ *
130
+ * Returns the vega options Greek (sensitivity to changes in volatility)
131
+ */
132
+ static VALUE
133
+ rupee_vega(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
134
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
135
+ {
136
+ const char *call_put_flag;
137
+ double S, K, T, r, q, v;
138
+
139
+ call_put_flag = StringValuePtr(_call_put_flag);
140
+ S = NUM2DBL(_S);
141
+ K = NUM2DBL(_K);
142
+ T = NUM2DBL(_T);
143
+ r = NUM2DBL(_r);
144
+ q = NUM2DBL(_q);
145
+ v = NUM2DBL(_v);
146
+
147
+ return rb_float_new(vega(call_put_flag, S, K, T, r, q, v));
148
+ }
149
+
150
+ /* call-seq: theta(call_put_flag, underlying, strike, time, rate, div_yield,
151
+ * volatility)
152
+ *
153
+ * returns the theta options greek (sensitivity to the passage of time; time
154
+ * decay)
155
+ */
156
+ static VALUE
157
+ rupee_theta(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
158
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
159
+ {
160
+ const char *call_put_flag;
161
+ double S, K, T, r, q, v;
162
+
163
+ call_put_flag = StringValuePtr(_call_put_flag);
164
+ S = NUM2DBL(_S);
165
+ K = NUM2DBL(_K);
166
+ T = NUM2DBL(_T);
167
+ r = NUM2DBL(_r);
168
+ q = NUM2DBL(_q);
169
+ v = NUM2DBL(_v);
170
+
171
+ return rb_float_new(theta(call_put_flag, S, K, T, r, q, v));
172
+ }
173
+
174
+ /* call-seq: rho(call_put_flag, underlying, strike, time, rate, div_yield,
175
+ * volatility)
176
+ *
177
+ * Returns the rho options Greek (sensitivity to the risk-free rate)
178
+ */
179
+ static VALUE
180
+ rupee_rho(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
181
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
182
+ {
183
+ const char *call_put_flag;
184
+ double S, K, T, r, q, v;
185
+
186
+ call_put_flag = StringValuePtr(_call_put_flag);
187
+ S = NUM2DBL(_S);
188
+ K = NUM2DBL(_K);
189
+ T = NUM2DBL(_T);
190
+ r = NUM2DBL(_r);
191
+ q = NUM2DBL(_q);
192
+ v = NUM2DBL(_v);
193
+
194
+ return rb_float_new(rho(call_put_flag, S, K, T, r, q, v));
195
+ }
196
+
197
+ /* call-seq: gamma(call_put_flag, underlying, strike, time, rate, div_yield,
198
+ * volatility)
199
+ *
200
+ * Returns the gamma options Greek (sensitivity to changes in delta; convexity)
201
+ */
202
+ static VALUE
203
+ rupee_gamma(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
204
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
205
+ {
206
+ const char *call_put_flag;
207
+ double S, K, T, r, q, v;
208
+
209
+ call_put_flag = StringValuePtr(_call_put_flag);
210
+ S = NUM2DBL(_S);
211
+ K = NUM2DBL(_K);
212
+ T = NUM2DBL(_T);
213
+ r = NUM2DBL(_r);
214
+ q = NUM2DBL(_q);
215
+ v = NUM2DBL(_v);
216
+
217
+ return rb_float_new(bs_gamma(call_put_flag, S, K, T, r, q, v));
218
+ }
219
+
220
+ /* call-seq: vanna(call_put_flag, S, K, T, r, q, v)
221
+ *
222
+ * Returns the vanna options Greek (sensitivity of delta to changes in
223
+ * volatility)
224
+ */
225
+ static VALUE
226
+ rupee_vanna(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
227
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
228
+ {
229
+ const char *call_put_flag;
230
+ double d1, d2, S, K, T, r, q, v;
231
+
232
+ call_put_flag = StringValuePtr(_call_put_flag);
233
+ S = NUM2DBL(_S);
234
+ K = NUM2DBL(_K);
235
+ T = NUM2DBL(_T);
236
+ r = NUM2DBL(_r);
237
+ q = NUM2DBL(_q);
238
+ v = NUM2DBL(_v);
239
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
240
+ d2 = d1 - v * sqrt(T);
241
+
242
+ return rb_float_new(-exp(-q * T) * pdf(d1) * d2 / v);
243
+ }
244
+
245
+ /* call-seq: charm(call_put_flag, S, K, T, r, q, v)
246
+ *
247
+ * Returns the charm options Greek (sensitivity of delta to the passage of
248
+ * time)
249
+ */
250
+ static VALUE
251
+ rupee_charm(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
252
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
253
+ {
254
+ const char *call_put_flag;
255
+ double d1, d2, S, K, T, r, q, v;
256
+
257
+ call_put_flag = StringValuePtr(_call_put_flag);
258
+ S = NUM2DBL(_S);
259
+ K = NUM2DBL(_K);
260
+ T = NUM2DBL(_T);
261
+ r = NUM2DBL(_r);
262
+ q = NUM2DBL(_q);
263
+ v = NUM2DBL(_v);
264
+
265
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
266
+ d2 = d1 - v * sqrt(T);
267
+
268
+ if (is_call(call_put_flag))
269
+ return rb_float_new(-q * exp(-q * T) * cnd(d1) + exp(-q * T) * pdf(d1) *
270
+ (2 * (r - q) * T - d2 * v * sqrt(T)) / (2 * T * v * sqrt(T)));
271
+ else
272
+ return rb_float_new(q * exp(-q * T) * cnd(-d1) + exp(-q * T) * pdf(d1) *
273
+ (2 * (r - q) * T - d2 * v * sqrt(T)) / (2 * T * v * sqrt(T)));
274
+ }
275
+
276
+ /* call-seq: rupee_speed(call_put_flag, S, K, T, r, q, v)
277
+ *
278
+ * Returns the speed options Greek (sensitivity of gamma to changes in the
279
+ * underlying's price).
280
+ */
281
+ static VALUE
282
+ rupee_speed(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
283
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
284
+ {
285
+ const char *call_put_flag;
286
+ double d1, S, K, T, r, q, v;
287
+
288
+ call_put_flag = StringValuePtr(_call_put_flag);
289
+ S = NUM2DBL(_S);
290
+ K = NUM2DBL(_K);
291
+ T = NUM2DBL(_T);
292
+ r = NUM2DBL(_r);
293
+ q = NUM2DBL(_q);
294
+ v = NUM2DBL(_v);
295
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
296
+
297
+ return rb_float_new(-exp(-q * T) * pdf(d1) / (S * S * v * sqrt(T)) *
298
+ (d1 / (v * sqrt(T)) + 1));
299
+ }
300
+
301
+ /* call-seq: zomma(call_put_flag, S, K, T, r, q, v)
302
+ *
303
+ * Returns the zomma options Greek (sensitivity of gamma to changes in
304
+ * volatility)
305
+ */
306
+ static VALUE
307
+ rupee_zomma(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
308
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
309
+ {
310
+ const char *call_put_flag;
311
+ double d1, d2, S, K, T, r, q, v;
312
+
313
+ call_put_flag = StringValuePtr(_call_put_flag);
314
+ S = NUM2DBL(_S);
315
+ K = NUM2DBL(_K);
316
+ T = NUM2DBL(_T);
317
+ r = NUM2DBL(_r);
318
+ q = NUM2DBL(_q);
319
+ v = NUM2DBL(_v);
320
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
321
+ d2 = d1 - v * sqrt(T);
322
+
323
+ return rb_float_new(-exp(-q * T) * pdf(d1) * (d1 * d2 - 1) /
324
+ (S * v * v * sqrt(T)));
325
+ }
326
+
327
+ /* call-seq: color(call_put_flag, S, K, T, r, q, v)
328
+ *
329
+ * Returns the color options Greek (sensitivity of gamma to the passage of
330
+ * time)
331
+ */
332
+ static VALUE
333
+ rupee_color(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
334
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
335
+ {
336
+ const char *call_put_flag;
337
+ double d1, d2, S, K, T, r, q, v;
338
+
339
+ call_put_flag = StringValuePtr(_call_put_flag);
340
+ S = NUM2DBL(_S);
341
+ K = NUM2DBL(_K);
342
+ T = NUM2DBL(_T);
343
+ r = NUM2DBL(_r);
344
+ q = NUM2DBL(_q);
345
+ v = NUM2DBL(_v);
346
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
347
+ d2 = d1 - v * sqrt(T);
348
+
349
+ return rb_float_new(-exp(-q * T) * pdf(d1) / (2.0 * S * T * v * sqrt(T)) *
350
+ (2.0 * q * T + 1.0 + (2.0 * (r - q) * T - d2 * v * sqrt(T)) /
351
+ (2.0 * T * v * sqrt(T)) * d1));
352
+ }
353
+
354
+ /* call-seq: dvega_dtime(call_put_flag, S, K, T, r, q, v)
355
+ *
356
+ * Returns the dvega dtime options Greek (sensitivity of vega to the passage of
357
+ * time)
358
+ */
359
+ static VALUE
360
+ rupee_dvega_dtime(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
361
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
362
+ {
363
+ const char *call_put_flag;
364
+ double d1, d2, S, K, T, r, q, v;
365
+
366
+ call_put_flag = StringValuePtr(_call_put_flag);
367
+ S = NUM2DBL(_S);
368
+ K = NUM2DBL(_K);
369
+ T = NUM2DBL(_T);
370
+ r = NUM2DBL(_r);
371
+ q = NUM2DBL(_q);
372
+ v = NUM2DBL(_v);
373
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
374
+ d2 = d1 - v * sqrt(T);
375
+
376
+ return rb_float_new(S * exp(-q * T) * pdf(d1) * sqrt(T) *
377
+ (q + ((r - q) * d1) / (v * sqrt(T)) - (1 + d1 * d2) / (2 * T)));
378
+ }
379
+
380
+ /* call-seq: vomma(call_put_flag, S, K, T, r, q, v)
381
+ *
382
+ * Returns the vomma options Greek (sensitivity of vega to changes in
383
+ * volatility)
384
+ */
385
+ static VALUE
386
+ rupee_vomma(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
387
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
388
+ {
389
+ const char *call_put_flag;
390
+ double d1, d2, S, K, T, r, q, v;
391
+
392
+ call_put_flag = StringValuePtr(_call_put_flag);
393
+ S = NUM2DBL(_S);
394
+ K = NUM2DBL(_K);
395
+ T = NUM2DBL(_T);
396
+ r = NUM2DBL(_r);
397
+ q = NUM2DBL(_q);
398
+ v = NUM2DBL(_v);
399
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
400
+ d2 = d1 - v * sqrt(T);
401
+
402
+ return rb_float_new(S * exp(-q * T) * pdf(d1) * sqrt(T) * d1 * d2 / v);
403
+ }
404
+
405
+ /* call-seq: dual_delta(call_put_flag, S, K, T, r, q, v)
406
+ *
407
+ * Returns the dual delta options Greek (probability of finishing in-the-money)
408
+ */
409
+ static VALUE
410
+ rupee_dual_delta(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
411
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
412
+ {
413
+ const char *call_put_flag;
414
+ double d1, d2, S, K, T, r, q, v;
415
+
416
+ call_put_flag = StringValuePtr(_call_put_flag);
417
+ S = NUM2DBL(_S);
418
+ K = NUM2DBL(_K);
419
+ T = NUM2DBL(_T);
420
+ r = NUM2DBL(_r);
421
+ q = NUM2DBL(_q);
422
+ v = NUM2DBL(_v);
423
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
424
+ d2 = d1 - v * sqrt(T);
425
+
426
+ if (is_call(call_put_flag))
427
+ return rb_float_new(-exp(-q * T) * cnd(d2));
428
+ else
429
+ return rb_float_new(exp(-q * T) * cnd(-d2));
430
+ }
431
+
432
+ /* call-seq: dual_gamma(call_put_flag, S, K, T, r, q, v)
433
+ *
434
+ * Returns the dual gamma options Greek.
435
+ */
436
+ static VALUE
437
+ rupee_dual_gamma(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
438
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
439
+ {
440
+ const char *call_put_flag;
441
+ double d1, d2, S, K, T, r, q, v;
442
+
443
+ call_put_flag = StringValuePtr(_call_put_flag);
444
+ S = NUM2DBL(_S);
445
+ K = NUM2DBL(_K);
446
+ T = NUM2DBL(_T);
447
+ r = NUM2DBL(_r);
448
+ q = NUM2DBL(_q);
449
+ v = NUM2DBL(_v);
450
+ d1 = (log(S / K) + (r - q + v * v / 2) * T) / (v * sqrt(T));
451
+ d2 = d1 - v * sqrt(T);
452
+
453
+ return rb_float_new(exp(-r * T) * pdf(d2) / (K * v * sqrt(T)));
454
+ }
455
+
456
+
457
+ /* call-seq: implied_volatility(call_put_flag, underlying, strike, time, rate,
458
+ * div_yield, price)
459
+ *
460
+ * Returns the Black-Scholes implied volatility using the Newton-Raphson method
461
+ */
462
+ static VALUE
463
+ rupee_impl_vol(self, _call_put_flag, _S, _K, _T, _r, _q, _cm)
464
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _cm;
465
+ {
466
+ static const double epsilon = 0.00000001;
467
+ double vi, ci, vegai, min_diff, S, K, T, r, q, cm;
468
+ const char *call_put_flag;
469
+
470
+ call_put_flag = StringValuePtr(_call_put_flag);
471
+ S = NUM2DBL(_S);
472
+ K = NUM2DBL(_K);
473
+ T = NUM2DBL(_T);
474
+ r = NUM2DBL(_r);
475
+ q = NUM2DBL(_q);
476
+ cm = NUM2DBL(_cm);
477
+
478
+ // Manaster and Koehler seed value
479
+ vi = sqrt(abs(log(S / K) + r * T) * 2 / T);
480
+ ci = bs(call_put_flag, S, K, T, r, q, vi);
481
+ vegai = vega(call_put_flag, S, K, T, r, q, vi);
482
+ min_diff = abs(cm - ci);
483
+
484
+ while (min_diff >= epsilon) {
485
+ vi -= (ci - cm) / vegai;
486
+ ci = bs(call_put_flag, S, K, T, r, q, vi);
487
+ vegai = vega(call_put_flag, S, K, T, r, q, vi);
488
+ min_diff = abs(cm - ci);
489
+ }
490
+
491
+ if (min_diff < epsilon)
492
+ return vi;
493
+ else
494
+ return 0;
495
+ }
496
+
497
+ /* call-seq: black_scholes(call_put_flag, underlying, strike, time, rate,
498
+ * volatility)
31
499
  *
32
500
  * The Black-Scholes European call/put valuation
33
501
  *
@@ -42,37 +510,37 @@ bs(call_put_flag, S, X, T, r, q, v)
42
510
  * * +volatility+ - The implied volatility at expiry
43
511
  */
44
512
  static VALUE
45
- rupee_black_scholes(self, rcall_put_flag, rF, rX, rT, rr, rq, rv)
46
- VALUE self, rcall_put_flag, rF, rX, rT, rr, rq, rv;
513
+ rupee_black_scholes(self, _call_put_flag, _S, _K, _T, _r, _q, _v)
514
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _q, _v;
47
515
  {
48
516
  const char *call_put_flag;
49
- double F, X, T, r, q, v;
517
+ double S, K, T, r, q, v;
50
518
 
51
- call_put_flag = StringValuePtr(rcall_put_flag);
52
- F = NUM2DBL(rF);
53
- X = NUM2DBL(rX);
54
- T = NUM2DBL(rT);
55
- r = NUM2DBL(rr);
56
- q = NUM2DBL(rq);
57
- v = NUM2DBL(rv);
519
+ call_put_flag = StringValuePtr(_call_put_flag);
520
+ S = NUM2DBL(_S);
521
+ K = NUM2DBL(_K);
522
+ T = NUM2DBL(_T);
523
+ r = NUM2DBL(_r);
524
+ q = NUM2DBL(_q);
525
+ v = NUM2DBL(_v);
58
526
 
59
- return rb_float_new(bs(call_put_flag, F, X, T, r, q, v));
527
+ return rb_float_new(bs(call_put_flag, S, K, T, r, q, v));
60
528
  }
61
529
 
62
530
  double
63
- gbs(call_put_flag, S, X, T, r, b, v)
531
+ gbs(call_put_flag, S, K, T, r, b, v)
64
532
  const char *call_put_flag;
65
- double S, X, T, r, b, v;
533
+ double S, K, T, r, b, v;
66
534
  {
67
535
  double d1, d2;
68
536
 
69
- d1 = (log(S / X) + (b + v * v / 2) * T) / (v * sqrt(T));
537
+ d1 = (log(S / K) + (b + v * v / 2) * T) / (v * sqrt(T));
70
538
  d2 = d1 - v * sqrt(T);
71
539
 
72
540
  if (is_call(call_put_flag))
73
- return S * exp((b - r) * T) * cnd(d1) - X * exp(-r * T) * cnd(d2);
541
+ return S * exp((b - r) * T) * cnd(d1) - K * exp(-r * T) * cnd(d2);
74
542
  else
75
- return X * exp(-r * T) * cnd(-d2) - S * exp((b - r) * T) * cnd(-d1);
543
+ return K * exp(-r * T) * cnd(-d2) - S * exp((b - r) * T) * cnd(-d1);
76
544
  }
77
545
 
78
546
  /* call-seq:
@@ -92,37 +560,37 @@ gbs(call_put_flag, S, X, T, r, b, v)
92
560
  * * +volatility+ - The implied volatility at expiry
93
561
  */
94
562
  static VALUE
95
- rupee_generalized_black_scholes(self, rcall_put_flag, rF, rX, rT, rr, rb, rv)
96
- VALUE self, rcall_put_flag, rF, rX, rT, rr, rb, rv;
563
+ rupee_generalized_black_scholes(self, _call_put_flag, _S, _K, _T, _r, _b, _v)
564
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _b, _v;
97
565
  {
98
566
  const char *call_put_flag;
99
- double F, X, T, r, b, v;
567
+ double S, K, T, r, b, v;
100
568
 
101
- call_put_flag = StringValuePtr(rcall_put_flag);
102
- F = NUM2DBL(rF);
103
- X = NUM2DBL(rX);
104
- T = NUM2DBL(rT);
105
- r = NUM2DBL(rr);
106
- b = NUM2DBL(rb);
107
- v = NUM2DBL(rv);
569
+ call_put_flag = StringValuePtr(_call_put_flag);
570
+ S = NUM2DBL(_S);
571
+ K = NUM2DBL(_K);
572
+ T = NUM2DBL(_T);
573
+ r = NUM2DBL(_r);
574
+ b = NUM2DBL(_b);
575
+ v = NUM2DBL(_v);
108
576
 
109
- return rb_float_new(gbs(call_put_flag, F, X, T, r, b, v));
577
+ return rb_float_new(gbs(call_put_flag, S, K, T, r, b, v));
110
578
  }
111
579
 
112
580
  static double
113
- black76(call_put_flag, F, X, T, r, v)
581
+ black76(call_put_flag, S, K, T, r, v)
114
582
  const char *call_put_flag;
115
- double F, X, T, r, v;
583
+ double S, K, T, r, v;
116
584
  {
117
585
  double d1, d2;
118
586
 
119
- d1 = (log(F / X) + (v * v / 2.0) * T) / (v * sqrt(T));
587
+ d1 = (log(S / K) + (v * v / 2.0) * T) / (v * sqrt(T));
120
588
  d2 = d1 - v * sqrt(T);
121
589
 
122
590
  if (is_call(call_put_flag))
123
- return exp(-r * T) * (F * cnd(d1) - X * cnd(d2));
591
+ return exp(-r * T) * (S * cnd(d1) - K * cnd(d2));
124
592
  else
125
- return exp(-r * T) * (X * cnd(-d2) - F * cnd(-d1));
593
+ return exp(-r * T) * (K * cnd(-d2) - S * cnd(-d1));
126
594
  }
127
595
 
128
596
  /* call-seq:
@@ -141,20 +609,20 @@ black76(call_put_flag, F, X, T, r, v)
141
609
  * * +volatility+ - The implied volatility at expiry
142
610
  */
143
611
  static VALUE
144
- rupee_black76(self, rcall_put_flag, rF, rX, rT, rr, rv)
145
- VALUE self, rcall_put_flag, rF, rX, rT, rr, rv;
612
+ rupee_black76(self, _call_put_flag, _S, _K, _T, _r, _v)
613
+ VALUE self, _call_put_flag, _S, _K, _T, _r, _v;
146
614
  {
147
615
  const char *call_put_flag;
148
- double F, X, T, r, v;
616
+ double S, K, T, r, v;
149
617
 
150
- call_put_flag = StringValuePtr(rcall_put_flag);
151
- F = NUM2DBL(rF);
152
- X = NUM2DBL(rX);
153
- T = NUM2DBL(rT);
154
- r = NUM2DBL(rr);
155
- v = NUM2DBL(rv);
618
+ call_put_flag = StringValuePtr(_call_put_flag);
619
+ S = NUM2DBL(_S);
620
+ K = NUM2DBL(_K);
621
+ T = NUM2DBL(_T);
622
+ r = NUM2DBL(_r);
623
+ v = NUM2DBL(_v);
156
624
 
157
- return rb_float_new(black76(call_put_flag, F, X, T, r, v));
625
+ return rb_float_new(black76(call_put_flag, S, K, T, r, v));
158
626
  }
159
627
 
160
628
  void
@@ -173,7 +641,35 @@ init_option()
173
641
  rb_define_singleton_method(klass, "black76", rupee_black76, 6);
174
642
  rb_define_singleton_method(klass, "black_scholes", rupee_black_scholes, 7);
175
643
  rb_define_alias(singleton, "bs", "black_scholes");
644
+ rb_define_singleton_method(klass, "charm", rupee_charm, 7);
645
+ rb_define_singleton_method(klass, "color", rupee_color, 7);
646
+ rb_define_singleton_method(klass, "delta", rupee_delta, 7);
647
+ rb_define_singleton_method(klass, "dual_delta", rupee_dual_delta, 7);
648
+ rb_define_singleton_method(klass, "dual_gamma", rupee_dual_gamma, 7);
649
+ rb_define_singleton_method(klass, "dvega_dtime", rupee_dvega_dtime, 7);
650
+ rb_define_singleton_method(klass, "gamma", rupee_gamma, 7);
176
651
  rb_define_singleton_method(klass, "generalized_black_scholes",
177
652
  rupee_generalized_black_scholes, 7);
178
653
  rb_define_alias(singleton, "gbs", "generalized_black_scholes");
654
+ rb_define_singleton_method(klass, "implied_volatility", rupee_impl_vol, 7);
655
+ rb_define_singleton_method(klass, "rho", rupee_rho, 7);
656
+ rb_define_singleton_method(klass, "speed", rupee_speed, 7);
657
+ rb_define_singleton_method(klass, "theta", rupee_theta, 7);
658
+ rb_define_singleton_method(klass, "vanna", rupee_vanna, 7);
659
+ rb_define_singleton_method(klass, "vega", rupee_vega, 7);
660
+ rb_define_singleton_method(klass, "vomma", rupee_vomma, 7);
661
+ rb_define_singleton_method(klass, "zomma", rupee_zomma, 7);
179
662
  }
663
+
664
+
665
+
666
+
667
+
668
+
669
+
670
+
671
+
672
+
673
+
674
+
675
+