1 PACKAGE BODY XTR_MM_FORMULAS AS
2 /* $Header: xtrmmflb.pls 120.2 2005/06/29 11:19:18 rjose ship $ */
3
4 --
5 -- Calculates the value of $1 after DAY_COUNT period given the
6 -- ANNUAL_BASIS and Annual Rate (RATE).
7 --
8 -- * P_RATE = the annual rate.
9 -- * P_DAY_COUNT = the number of days for which the GROWTH_FACTOR
10 -- is calculated
11 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
12 -- DAY_COUNT are based on
13 -- * P_GROWTH_FAC = the value of $1 after DAY_COUNT period given the
14 -- ANNUAL_BASIS and Annual Rate (RATE).
15 --
16 PROCEDURE growth_factor(p_rate IN NUMBER,
17 p_day_count IN NUMBER,
18 p_annual_basis IN NUMBER,
19 p_growth_fac IN OUT NOCOPY NUMBER) is
20 BEGIN
21
22 p_growth_fac := 1 + (p_rate * p_day_count) / (100 * p_annual_basis);
23
24 END growth_factor;
25
26
27
28 --
29 -- Calculates the PRESENT_VALUE given the discount rate as inputs.
30 --
31 -- * P_FUTURE_VALUE = the amount at maturity (i.e. Maturity Amount in
32 -- Discounted Securities Calculator HLD).
33 -- * P_DISCOUNT_RATE = the return in a discounted security as an
34 -- annualized percentage of the future amount.
35 -- * P_PRESENT_VALUE = the fair value of the discounted security.
36 -- * P_DAY_COUNT = number of days between the PRESENT_VALUE date and
37 -- FUTURE_VALUE date. (For example: DAY_COUNT = Maturity Date -
38 -- Settlement Date in Discounted Securities Calculator HLD).
39 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
40 -- DAY_COUNT are based on.
41 --
42 -- ######################################################################
43 -- # #
44 -- # WARNING!!!!! The procedure should never be called directly, please #
45 -- # call xtr_mm_covers.present_value instead. #
46 -- # #
47 -- ######################################################################
48 --
49 PROCEDURE present_value_discount_rate(p_future_value IN NUMBER,
50 p_discount_rate IN NUMBER,
51 p_day_count IN NUMBER,
52 p_annual_basis IN NUMBER,
53 p_present_value IN OUT NOCOPY NUMBER) is
54 v_growth_fac NUMBER;
55
56 BEGIN
57
58 growth_factor(p_discount_rate, p_day_count, p_annual_basis, v_growth_fac);
59
60 p_present_value := p_future_value * (1 - (v_growth_fac -1));
61
62 END present_value_discount_rate;
63
64
65
66 --
67 -- Calculates the PRESENT_VALUE given the yield rate as inputs.
68 --
69 -- * P_FUTURE_VALUE = the amount at maturity
70 -- * P_YIELD_RATE = the return in a discounted security as an
71 -- annualized percentage of the current amount.
72 -- * P_PRESENT_VALUE = the fair value of the discounted security.
73 -- * P_DAY_COUNT = number of days between the PRESENT_VALUE date
74 -- and FUTURE_VALUE date.
75 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and
76 -- the DAY_COUNT are based on.
77 --
78 -- ######################################################################
79 -- # #
80 -- # WARNING!!!!! The procedure should never be called directly, please #
81 -- # call xtr_mm_covers.present_value instead. #
82 -- # #
83 -- ######################################################################
84 --
85 PROCEDURE present_value_yield_rate(p_future_value IN NUMBER,
86 p_yield_rate IN NUMBER,
87 p_day_count IN NUMBER,
88 p_annual_basis IN NUMBER,
89 p_present_value IN OUT NOCOPY NUMBER) IS
90
91 v_growth_fac NUMBER;
92
93 BEGIN
94
95 growth_factor(p_yield_rate, p_day_count, p_annual_basis, v_growth_fac);
96
97 p_present_value := p_future_value/v_growth_fac;
98
99 END present_value_yield_rate;
100
101
102
103
104 --
105 -- Calculates the FUTURE_VALUE given the yield rate as inputs.
106 --
107 -- * P_FUTURE_VALUE = the amount at maturity (i.e. Maturity Amount in
108 -- Discounted Securities Calculator HLD).
109 -- * P_YIELD_RATE = the return in a discounted security as an annualized
110 -- percentage of the current amount.
111 -- * P_PRESENT_VALUE = the fair value of the discounted security.
112 -- * P_DAY_COUNT = number of days between the PRESENT_VALUE date and
113 -- FUTURE_VALUE date. (For example: DAY_COUNT = Maturity Date - Settlement
114 -- Date in Discounted Securities Calculator HLD).
115 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
116 -- DAY_COUNT are based on.
117 --
118 -- ######################################################################
119 -- # #
120 -- # WARNING!!!!! The procedure should never be called directly, please #
121 -- # call xtr_mm_covers.future_value instead. #
122 -- # #
123 -- ######################################################################
124 --
125 PROCEDURE future_value_yield_rate(p_present_value IN NUMBER,
126 p_yield_rate IN NUMBER,
127 p_day_count IN NUMBER,
128 p_annual_basis IN NUMBER,
129 p_future_value IN OUT NOCOPY NUMBER) IS
130
131 v_growth_fac NUMBER;
132
133 BEGIN
134
135 growth_factor(p_yield_rate, p_day_count, p_annual_basis, v_growth_fac);
136
137 p_future_value := p_present_value * v_growth_fac;
138
139 END future_value_yield_rate;
140
141
142
143 --
144 -- Calculates the FUTURE_VALUE given the discount rate as inputs.
145 --
146 -- * P_FUTURE_VALUE = the amount at maturity
147 -- * P_PRESENT_VALUE = the fair value of the discounted security.
148 -- * P_DISCOUNT_RATE = the return in a discounted security as an annualized
149 -- percentage of the future amount.
150 -- * P_DAY_COUNT = number of days between the PRESENT_VALUE date and
151 -- FUTURE_VALUE date.
152 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
153 -- DAY_COUNT are based on.
154 --
155 -- ######################################################################
156 -- # #
157 -- # WARNING!!!!! The procedure should never be called directly, please #
158 -- # call xtr_mm_covers.present_value instead. #
159 -- # #
160 -- ######################################################################
161 --
162 PROCEDURE future_value_discount_rate(p_present_value IN NUMBER,
163 p_discount_rate IN NUMBER,
164 p_day_count IN NUMBER,
165 p_annual_basis IN NUMBER,
166 p_future_value IN OUT NOCOPY NUMBER) IS
167 BEGIN
168
169 p_future_value := p_present_value * (1 + p_discount_rate * p_day_count /
170 (100 * p_annual_basis - p_discount_rate * p_day_count));
171
172 END future_value_discount_rate;
173
174
175
176 --
177 -- Calculates FRA Price (=Contract Rate) as defined in FRA Calculator HLD
178 --
179 --
180 -- * p_t = number of days from today to start date
181 -- * P_T1 = number of days from today to maturity date
182 -- * P_Rt = annual interest rate for maturity t days
183 -- * P_RT1 = annual interest rate for maturity T1 days
184 -- *** Assumed: Rt and RT1 have the same day count basis.
185 -- * p_year_basis = number of days in a year the interest rate is based on.
186 -- * p_fra_rate = fair contract rate of FRA (forward interest rate covering
187 -- from the Start Date to the Maturity Date).
188 --
189 PROCEDURE fra_price(p_t IN NUMBER,
190 p_T1 IN NUMBER,
191 p_Rt IN NUMBER,
192 p_Rt1 IN NUMBER,
193 p_year_basis IN NUMBER,
194 p_fra_rate IN OUT NOCOPY NUMBER) AS
195
196 BEGIN
197
198 IF (p_t is NOT NULL and p_T1 is NOT NULL and p_Rt is NOT NULL and
199 p_Rt1 is NOT NULL and p_year_basis is NOT NULL) THEN
200 -- Calc for Invest Rate
201 p_fra_rate := ((1 + p_RT1 * p_T1 / (p_year_basis * 100)) /
202 (1 + p_Rt * p_t / (p_year_basis * 100)) - 1) *
203 (p_year_basis * 100 / (p_T1 - p_t));
204 ELSE
205 RAISE_APPLICATION_ERROR
206 (-20001,'At least one of the required parameters is missing.');
207 END IF;
208
209 END fra_price;
210
211
212
213 --
214 -- Calculates the FRA Settlement Amount in FRA Calculator when the input
215 -- parameter is set to 'Yield'.
216 --
217 -- * P_FRA_PRICE = fra_rate = fair contract rate of FRA (forward interest
218 -- rate covering from the Start Date to the Maturity Date of the contract).
219 -- * P_SETTLEMENT_RATE = current market annual interest rate.
220 -- * P_FACE_VALUE = notional principal amount of FRA.
221 -- * P_DAY_COUNT = number of days between the Settlement Date to Maturity Date.
222 -- * P_ANNUAL_BASIS = number of days in a year the SETTLEMENT_RATE and
223 -- DAY_COUNT are based on.
224 -- * P_SETTLEMENT_AMOUNT = absolute profit or loss amount
225 --
226 -- ######################################################################
227 -- # #
228 -- # WARNING!!!!! The procedure should never be called directly, please #
229 -- # call xtr_mm_covers.fra_settlement_amount instead. #
230 -- # #
231 -- ######################################################################
232 --
233 PROCEDURE fra_settlement_amount_yield(
234 p_fra_price IN NUMBER,
235 p_settlement_rate IN NUMBER,
236 p_face_value IN NUMBER,
237 p_day_count IN NUMBER,
238 p_annual_basis IN NUMBER,
239 p_settlement_amount IN OUT NOCOPY NUMBER) IS
240
241 BEGIN
242
243 p_settlement_amount :=
244 (abs(p_fra_price - p_settlement_rate) * p_face_value * p_day_count) /
245 (100 * p_annual_basis + p_settlement_rate * p_day_count);
246
247 END fra_settlement_amount_yield;
248
249
250
251 --
252 -- Calculates the FRA Settlement Amount in FRA Calculator when the input
253 -- parameter is set to 'Discount'.
254 --
255 -- * P_FRA_PRICE = fra_rate = fair contract rate of FRA (forward interest
256 -- rate covering from the Start Date to the Maturity Date of the contract).
257 -- * P_SETTLEMENT_RATE = current market annual interest rate.
258 -- * P_FACE_VALUE = notional principal amount of FRA.
259 -- * P_DAY_COUNT = number of days between the Settlement Date to Maturity Date.
260 -- * P_ANNUAL_BASIS = number of days in a year the SETTLEMENT_RATE and
261 -- DAY_COUNT are based on.
262 -- * P_SETTLEMENT_AMOUNT = absolute profit or loss amount
263 --
264 -- ######################################################################
265 -- # #
266 -- # WARNING!!!!! The procedure should never be called directly, please #
267 -- # call xtr_mm_covers.fra_settlement_amount instead. #
268 -- # #
269 -- ######################################################################
270 --
271 PROCEDURE fra_settlement_amount_discount(
272 p_fra_price IN NUMBER,
273 p_settlement_rate IN NUMBER,
274 p_face_value IN NUMBER,
275 p_day_count IN NUMBER,
276 p_annual_basis IN NUMBER,
277 p_settlement_amount IN OUT NOCOPY NUMBER) IS
278
279 v_growth_factor_contract NUMBER;
280 v_growth_factor_settlement NUMBER;
281
282 BEGIN
283
284 growth_factor(p_fra_price, p_day_count, p_annual_basis,
285 v_growth_factor_contract);
286
287 growth_factor(p_settlement_rate, p_day_count, p_annual_basis,
288 v_growth_factor_settlement);
289
290
291 p_settlement_amount := (abs(p_face_value * (1/v_growth_factor_contract -
292 1/v_growth_factor_settlement)));
293
294 END fra_settlement_amount_discount;
295
296
297
298 --
299 -- Calculates the price of a generic option.
300 --
301 -- * time_in_days = time left to maturity in days
302 -- * int_rate = annual risk free interest rate.
303 -- * market_price = the current market price of the commodity
304 -- * strike_price = the strike price agreed in the option.
305 -- * vol = volatility
306 -- * l_call_price = theoretical fair value of the call.
307 -- * L_put_price = theoretical fair value of the put
308 -- * l_delta_call/put = delta of the call/put
309 -- * l_theta_call/put = theta of the call/put
310 -- * l_rho_call/put = rho of the call/put
311 -- * l_gamma = gamma
312 -- * l_vega = vega
313 --
314 -- gamma, theta, delta, vega are sensitivity measurements of the model
315 -- relatives to its different variables and explained extensively in Hull's
316 -- Option, Future, and Other Derivatives.
317 --
318 PROCEDURE bs_option_price(time_in_days IN NUMBER,
319 int_rate IN NUMBER,
320 market_price IN NUMBER,
321 strike_price IN NUMBER,
322 vol IN NUMBER,
323 l_delta_call IN OUT NOCOPY NUMBER,
324 l_delta_put IN OUT NOCOPY NUMBER,
325 l_theta_call IN OUT NOCOPY NUMBER,
326 l_theta_put IN OUT NOCOPY NUMBER,
327 l_rho_call IN OUT NOCOPY NUMBER,
328 l_rho_put IN OUT NOCOPY NUMBER,
329 l_gamma IN OUT NOCOPY NUMBER,
330 l_vega IN OUT NOCOPY NUMBER,
331 l_call_price IN OUT NOCOPY NUMBER,
332 l_put_price IN OUT NOCOPY NUMBER) IS
333
334 --
335 -- Below are approximations of normal probability and PI(always fixed constant)
336 --
337 a1 NUMBER := 0.4361836;
338 a2 NUMBER := -0.1201678;
339 a3 NUMBER := 0.9372980;
340 pi NUMBER := 3.14159265358979;
341 --
342 r NUMBER := int_rate / 100;
343 t NUMBER := time_in_days / 360;
344 v NUMBER := vol / 100;
345 d1 NUMBER;
346 d2 NUMBER;
347 n_d1_a NUMBER;
348 k1 NUMBER;
349 n_d1_temp NUMBER;
350 n_d1 NUMBER;
351 n_d2_a NUMBER;
352 k2 NUMBER;
353 n_d2_temp NUMBER;
354 n_d2 NUMBER;
355 --
356 BEGIN
357
358 d1 := (LN(market_price/strike_price) + (r + POWER(v, 2)/2)*t)/(v * SQRT(t));
359 d2 := d1 - v*SQRT(t);
360 n_d1_a := EXP(-(POWER(abs(d1), 2)) / 2) / SQRT(2 * pi);
361 k1 := 1 / (1 + 0.33267 * ABS(d1));
362 n_d1_temp := 1 - n_d1_a*(a1*k1+a2*POWER(k1,2)+a3*POWER(k1,3));
363
364 IF d1 >= 0 THEN
365 n_d1 := n_d1_temp;
366 ELSE
367 n_d1 := 1 - n_d1_temp;
368 END IF;
369
370 n_d2_a := EXP(-(POWER(abs(d2),2)) / 2) / SQRT(2*pi);
371 k2 := 1/(1 + 0.33267 * ABS(d2));
372 n_d2_temp := 1-n_d2_a*(a1*k2+a2*POWER(k2,2)+a3*POWER(k2,3));
373
374 IF d2 >= 0 THEN
375 n_d2 := n_d2_temp;
376 ELSE
377 n_d2 := 1 - n_d2_temp;
378 END IF;
379
380 --
381 -- See Currency Options on the Philadelphia Exchange p272
382 --
383 l_call_price := EXP(-r*t)*(market_price * n_d1-strike_price*n_d2);
384 l_put_price := EXP(-r*t)*(strike_price*(1-n_d2)-market_price*(1-n_d1));
385
386 --
387 -- Black-Scholes Formulas
388 --
389 -- l_call_price := (market_price * n_d1)-(strike_price*EXP(-r*t)*n_d2);
390 -- l_put_price := strike_price*EXP(-r*t)*(1-n_d2)-market_price*(1-n_d1);
391 --
392
393 l_delta_call := n_d1;
394 l_delta_put := n_d1 - 1;
395 l_gamma := n_d1_a/(market_price*v*SQRT(t));
396 l_vega := market_price*SQRT(t)*n_d1_a;
397 l_theta_call := -((market_price*n_d1_a*v)/2/SQRT(t))-(r*strike_price*EXP(-r*t)*n_d2);
401
398 l_theta_put := -(market_price*n_d1_a*v/2/SQRT(t))+(r*strike_price*EXP(-r*t)*(1-n_d2));
399 l_rho_call := strike_price*t*EXP(-r*t)*n_d2;
400 l_rho_put := -strike_price*t*EXP(-r*t)*(1-n_d2);
402 END bs_option_price;
403
404
405
406 --
407 -- Calculates the cashflow given the coupon rate.
408 --
409 -- * PRINCIPAL_AMOUNT = the face value from which the cash flows are generated.
410 -- * P_RATE is the annual coupon rate.
411 -- * P_DAY_COUNT = number of days from the spot date/current date to the cash
412 -- flow payment date. (For example: DAY_COUNT = Maturity Date - Spot Date,
413 -- in IRS HLD).
414 -- * P_ANNUAL_BASIS = number of days in a year from which the DAY_COUNT and
415 -- RATE are based on.
416 --
417 PROCEDURE coupon_cashflow(p_principal_amount IN NUMBER,
418 p_rate IN NUMBER,
419 p_day_count IN NUMBER,
420 p_annual_basis IN NUMBER,
421 p_cashflow_value IN OUT NOCOPY NUMBER) IS
422
423 v_growth_fac NUMBER;
424
425 BEGIN
426
427 growth_factor(p_rate, p_day_count, p_annual_basis, v_growth_fac);
428
429 p_cashflow_value := p_principal_amount * (v_growth_fac - 1);
430
431 END coupon_cashflow;
432
433
434 --
435 -- Calculates the present value given the discount factor.
436 --
437 -- * P_DISCOUNT_FACTOR = a number between 0 and 1 that is use to calculate
438 -- the present value as a function of interest rate.
439 -- * P_FUTURE_VALUE = the amount at maturity.
440 -- * P_PRESENT_VALUE = the fair value of the discounted security.
441 --
442 PROCEDURE present_value_discount_factor(
443 p_discount_factor IN NUMBER,
444 p_future_value IN NUMBER,
445 p_present_value IN OUT NOCOPY NUMBER) IS
446
447 BEGIN
448
449 p_present_value := p_future_value * p_discount_factor;
450
451 END present_value_discount_factor;
452
453
454
455
456 /*--------------------------------------------------------------------------
457 BLACK_OPTION_PRICE Calculates the price and sensitivities of the interest rate option price using Blacks Formula.(Hull's 4th Edition p.540)
458
459 black_opt_in_rec_typ:
460 IN: P_PRINCIPAL num
461 P_INT_RATE num
462 P_FORWARD_RATE num
463 P_T1 num
464 P_T2 num
465 P_T2_INT_RATE num
466 P_VOLATILITY num
467 black_opt_out_rec_typ:
468 OUT: P_CAPLET_PRICE num
469 P_FLOORLET_PRICE num
470 P_ND1 num
471 P_ND2 num
472 P_ND1_A num
473 P_ND2_A num
474
475 Assumption: Annual Basis = 360
476 Continuous interest rate is required
477
478 Call XTR_RATE_CONVERSION.rate_conversion to convert day counts and/or between compounded and simple interest rates.
479
480 P_PRINCIPAL = the principal amount from which the interest rate is calculated
481 P_INT_RATE = strike price = interest rate for the deal
482 P_FORWARD_RATE = market forward rate for the period of the deal
483 P_T1 = number of days to the start date when the deal becomes effective.
484 P_T2 = number of days to the end date when the deal matures
485 p_T2_INT_RATE = current interest rate until the maturity date
486 P_VOLATILITY = volatility of interest rate per annum
487 P_CAPLET_PRICE = interest rate collars
488 P_FLOORLET_PRICE = interest rate floors(CAPLET_PRICE = FLOORLET_PRICE + SWAP_VALUE)
489 P_ND1/2 = cumulative normal probability distribution value = N(x) in Black Formula
490 P_ND1/2_A = N'(x) in Black Formula
491
492 --------------------------------------------------------------------------*/
493 --Addition by prafiuly 12/18/2000
494 --Modified: fhu 6/20/01
495
496 PROCEDURE black_option_price(p_in_rec IN black_opt_in_rec_type,
497 p_out_rec IN OUT NOCOPY black_opt_out_rec_type) is
498
499 --
500 -- a1 NUMBER := 0.4361836;
501 -- a2 NUMBER := -0.1201678;
502 -- a3 NUMBER := 0.9372980;
503
504 --
505 v_time_span NUMBER := p_in_rec.p_t2 - p_in_rec.p_t1;
506 v_t NUMBER := v_time_span/365; -- bug 3509267
507 v_t1 NUMBER := p_in_rec.p_t1/365;
508 v_t2 NUMBER := p_in_rec.p_t2/365;
509 v_forward NUMBER := p_in_rec.p_forward_rate/100;
510 v_vol NUMBER := p_in_rec.p_volatility/100;
511 v_ir NUMBER := p_in_rec.p_int_rate/100;
512 v_ir2 NUMBER := p_in_rec.p_t2_int_rate/100;
513 v_d1 NUMBER;
514 v_d2 NUMBER;
515 v_n_d1 NUMBER;
516 v_n_d2 NUMBER;
517 v_n_d1_a NUMBER;
518 v_n_d2_a NUMBER;
519 v_cum_normdist_in_rec cum_normdist_in_rec_type;
520 v_cum_normdist_out_rec cum_normdist_out_rec_type;
521
522 BEGIN
523
524 v_d1 := (LN(v_forward / v_ir) + 0.5 * POWER(v_vol, 2) * v_t1) /
525 (v_vol * SQRT(v_t1));
526
527 v_d2 := v_d1 - (v_vol * SQRT(v_t1));
528
529 v_cum_normdist_in_rec.p_d1 := v_d1;
530 v_cum_normdist_in_rec.p_d2 := v_d2;
531 cumulative_norm_distribution (v_cum_normdist_in_rec, v_cum_normdist_out_rec);
532
533 v_n_d1 := v_cum_normdist_out_rec.p_n_d1;
534 v_n_d2 := v_cum_normdist_out_rec.p_n_d2;
535
536 v_n_d1_a := v_cum_normdist_out_rec.p_n_d1_a;
537 v_n_d2_a := v_cum_normdist_out_rec.p_n_d2_a;
538
539 p_out_rec.p_caplet_price := p_in_rec.p_principal * v_t *
543 EXP(-v_ir2 * v_t2) * (v_ir * (1 - v_n_d2) - v_forward * (1 - v_n_d1));
540 EXP(-v_ir2 * v_t2) * (v_forward * v_n_d1 - v_ir * v_n_d2);
541
542 p_out_rec.p_floorlet_price := p_in_rec.p_principal * v_t *
544
545 p_out_rec.p_nd1 := v_n_d1;
546 p_out_rec.p_nd2 := v_n_d2;
547 p_out_rec.p_nd1_a := v_n_d1_a;
548 p_out_rec.p_nd2_a := v_n_d2_a;
549
550 END black_option_price;
551
552
553
554 /*---------------------------------------------------------------------------
555 --addition by prafiuly 02/01/01
556 --Find Cumulative Normal Distribution,precision up to 6 decimal places
557 --from Hull's Fourth Edition p.252
558 cum_normdist_in_rec_type:
559 p_d1 = the value of d1 from Black's formula
560 p_d2 = the value of d2 from Black's formula
561 cum_normdist_out_rec_type:
562 p_n_d1 = the cumulative normal distribution given p_d1
563 p_n_d2 = the cumulative normal distribution given p_d2
564
565 ----------------------------------------------------------------------------*/
566 PROCEDURE cumulative_norm_distribution (
567 p_in_rec IN cum_normdist_in_rec_type,
568 p_out_rec IN OUT NOCOPY cum_normdist_out_rec_type) is
569
570
571 c_a1 NUMBER := 0.319381530;
572 c_a2 NUMBER := -0.356563782;
573 c_a3 NUMBER := 1.781477937;
574 c_a4 NUMBER := -1.821255978;
575 c_a5 NUMBER := 1.330274429;
576 c_pi NUMBER := 3.14159265358979;
577 v_d1 NUMBER := p_in_rec.p_d1;
578 v_d2 NUMBER := p_in_rec.p_d2;
579 v_n_d1_a NUMBER;
580 v_k1 NUMBER;
581 v_n_d1_temp NUMBER;
582 v_n_d1 NUMBER;
583 v_n_d2_a NUMBER;
584 v_k2 NUMBER;
585 v_n_d2_temp NUMBER;
586 v_n_d2 NUMBER;
587
588
589 BEGIN
590
591 v_n_d1_a := EXP(-(POWER(ABS(v_d1), 2)) / 2) / SQRT(2 * c_pi);
592
593 v_k1 := 1 / (1 + 0.2316419 * ABS(v_d1));
594
595 v_n_d1_temp := 1 - v_n_d1_a*(c_a1 * v_k1 + c_a2 * POWER(v_k1, 2) +
596 c_a3 * POWER(v_k1, 3) + c_a4 * POWER(v_k1, 4) + c_a5 * POWER(v_k1, 5));
597
598 IF v_d1 >= 0 THEN
599 v_n_d1 := v_n_d1_temp;
600 ELSE
601 v_n_d1 := 1 - v_n_d1_temp;
602 END IF;
603
604 v_n_d2_a := EXP(-(POWER(abs(v_d2), 2)) / 2) / SQRT(2 * c_pi);
605
606 v_k2 := 1/(1 + 0.2316419 * ABS(v_d2));
607
608 v_n_d2_temp := 1 - v_n_d2_a * (c_a1 * v_k2 + c_a2 * POWER(v_k2, 2) +
609 c_a3 * POWER(v_k2, 3) + c_a4 * POWER(v_k2, 4) + c_a5 * POWER(v_k2, 5));
610
611 IF v_d2 >= 0 THEN
612 v_n_d2 := v_n_d2_temp;
613 ELSE
614 v_n_d2 := 1 - v_n_d2_temp;
615 END IF;
616
617 p_out_rec.p_n_d1 := v_n_d1;
618 p_out_rec.p_n_d2 := v_n_d2;
619 p_out_rec.p_n_d1_a := v_n_d1_a;
620 p_out_rec.p_n_d2_a := v_n_d2_a;
621 --
622 END cumulative_norm_distribution;
623
624
625 --
626 -- Calculates FRA Price (=Contract Rate) for compounded interest where
627 -- t2-t1 >= N
628 -- as defined in Market Data Curves HLD
629 --
630 --
631 -- * p_t = number of days from today to start date
632 -- * p_T1 = number of days from today to maturity date
633 -- * p_Rt = annual interest rate for maturity p_t days
634 -- * p_RT1 = annual interest rate for maturity p_T1 days
635 -- *** Assumed: Rt and RT1 have the same day count basis.
636 -- * p_year_basis = number of days in a year the interest rate is based on.
637 -- * p_fra_rate = fair contract rate of FRA (forward interest rate covering
638 -- from the Start Date to the Maturity Date).
639 --
640 PROCEDURE fra_price_long(p_t IN NUMBER,
641 p_T1 IN NUMBER,
642 p_Rt IN NUMBER,
643 p_Rt1 IN NUMBER,
644 p_year_basis IN NUMBER,
645 p_fra_rate IN OUT NOCOPY NUMBER) AS
646 BEGIN
647
648 IF (p_t is NOT NULL and p_T1 is NOT NULL and p_Rt is NOT NULL and
649 p_Rt1 is NOT NULL and p_year_basis is NOT NULL) THEN
650 -- Calc for Invest Rate
651 p_fra_rate := (power((power(1+(p_Rt1/100),p_T1/p_year_basis)/power(1+(p_Rt/100),p_t/p_year_basis)),p_year_basis/(p_T1-p_t))-1)*100;
652 ELSE
653 RAISE_APPLICATION_ERROR
654 (-20001,'At least one of the required parameters is missing.');
655 END IF;
656
657 END fra_price_long;
658
659
660 --
661 -- Calculates FRA Price (=Contract Rate) using discount factor as input rates
662 -- as defined in Market Data Curves HLD
663 --
664 --
665 -- * p_t = number of days from today to start date
666 -- * p_T1 = number of days from today to maturity date
667 -- * p_Rt = discount factor for maturity p_t days
668 -- * p_RT1 = discount factor for maturity p_T1 days
669 -- *** Assumed: Rt and RT1 have the same day count basis.
670 -- * p_year_basis = number of days in a year the interest rate is based on.
671 -- * p_fra_rate = fair contract rate of FRA (forward interest rate covering
672 -- from the Start Date to the Maturity Date).
673 --
674 PROCEDURE fra_price_df(p_t IN NUMBER,
675 p_T1 IN NUMBER,
676 p_Rt IN NUMBER,
677 p_Rt1 IN NUMBER,
678 p_year_basis IN NUMBER,
679 p_fra_rate IN OUT NOCOPY NUMBER) AS
680
681 BEGIN
682
683 IF (p_t is NOT NULL and p_T1 is NOT NULL and p_Rt is NOT NULL and
684 p_Rt1 is NOT NULL and p_year_basis is NOT NULL) THEN
685 -- Calc for Invest Rate
686 p_fra_rate := ((p_Rt/p_Rt1)-1)*(p_year_basis/(p_T1-p_t))*100;
687 ELSE
688 RAISE_APPLICATION_ERROR
689 (-20001,'At least one of the required parameters is missing.');
690 END IF;
691
692 END fra_price_df;
693
694
695 END;