1 PACKAGE BODY XTR_RATE_CONVERSION AS
2 /* $Header: xtrrtcvb.pls 120.1 2005/06/29 09:32:59 rjose ship $ */
3
4 --
5 -- Converts a discount rate to a yield rate.
6 --
7 -- * P_DISCOUNT_RATE = the return in discounted security as an annualized
8 -- percentage of the future amount.
9 -- * P_DAY_COUNT = number of days between the start deal date and maturity
10 -- deal date.
11 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
12 -- P_DAY_COUNT are based on.
13 -- * P_YIELD_RATE = the return in discounted security as an annualized
14 -- percentage of the current amount.
15 --
16 -- The formula is
17 -- 100 * annual basis * discount rate
18 -- p_discount_rate = ------------------------------------------------
19 -- 100 * annual basis - day count * discount rate
20 --
21 PROCEDURE discount_to_yield_rate(p_discount_rate IN NUMBER,
22 p_day_count IN NUMBER,
23 p_annual_basis IN NUMBER,
24 p_yield_rate IN OUT NOCOPY NUMBER) IS
25 v_growth_fac NUMBER;
26
27 BEGIN
28
29 xtr_mm_formulas.growth_factor(p_discount_rate, p_day_count,
30 p_annual_basis, v_growth_fac);
31
32 p_yield_rate := p_discount_rate * (1/(1 - (v_growth_fac - 1)));
33
34 END discount_to_yield_rate;
35
36
37
38 --
39 -- Converts a discount rate to a yield rate.
40 --
41 -- * P_YIELD_RATE = the return in discounted security as an annualized
42 -- percentage of the current amount.
43 -- * P_DAY_COUNT = number of days between the deal start date and deal
44 -- maturity date.
45 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
46 -- P_DAY_COUNT are based on.
47 -- * P_DISCOUNT_RATE = the return in discounted security as an annualized
48 -- percentage of the future amount.
49 --
50 -- The formula is
51 -- 100 * annual basis * yield rate
52 -- p_discount_rate = ---------------------------------------------
53 -- 100 * annual basis + day count * yield rate
54 --
55 PROCEDURE yield_to_discount_rate(p_yield_rate IN NUMBER,
56 p_day_count IN NUMBER,
57 p_annual_basis IN NUMBER,
58 p_discount_rate IN OUT NOCOPY NUMBER) IS
59 v_growth_fac NUMBER;
60
61 BEGIN
62
63 xtr_mm_formulas.growth_factor(p_yield_rate, p_day_count,
64 p_annual_basis, v_growth_fac);
65
66 p_discount_rate := p_yield_rate/v_growth_fac;
67
68 END yield_to_discount_rate;
69
70
71 --
72 -- Converts between rates of different day count basis.
73 --
74 -- * P_RATE_IN/OUT= annualized return/rate for the input/output rate.
75 -- * P_DAY_COUNT_IN/OUT = number of days between the deal start date and
76 -- deal maturity date for the input rate/output rate.
77 -- * P_ANNUAL_BASIS_IN/OUT = number of days in a year where the RATE and
78 -- the P_DAY_COUNT are based on.
79 --
80 PROCEDURE day_count_basis_conv(p_day_count_in IN NUMBER,
81 p_day_count_out IN NUMBER,
82 p_annual_basis_in IN NUMBER,
83 p_annual_basis_out IN NUMBER,
84 p_rate_in IN NUMBER,
85 p_rate_out IN OUT NOCOPY NUMBER) IS
86
87 BEGIN
88
89 IF (p_day_count_out <> 0) THEN
90 p_rate_out := (p_day_count_in * p_annual_basis_out * p_rate_in)/
91 (p_day_count_out * p_annual_basis_in);
92 ELSE
93 p_rate_out := p_rate_in;
94 END IF;
95
96 END day_count_basis_conv;
97
98
99 --
100 -- Converts a simple rate to a continuously compounded rate with
101 -- the same day count basis.
102 --
103 -- * P_SIMPLE_RATE = interest rate per annum that does not compound over time.
104 -- * P_NUM_YEARS = number of years in the period for which the rate is
105 -- effective.
106 -- * P_CONTINUOUS_RATE = compounded rate that has infinitesimal accrual time.
107 --
108 PROCEDURE simple_to_continuous_rate(p_simple_rate IN NUMBER,
109 p_num_years IN NUMBER,
110 p_continuous_rate IN OUT NOCOPY NUMBER) IS
111
112 BEGIN
113
114 p_continuous_rate := (LN(1 +(p_simple_rate/100)*p_num_years)/p_num_years)*100;
115
116 END simple_to_continuous_rate;
117
118
119 --
120 -- Converts continuously compounded rate to a simple rate with
121 -- the same day count basis.
122 --
123 -- * P_SIMPLE_RATE = interest rate per annum that does not compound over time.
124 -- * P_NUM_YEARS = number of years in the period for which the rate is
125 -- effective.
126 -- * P_CONTINUOUS_RATE = compounded rate that has infinitesimal accrual time.
127 --
128 PROCEDURE continuous_to_simple_rate(p_continuous_rate IN NUMBER,
129 p_num_years IN NUMBER,
130 p_simple_rate IN OUT NOCOPY NUMBER) IS
131 BEGIN
132
133 p_simple_rate := 100*(EXP((p_continuous_rate/100)*p_num_years)-1)/p_num_years;
134
135 END continuous_to_simple_rate;
136
137
138
139 --
140 -- Converts a simple rate to a discretely compounded rate with the same
141 -- day count basis.
142 --
143 -- * P_SIMPLE_RATE = interest rate per annum that does not compound overtime.
144 -- * P_NUM_YEARS = number of years in the period for which the rate is
145 -- effective.
146 -- * P_COMPOUNDTIMES = accrual frequency in a year for the P_COMPOUNDRATE.
147 -- * P_COMPOUNDRATE = a discretely compounded rate.
148 --
149 PROCEDURE simple_to_compound_rate(p_simple_rate IN NUMBER,
150 p_compound_times IN NUMBER,
151 p_num_years IN NUMBER,
152 p_compound_rate IN OUT NOCOPY NUMBER) IS
153
154 BEGIN
155
156 p_compound_rate := 100 * p_compound_times * (POWER((1 + (p_simple_rate/100) *
157 p_num_years), 1/(p_compound_times * p_num_years)) - 1);
158
159 END simple_to_compound_rate;
160
161
162
163 --
164 -- Converts a discretely compounded rate to a simple rate with the same
165 -- day count basis.
166 --
167 -- * P_SIMPLE_RATE = interest rate per annum that does not compound overtime.
168 -- * P_NUM_YEARS = number of years in the period for which the rate is
169 -- effective.
170 -- * P_COMPOUNDTIMES = accrual frequency in a year for the P_COMPOUNDRATE.
171 -- * P_COMPOUNDRATE = a discretely compounded rate.
172 --
173 PROCEDURE compound_to_simple_rate(p_compound_rate IN NUMBER,
174 p_compound_times IN NUMBER,
175 p_num_years IN NUMBER,
176 p_simple_rate IN OUT NOCOPY NUMBER) IS
177 BEGIN
178
179 p_simple_rate := 100 * (POWER((1 + (p_compound_rate/100)/p_compound_times),
180 (p_num_years * p_compound_times)) - 1) / p_num_years;
181
182 END compound_to_simple_rate;
183
184
185 --
186 -- Converts a continuously compounded rate to a discretely compounded rate
187 -- with the same day count basis.
188 --
189 -- * P_CONTINUOUS_RATE = compounded rate that has infinitesimal accrual time.
190 -- * P_COMPOUNDRATE = a discretely compounded rate.
191 -- * P_COMPOUNDTIMES = accrual frequency in a year for the P_COMPOUNDRATE.
192 --
193 PROCEDURE continuous_to_compound_rate(
194 p_continuous_rate IN NUMBER,
195 p_compound_times IN NUMBER,
196 p_compound_rate IN OUT NOCOPY NUMBER) IS
197 BEGIN
198
199 p_compound_rate := 100 * p_compound_times * (EXP((p_continuous_rate/100)/
200 p_compound_times) - 1);
201
202 END continuous_to_compound_rate;
203
204
205 --
206 -- Converts a discretely compounded rate to a continuously compounded
207 -- rate with the same day count basis.
208 --
209 -- * P_CONTINUOUS_RATE = compounded rate that has infinitesimal accrual time.
210 -- * P_COMPOUNDRATE = a discretely compounded rate.
211 -- * P_COMPOUNDTIMES = accrual frequency in a year for the P_COMPOUNDRATE.
212 --
213 PROCEDURE compound_to_continuous_rate(p_compound_rate IN NUMBER,
214 p_compound_times IN NUMBER,
215 p_continuous_rate IN OUT NOCOPY NUMBER) IS
216 BEGIN
217
218 p_continuous_rate := 100 * p_compound_times * LN(1 + (p_compound_rate/100)/
219 p_compound_times);
220
221 END compound_to_continuous_rate;
222
223
224 --
225 -- Converts between two different discretely compounded interest rates with
226 -- different compounding frequency (with the same day count basis).
227 --
228 -- * P_COMPOUNDRATE_IN= a discretely compounded rate that is to be converted.
229 -- * P_COMPOUNDTIMES_IN/OUT = accrual frequency in a year for the
230 -- P_COMPOUNDRATE_IN/OUT.
231 -- * P_COMPOUNDRATE_OUT = a discretely compounded rate that is to be
232 -- calculated.
233 --
234 PROCEDURE compound_to_compound_rate(
235 p_compound_rate_in IN NUMBER,
236 p_compound_times_in IN NUMBER,
237 p_compound_times_out IN NUMBER,
238 p_compound_rate_out IN OUT NOCOPY NUMBER) IS
239
240 BEGIN
241
242 p_compound_rate_out := 100 * p_compound_times_out *
243 (POWER((1 + (p_compound_rate_in/100)/p_compound_times_in),
244 (p_compound_times_in/p_compound_times_out)) - 1);
245
246 END compound_to_compound_rate;
247
248
249 /*----------------------------------------------------------------------------
250 addition by prafiuly 02/05/01
251
252 ******************************************************************************
253 IMPORTANT: the result of doing day count basis conversion first and then doing
254 rate type conversion second is different from the result of doing the rate
255 type conversion first and then doing the day count basis conversion second.
256 This causes some inconsistencies in the result. For example: the result of
257 converting from a simple rate to a compounded rate with different day count
258 basis and then converting it back to a simple rate type with its original
259 day count basis will not be the same as the original value of the simple rate.
260 The problem is not caused by the implementation/coding, but is caused by
261 methodologies used as described in the Rate Conversions HLD.
262 ******************************************************************************
263
264 RATE_CONVERSION: converts between two rates that have different day count basis
265 or compounding types.
266
267 Note: this procedure does not cover DISCOUNT_TO_YIELD_RATE and
268 YIELD_TO_DISCOUNT_RATE conversions.
269
270 RATE_CONV_IN_REC_TYPE:
271 p_START_DATE date
272 p_END_DATE date
273 p_DAY_COUNT_BASIS_IN varchar2
274 p_DAY_COUNT_BASIS_OUT varchar2
275 p_RATE_TYPE_IN char
276 p_RATE_TYPE _OUT char
277 p_COMPOUND_FREQ_IN num
278 p_COMPOUND_FREQ_OUT num
279 p_RATE_IN num
280 RATE_CONV_OUT_REC_TYPE:
281 p_ RATE_OUT num
282
283 Formula:
284 Call XTR_CALC_P.DAYS_CALC_RUN_C(...);
285 IF p_DAY_COUNT_BASIS_IN?OUT is NOT NULL THEN
286 Call DAY_COUNT_BASIS_CONV(...)
287 IF p_RATE_TYPE_IN/OUT is NOT NULL THEN
288 Calculate v_Num_Years
289 Depending on p_RATE_TYPE_IN/OUT, call the appropriate Rate Types Conversion
290 procedure (from above).
291
292 Assumption: the effective period for the rates is one year.
293
294 p_START_DATE = the start date when the rates becomes effective.
295 p_END_DATE = the end date of the rates.
296 p_DAY_COUNT_BASIS_IN/OUT = the day count basis for the input rate and the
297 output rate. This are only necessary if the rates day count basis are different.
298 p_RATE_TYPE_IN/OUT = the input/output rates type. 'S' for Simple Rate, 'C' for
299 Continuous Rate, and 'P' for Compounding Rate. This is only necessary if the
300 conversion involve different rate types.
301 p_COMPOUND_FREQ_IN/OUT = frequencies of discretely compounded input/output rate.
302 This is only necessary if either p_RATE_TYPE_IN or p_RATE_TYPE_OUT is 'P'.
303 p_RATE_IN/OUT = the input/output rates.
304 -----------------------------------------------------------------------------*/
305
306 PROCEDURE rate_conversion (p_in_rec IN rate_conv_in_rec_type,
307 p_out_rec IN OUT NOCOPY rate_conv_out_rec_type) is
308
309 v_num_years NUMBER;
310 v_dummy NUMBER;
311 v_day_count_in NUMBER;
312 v_ann_basis_in NUMBER;
313 v_day_count_out NUMBER;
314 v_ann_basis_out NUMBER;
315 v_temp_rate NUMBER;
316 v_rt_in CHAR;
317 v_rt_out CHAR;
318 e_invalid_rate_type EXCEPTION;
319 e_invalid_dc_basis EXCEPTION;
320
321 BEGIN
322
323 IF (p_in_rec.p_day_count_basis_out IS NOT NULL) THEN
324 xtr_calc_p.calc_days_run_c(p_in_rec.p_start_date, p_in_rec.p_end_date,
325 p_in_rec.p_day_count_basis_out, v_dummy,
326 v_day_count_out, v_ann_basis_out);
327 IF (p_in_rec.p_day_count_basis_in IS NOT NULL) and
328 (p_in_rec.p_day_count_basis_in <> p_in_rec.p_day_count_basis_out) THEN
329 xtr_calc_p.calc_days_run_c(p_in_rec.p_start_date, p_in_rec.p_end_date,
330 p_in_rec.p_day_count_basis_in, v_dummy,
331 v_day_count_in, v_ann_basis_in);
332 day_count_basis_conv(v_day_count_in, v_day_count_out, v_ann_basis_in,
333 v_ann_basis_out, p_in_rec.p_rate_in, v_temp_rate);
334 ELSE
335 v_temp_rate := p_in_rec.p_rate_in;
336 END IF;
337 ELSE
338 RAISE e_invalid_dc_basis;
339 END IF;
340
341 IF (p_in_rec.p_rate_type_in IS NOT NULL) and
342 (p_in_rec.p_rate_type_out IS NOT NULL) and
343 -- Avoid having the same in/out rate types except for compounding rates
344 ((p_in_rec.p_rate_type_in <> p_in_rec.p_rate_type_out) or
345 (upper(p_in_rec.p_rate_type_in)='P' and upper(p_in_rec.p_rate_type_out)='P'))
346 THEN
347 v_rt_in := upper(p_in_rec.p_rate_type_in);
348 v_rt_out := upper(p_in_rec.p_rate_type_out);
349 IF (v_rt_in IN ('C','S','P')) and (v_rt_out IN ('C','S','P')) THEN
350 IF (v_rt_in = 'S') THEN
351 IF (v_rt_out = 'C') THEN
352 v_num_years := v_day_count_out/v_ann_basis_out;
353 simple_to_continuous_rate(v_temp_rate,v_num_years,
354 p_out_rec.p_rate_out);
355 ELSIF (v_rt_out = 'P') THEN
356 v_num_years := v_day_count_out/v_ann_basis_out;
357 simple_to_compound_rate(v_temp_rate,p_in_rec.p_compound_freq_out,
358 v_num_years, p_out_rec.p_rate_out);
359 END IF;
360 ELSIF (v_rt_in = 'C') THEN
361 IF (v_rt_out = 'S') THEN
362 v_num_years := v_day_count_out/v_ann_basis_out;
363 continuous_to_simple_rate(v_temp_rate,v_num_years,
364 p_out_rec.p_rate_out);
365 ELSIF (v_rt_out = 'P') THEN
366 continuous_to_compound_rate(v_temp_rate,p_in_rec.p_compound_freq_out,
367 p_out_rec.p_rate_out);
368 END IF;
369 ELSIF (v_rt_in = 'P') THEN
370 IF (v_rt_out = 'S') THEN
371 v_num_years := v_day_count_out/v_ann_basis_out;
372 compound_to_simple_rate(v_temp_rate,p_in_rec.p_compound_freq_in,
373 v_num_years, p_out_rec.p_rate_out);
374 ELSIF (v_rt_out = 'C') THEN
375 compound_to_continuous_rate(v_temp_rate,p_in_rec.p_compound_freq_in,
376 p_out_rec.p_rate_out);
377 ELSIF (v_rt_out = 'P') THEN
378 compound_to_compound_rate(v_temp_rate,p_in_rec.p_compound_freq_in,
379 p_in_rec.p_compound_freq_out,
380 p_out_rec.p_rate_out);
381 END IF;
382 END IF;
383 ELSE
384 RAISE e_invalid_rate_type;
385 END IF;
386 ELSE
387 p_out_rec.p_rate_out := v_temp_rate;
388 END IF;
389
390
391 EXCEPTION
392
393 WHEN e_invalid_rate_type THEN
394 RAISE_APPLICATION_ERROR
395 (-20001, 'Rate Type code can only be ''C'',''S'',''P''.');
396 WHEN e_invalid_dc_basis THEN
397 RAISE_APPLICATION_ERROR
398 (-20002, 'p_DAY_COUNT_BASIS_OUT cannot be null');
399
400 END rate_conversion;
401
402 --
403 --YIELD_TO_DISCOUNT_FACTOR_SHORT
404 --Converts an annualized yield rate to a discount factor, assuming the number
405 --of days between spot date and maturity date is less than or equal to a year.
406 --
407 -- * P_RATE = the annual rate.
411 -- DAY_COUNT are based on
408 -- * P_DAY_COUNT = the number of days for which the GROWTH_FACTOR
409 -- is calculated
410 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
412 -- * P_DISCOUNT_FACTOR = the value of the consideration/present value
413 -- in order to have $1 in the maturity date (after DAY_COUNT period)
414 --
415 PROCEDURE yield_to_discount_factor_short(p_rate IN NUMBER,
416 p_day_count IN NUMBER,
417 p_annual_basis IN NUMBER,
418 p_discount_factor IN OUT NOCOPY NUMBER) is
419 BEGIN
420
421 p_discount_factor := 1/(1+((p_rate/100)*p_day_count/p_annual_basis));
422
423 END yield_to_discount_factor_short;
424
425
426 --
427 --YIELD_TO_DISCOUNT_FACTOR_LONG
428 --Converts an annualized yield rate to a discount factor, assuming the number
429 --of days between spot date and maturity date is less than or equal to a year.
430 --
431 -- * P_RATE = the annual rate.
432 -- * P_DAY_COUNT = the number of days for which the GROWTH_FACTOR
433 -- is calculated
434 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
435 -- DAY_COUNT are based on
436 -- * P_DISCOUNT_FACTOR = the value of the consideration/present value
437 -- in order to have $1 in the maturity date (after DAY_COUNT period)
438 --
439 PROCEDURE yield_to_discount_factor_long(p_rate IN NUMBER,
440 p_day_count IN NUMBER,
441 p_annual_basis IN NUMBER,
442 p_discount_factor IN OUT NOCOPY NUMBER) is
443 BEGIN
444
445 p_discount_factor := 1/power((1+(p_rate/100)),(p_day_count/p_annual_basis));
446
447 END yield_to_discount_factor_long;
448
449
450 --
451 --DISCOUNT_FACTOR_TO_YIELD_SHORT
452 --Converts a discount factor to an annualized yield rate, assuming the number
453 --of days between spot date and maturity date is less than or equal to a year.
454 --
455 -- * P_RATE = the annualized yield rate.
456 -- * P_DAY_COUNT = the number of days for which the GROWTH_FACTOR
457 -- is calculated
458 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
459 -- DAY_COUNT are based on
460 -- * P_DISCOUNT_FACTOR = the value of the consideration/present value
461 -- in order to have $1 in the maturity date (after DAY_COUNT period)
462 --
463 PROCEDURE discount_factor_to_yield_short(p_discount_factor IN NUMBER,
464 p_day_count IN NUMBER,
465 p_annual_basis IN NUMBER,
466 p_rate IN OUT NOCOPY NUMBER) IS
467 BEGIN
468
469 p_rate := (((1/p_discount_factor)-1)*p_annual_basis/p_day_count)*100;
470
471 END discount_factor_to_yield_short;
472
473
474 --
475 --DISCOUNT_FACTOR_TO_YIELD_LONG
476 --Converts an annualized yield rate to a discount factor, assuming the number
477 --of days between spot date and maturity date is more than a year.
478 --
479 -- * P_RATE = the annualized yield rate.
480 -- * P_DAY_COUNT = the number of days for which the GROWTH_FACTOR
481 -- is calculated
482 -- * P_ANNUAL_BASIS = number of days in a year where the RATE and the
483 -- DAY_COUNT are based on
484 -- * P_DISCOUNT_FACTOR = the value of the consideration/present value
485 -- in order to have $1 in the maturity date (after DAY_COUNT period)
486 --
487 PROCEDURE discount_factor_to_yield_long(p_discount_factor IN NUMBER,
488 p_day_count IN NUMBER,
489 p_annual_basis IN NUMBER,
490 p_rate IN OUT NOCOPY NUMBER) IS
491 BEGIN
492
493 p_rate := (power((1/p_discount_factor),(p_annual_basis/p_day_count))-1)*100;
494
495 END discount_factor_to_yield_long;
496
497
498 /*---------------------------------------------------------------------------
499 DISCOUNT_FACTOR_CONV
500 Converts an annualized yield rate to a discount factor and vice versa
501
502 Assumption:
503 If p_RATE_TYPE, p_COMPOUND_FREQ(if p_RATE_TYPE='P'), p_FUTURE_DATE,
504 p_SPOT_DATE, and p_DAY_COUNT_BASIS are not null then use them to calculate the
505 discount factor, else use p_DAY_COUNT and p_ANNUAL_BASIS, if they are not null.
506 If p_DAY_COUNT is null then p_FUTURE_DATE, p_SPOT_DATE, and p_DAY_COUNT_BASIS
507 are used to calculate the day count and the annual basis.
508 The first method should be used to avoid errors due to inconsistent rate type
509 and problem in determining a period less than or greater than a year
510 (please refer to Bug 2295869 and related Bug 2354567).
511
512 p_INDICATOR = an indicator that tells whether the conversion is from yield
513 rate to discount factor ('T') or from discount factor to yield rate ('F').
514 p_RATE = the annualized yield rate or the discount factor depending on the
515 value of the p_INDICATOR.
516 p_DAY_COUNT = the number of days for which the p_GROWTH_FACTOR is calculated
517 p_ANNUAL_BASIS = number of days in a year where the p_RATE and the p_DAY_COUNT
518 are based on.
519 p_RESULT = the discount factor or the annualized yield rate depending on the
520 value of the p_INDICATOR.
521 p_SPOT_DATE = the start date of the p_RATE.
522 p_FUTURE_DATE = the end date of the p_RATE.
523 p_RATE_TYPE = the p_RATE rate's type. 'S' for Simple Rate. 'C' for
524 Continuous Rate, and 'P' for Compounding Rate.
528 PROCEDURE discount_factor_conv(p_in_rec IN df_in_rec_type,
525 p_COMPOUND_FREQ = frequencies of discretely compounded input rate.
526 p_DAY_COUNT_BASIS = the day count basis of p_RATE.
527 ---------------------------------------------------------------------------*/
529 p_out_rec IN OUT NOCOPY df_out_rec_type) IS
530
531 v_day_count NUMBER;
532 v_annual_basis NUMBER;
533 v_day_count_act NUMBER;
534 v_ann_basis_act NUMBER;
535 v_rate NUMBER;
536 v_cf_necessary BOOLEAN := FALSE;
537 v_rc_in xtr_rate_conversion.rate_conv_in_rec_type;
538 v_rc_out xtr_rate_conversion.rate_conv_out_rec_type;
539
540 BEGIN
541 --Determine whether p_compounding_freq is necessary
542 IF p_in_rec.p_rate_type='P' THEN
543 v_cf_necessary := TRUE;
544 END IF;
545
546 --Determine whether we need to calc using p_RATE_TYPE,
547 --p_COMPOUND_FREQ(if p_RATE_TYPE='P'), p_FUTURE_DATE,
548 --p_SPOT_DATE, and p_DAY_COUNT_BASIS
549 IF p_in_rec.p_future_date IS NOT NULL AND p_in_rec.p_spot_date IS NOT NULL
550 AND p_in_rec.p_day_count_basis IS NOT NULL AND p_in_rec.p_rate_type IS NOT
551 NULL AND p_in_rec.p_indicator = 'T' AND v_cf_necessary THEN
552 --Calculate the annual basis and day count based on ACT/ACT to get
553 --fair comparison
554 xtr_calc_p.calc_days_run_c(p_in_rec.p_spot_date, p_in_rec.p_future_date,
555 'ACTUAL/ACTUAL', null, v_day_count_act,
556 v_ann_basis_act);
557 --Made sure the rate is Simple for < 1 Year and annualized for >= 1 Year.
558 v_rc_in.p_rate_type_in := p_in_rec.p_rate_type;
559 v_rc_in.p_day_count_basis_in := p_in_rec.p_day_count_basis;
560 v_rc_in.p_rate_in := p_in_rec.p_rate;
561 v_rc_in.p_start_date := p_in_rec.p_spot_date;
562 v_rc_in.p_end_date := p_in_rec.p_future_date;
563 v_rc_in.p_compound_freq_in := p_in_rec.p_compound_freq;
564 xtr_rate_conversion.rate_conv_simple_annualized(v_rc_in, v_rc_out);
565 v_rate := v_rc_out.p_rate_out;
566 --get annual basis and day count based on the given day count basis
567 xtr_calc_p.calc_days_run_c(p_in_rec.p_spot_date,
568 p_in_rec.p_future_date,
569 p_in_rec.p_day_count_basis, null, v_day_count,
570 v_annual_basis);
571 ELSIF p_in_rec.p_annual_basis IS NOT NULL AND p_in_rec.p_day_count IS NOT
572 NULL THEN
573 v_day_count_act := p_in_rec.p_day_count;
574 v_ann_basis_act := p_in_rec.p_annual_basis;
575 v_rate := p_in_rec.p_rate;
576 v_day_count := p_in_rec.p_day_count;
577 v_annual_basis := p_in_rec.p_annual_basis;
578 ELSE
579 --Calculate the annual basis and day count based on ACT/ACT to get
580 --fair comparison
581 xtr_calc_p.calc_days_run_c(p_in_rec.p_spot_date, p_in_rec.p_future_date,
582 'ACTUAL/ACTUAL', null, v_day_count_act,
583 v_ann_basis_act);
584 v_rate := p_in_rec.p_rate;
585 xtr_calc_p.calc_days_run_c(p_in_rec.p_spot_date,
586 p_in_rec.p_future_date,
587 p_in_rec.p_day_count_basis, null, v_day_count,
588 v_annual_basis);
589 END IF;
590
591 --start the logic to determine which discount factor conversion should be
592 --called
593 IF (p_in_rec.p_indicator = 'F') THEN
594 IF (v_ann_basis_act >= v_day_count_act) THEN
595 --do the less than a year discount factor
596 discount_factor_to_yield_short(v_rate,
597 v_day_count,
598 v_annual_basis,
599 p_out_rec.p_result);
600 ELSE
601 --do the more than a year discount factor
602 discount_factor_to_yield_long(v_rate,
603 v_day_count,
604 v_annual_basis,
605 p_out_rec.p_result);
606 END IF;
607 ELSE --(p_in_rec.p_indicator = 'T')
608 IF (v_ann_basis_act >= v_day_count_act) THEN
609 --do the less than a year discount factor
610 yield_to_discount_factor_short(v_rate,
611 v_day_count,
612 v_annual_basis,
613 p_out_rec.p_result);
614 ELSE
615 --do the more than a year discount factor
616 yield_to_discount_factor_long(v_rate,
617 v_day_count,
618 v_annual_basis,
619 p_out_rec.p_result);
620 END IF;
621 END IF;
622
623 END discount_factor_conv;
624
625
626 /*----------------------------------------------------------------------------
627 RATE_CONV_SIMPLE_ANNUALIZED: converts the given rate to a simple rate
628 if the period between p_START_DATE and p_END_DATE is less than or equal
629 to a year or
630 to an annually compounded rate if the period between p_START_DATE and
631 p_END_DATE is greater than a year.
632
633 ******************************************************************************
634 IMPORTANT: The above is currently the assumption for the System Rates, and
635 what is expected for some of the cover routine API.
636 ******************************************************************************
637
638 Moreover, if p_DAY_COUNT_BASIS_OUT is NULL, this procedure will keep the
639 day count basis of p_RATE_IN, otherwise it will convert to whatever defined
640 in p_DAY_COUNT_BASIS_OUT.
641
642 Note: this procedure does not cover DISCOUNT_TO_YIELD_RATE and
643 YIELD_TO_DISCOUNT_RATE conversions.
644
645 RATE_CONV_IN_REC_TYPE:
646 p_START_DATE date
647 p_END_DATE date
648 p_DAY_COUNT_BASIS_IN varchar2
649 p_DAY_COUNT_BASIS_OUT varchar2
650 p_RATE_TYPE_IN char
651 p_COMPOUND_FREQ_IN num
652 p_RATE_IN num
656 Assumption: the effective period for the rates is one year.
653 RATE_CONV_OUT_REC_TYPE:
654 p_RATE_OUT num
655
657
658 p_START_DATE = the start date when the rates becomes effective.
659 p_END_DATE = the end date of the rates.
660 p_DAY_COUNT_BASIS_IN/OUT = the day count basis for the input rate and the
661 output rate. This are only necessary if the rates day count basis are
662 different.
663 p_RATE = the annualized yield rate or the discount factor depending on the
664 value of the p_INDICATOR.
665 p_RATE_TYPE_IN = the input rates type. 'S' for Simple Rate, 'C' for
666 Continuous Rate, and 'P' for Compounding Rate. This is only necessary if the
667 conversion involve different rate types.
668 p_COMPOUND_FREQ_IN = frequencies of discretely compounded input
669 rate.
670 This is only necessary if either p_RATE_TYPE_IN or p_RATE_TYPE_OUT is 'P'.
671 p_RATE_IN/OUT = the input/output rates.
672 -----------------------------------------------------------------------------*/
673 PROCEDURE rate_conv_simple_annualized (p_in_rec IN rate_conv_in_rec_type,
674 p_out_rec IN OUT NOCOPY rate_conv_out_rec_type) IS
675 v_day_count NUMBER;
676 v_ann_basis NUMBER;
677 v_rc_in rate_conv_in_rec_type;
678 v_rc_out rate_conv_out_rec_type;
679 BEGIN
680 --find out whether the rate less than a year or not
681 xtr_calc_p.calc_days_run_c(p_in_rec.p_start_date, p_in_rec.p_end_date,
682 'ACTUAL/ACTUAL', null,
683 v_day_count, v_ann_basis);
684 IF v_day_count<=v_ann_basis THEN --convert to simple rate
685 --only converts if not Simple rate already
686 IF p_in_rec.p_rate_type_out='S' AND
687 (p_in_rec.p_day_count_basis_out IS NULL OR
688 p_in_rec.p_day_count_basis_in=p_in_rec.p_day_count_basis_out) THEN
689 p_out_rec.p_rate_out := p_in_rec.p_rate_in;
690 ELSE
691 v_rc_in.p_rate_type_out := 'S';
692 IF p_in_rec.p_day_count_basis_out IS NULL THEN
693 v_rc_in.p_day_count_basis_out := p_in_rec.p_day_count_basis_in;
694 ELSE
695 v_rc_in.p_day_count_basis_out := p_in_rec.p_day_count_basis_out;
696 END IF;
697 v_rc_in.p_rate_type_in := p_in_rec.p_rate_type_in;
698 v_rc_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_in;
699 v_rc_in.p_rate_in := p_in_rec.p_rate_in;
700 v_rc_in.p_start_date := p_in_rec.p_start_date;
701 v_rc_in.p_end_date := p_in_rec.p_end_date;
702 v_rc_in.p_compound_freq_in := p_in_rec.p_compound_freq_in;
703 xtr_rate_conversion.rate_conversion(v_rc_in, v_rc_out);
704 p_out_rec.p_rate_out := v_rc_out.p_rate_out;
705 END IF;
706 ELSE --convert to annually compounding
707 --only converts if not Annually compounding rate already
708 IF (p_in_rec.p_rate_type_out='P' AND p_in_rec.p_compound_freq_in=1)
709 AND (p_in_rec.p_day_count_basis_out IS NULL OR
710 p_in_rec.p_day_count_basis_in=p_in_rec.p_day_count_basis_out) THEN
711 p_out_rec.p_rate_out := p_in_rec.p_rate_in;
712 ELSE
713 v_rc_in.p_rate_type_out := 'P';
714 IF p_in_rec.p_day_count_basis_out IS NULL THEN
715 v_rc_in.p_day_count_basis_out := p_in_rec.p_day_count_basis_in;
716 ELSE
717 v_rc_in.p_day_count_basis_out := p_in_rec.p_day_count_basis_out;
718 END IF;
719 v_rc_in.p_rate_type_in := p_in_rec.p_rate_type_in;
720 v_rc_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_in;
721 v_rc_in.p_rate_in := p_in_rec.p_rate_in;
722 v_rc_in.p_start_date := p_in_rec.p_start_date;
723 v_rc_in.p_end_date := p_in_rec.p_end_date;
724 v_rc_in.p_compound_freq_in := p_in_rec.p_compound_freq_in;
725 v_rc_in.p_compound_freq_out := 1;
726 xtr_rate_conversion.rate_conversion(v_rc_in, v_rc_out);
727 p_out_rec.p_rate_out := v_rc_out.p_rate_out;
728 END IF;
729 END IF;
730 END rate_conv_simple_annualized;
731
732 END;
733