DBA Data[Home] [Help]

PACKAGE BODY: APPS.XTR_RATE_CONVERSION

Source


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