[Home] [Help]
PACKAGE BODY: APPS.QRM_MM_FORMULAS
Source
1 PACKAGE BODY QRM_MM_FORMULAS AS
2 /* $Header: qrmmmflb.pls 120.14 2004/07/02 16:18:37 jhung ship $ */
3
4 /*--------------------------------------------------------------------------
5 BLACK_OPTION_SENS Calculates sensitivities of the interest rate option price using Blacks Formula.(Hull's 4th Edition p.540)
6
7 black_opt_sens_in_rec_typ:
8 IN:
9 p_PRINCIPAL num
10 p_STRIKE_RATE num
11 p_IR_SHORT num
12 p_RATE_TYPE_SHORT varchar2 DEFAULT 'S'
13 p_COMPOUND_FREQ_SHORT num
14 p_DAY_COUNT_BASIS_SHORT varchar2
15 p_IR_LONG num
16 p_RATE_TYPE_LONG varchar2 DEFAULT 'S'
17 p_COMPOUND_FREQ_LONG num
18 p_DAY_COUNT_BASIS_LONG varchar2
19 p_SPOT_DATE date
20 p_START_DATE date
21 p_MATURITY_DATE date
22 p_VOLATILITY num
23
24 IN: P_PRINCIPAL num
25 P_INT_RATE num
26 P_FORWARD_RATE num
27 P_SPOT_RATE num
28 P_T1 num
29 P_T2 num
30 P_T2_INT_RATE num
31 P_VOLATILITY num
32 black_opt_sens_out_rec_typ:
33 OUT: P_DELTA_CALL num
34 P_DELTA_PUT num
35 P_THETA_CALL num
36 P_THETA_PUT num
37 P_RHO_CALL num
38 P_RHO_PUT num
39 P_GAMMA num
40 P_VEGA num
41
42 Assumption: Annual Basis = 360
43 Continuous interest rate is required
44
45 Call XTR_RATE_CONVERSION.rate_conversion to convert day counts and/or between compounded and simple interest rates.
46
47 Calls XTR_MM_FORMULAS.black_option_price to get cumulative normal distribution
48 figures.
49
50 Note: All rates (not spot) are assumed to be in percentage form. Eg: interest rate of 0.08 should be inputted as 8.
51
52 P_PRINCIPAL = the principal amount from which the interest rate is calculated
53 P_INT_RATE = strike price = simple interest rate for the deal
54 P_FORWARD_RATE = market forward rate for the period of the deal
55 P_SPOT_RATE = spote rate from revaluation date to start/reset date
56 P_T1 = number of days to the start date when the deal becomes effective.
57 P_T2 = number of days to the end date when the deal matures
58 p_T2_INT_RATE = current interest rate until the maturity date
59 P_VOLATILITY = volatility of interest rate per annum
60
61 P_DELTA_CALL = delta call
62 P_DELTA_PUT = delta put
63 P_THETA_CALL = theta call
64 P_THETA_PUT = theta put
65 P_RHO_CALL = rho call
66 P_RHO_PUT = rho put
67 P_GAMMA = gamma
68 P_VEGA = vega
69
70 --------------------------------------------------------------------------*/
71 --Addition by fhu 6/19/01
72
73 PROCEDURE black_option_sens(p_in_rec IN black_opt_sens_in_rec_type,
74 p_out_rec IN OUT NOCOPY black_opt_sens_out_rec_type) is
75 v_n_d1 number;
76 v_n_d2 number;
77 v_n_d1_a number;
78 v_n_d2_a number;
79
80 -- spot rate from spot to start date
81 v_spot NUMBER := p_in_rec.p_ir_short/100;
82 v_day_count NUMBER;
83 v_annual_basis NUMBER;
84 v_t1 NUMBER; -- no of days from spot to start date
85 v_forward NUMBER;
86 -- strike rate
87 v_ir NUMBER := p_in_rec.p_strike_rate/100;
88 v_vol NUMBER := p_in_rec.p_volatility/100;
89
90 black_opt_price_in XTR_MM_COVERS.black_opt_cv_in_rec_type;
91 black_opt_price_out XTR_MM_COVERS.black_opt_cv_out_rec_type;
92 conv_in XTR_RATE_CONVERSION.rate_conv_in_rec_type;
93 conv_out XTR_RATE_CONVERSION.rate_conv_out_rec_type;
94
95 BEGIN
96
97 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
98 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.BLACK_OPTION_SENS');
99 END IF;
100
101 IF (v_vol = 0) THEN
102 raise e_option_vol_zero;
103 END IF;
104
105 black_opt_price_in.p_principal := p_in_rec.p_principal;
106 black_opt_price_in.p_strike_rate := p_in_rec.p_strike_rate;
107 black_opt_price_in.p_rate_type_strike := p_in_rec.p_rate_type_strike;
108 black_opt_price_in.p_compound_freq_strike := p_in_rec.p_compound_freq_strike;
109 black_opt_price_in.p_day_count_basis_strike := p_in_rec.p_day_count_basis_strike;
110 black_opt_price_in.p_ir_short := p_in_rec.p_ir_short;
111 black_opt_price_in.p_rate_type_short := p_in_rec.p_rate_type_short;
112 black_opt_price_in.p_compound_freq_short := p_in_rec.p_compound_freq_short;
113 black_opt_price_in.p_day_count_basis_short := p_in_rec.p_day_count_basis_short;
114 black_opt_price_in.p_ir_long := p_in_rec.p_ir_long;
115 black_opt_price_in.p_rate_type_long := p_in_rec.p_rate_type_long;
116 black_opt_price_in.p_compound_freq_long := p_in_rec.p_compound_freq_long;
117 black_opt_price_in.p_day_count_basis_long := p_in_rec.p_day_count_basis_long;
118 black_opt_price_in.p_spot_date := p_in_rec.p_spot_date;
119 black_opt_price_in.p_start_date := p_in_rec.p_start_date;
120 black_opt_price_in.p_maturity_date := p_in_rec.p_maturity_date;
121 black_opt_price_in.p_volatility := p_in_rec.p_volatility;
122
123 -- Call XTR_MM_FORMULAS.black_option_price
124 XTR_MM_COVERS.black_option_price_cv(black_opt_price_in,
125 black_opt_price_out);
126 v_n_d1 := black_opt_price_out.p_nd1;
127 v_n_d2 := black_opt_price_out.p_nd2;
128 v_n_d1_a := black_opt_price_out.p_nd1_a;
129 v_n_d2_a := black_opt_price_out.p_nd2_a;
130 v_forward := black_opt_price_out.p_forward_forward_rate/100;
131
132 -- calculate t1: number of days from spot to start date
133 -- day count basis is Actual/365 -- bug 3611158
134 XTR_CALC_P.calc_days_run_c(p_in_rec.p_spot_date, p_in_rec.p_start_date, 'ACTUAL365', null, v_day_count, v_annual_basis);
135 v_t1 := v_day_count/365;
136
137 -- convert v_spot to continously compounded, Actual/365 day count basis
138 IF NOT (p_in_rec.p_rate_type_short IN ('C','c') AND
139 p_in_rec.p_day_count_basis_short = 'ACTUAL365') THEN
140 conv_in.p_start_date := p_in_rec.p_spot_date;
141 conv_in.p_end_date := p_in_rec.p_start_date;
142 conv_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_short;
143 conv_in.p_day_count_basis_out := 'ACTUAL365';
144 conv_in.p_rate_type_in := p_in_rec.p_rate_type_short;
145 conv_in.p_rate_type_out := 'C';
146 conv_in.p_compound_freq_in := p_in_rec.p_compound_freq_short;
147 conv_in.p_rate_in := p_in_rec.p_ir_short;
148 XTR_RATE_CONVERSION.rate_conversion(conv_in,conv_out);
149 v_spot := conv_out.p_rate_out/100;
150 END IF;
151
152 -- convert strike rate to simple Actual/365 day count basis
153 IF NOT (p_in_rec.p_rate_type_strike IN ('S','s') AND
154 p_in_rec.p_day_count_basis_strike = 'ACTUAL365') THEN
155 conv_in.p_start_date := p_in_rec.p_start_date;
156 conv_in.p_end_date := p_in_rec.p_maturity_date;
157 conv_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_strike;
158 conv_in.p_day_count_basis_out := 'ACTUAL365';
159 conv_in.p_rate_type_in := p_in_rec.p_rate_type_strike;
160 conv_in.p_rate_type_out := 'S';
161 conv_in.p_compound_freq_in := p_in_rec.p_compound_freq_strike;
162 conv_in.p_rate_in := p_in_rec.p_strike_rate;
163 XTR_RATE_CONVERSION.rate_conversion(conv_in,conv_out);
164 v_ir := conv_out.p_rate_out/100;
165 END IF;
166
167 IF (g_proc_level>=g_debug_level) THEN
168 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'spot rate: '||v_spot);
169 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 't1: '||v_t1);
170 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'N(d1): '||v_n_d1);
171 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'forward: '||v_forward);
172 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'N(d2): '||v_n_d2);
173 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'N''(d1): '||v_n_d1_a);
174 XTR_RISK_DEBUG_PKG.dlog('black_option_sens: ' || 'strike rate: '||v_ir);
175 END IF;
176
177 -- sensitivities calculation
178 p_out_rec.p_delta_cap := EXP(-v_spot*v_t1)*v_n_d1;
179 p_out_rec.p_delta_floor := EXP(-v_spot*v_t1)*(v_n_d1-1);
180
181 p_out_rec.p_theta_cap := -(v_forward*v_n_d1_a*v_vol*EXP(-v_spot*v_t1))/
182 (2*SQRT(v_t1)) + v_spot*v_forward*v_n_d1*EXP(-v_spot*v_t1) -
183 v_spot*v_ir*EXP(-v_spot*v_t1)*v_n_d2;
184 p_out_rec.p_theta_floor := -(v_forward*v_n_d1_a*v_vol*EXP(-v_spot*v_t1))/
185 (2*SQRT(v_t1)) - v_spot*v_forward*(1-v_n_d1)*EXP(-v_spot*v_t1)
186 + v_spot*v_ir*EXP(-v_spot*v_t1)*(1-v_n_d2);
187
188 p_out_rec.p_rho_cap := v_ir*v_t1*EXP(-v_spot*v_t1)*v_n_d2;
189 p_out_rec.p_rho_floor := -v_ir*v_t1*EXP(-v_spot*v_t1)*(1-v_n_d2);
190
191 p_out_rec.p_gamma := (v_n_d1_a*EXP(-v_spot*v_t1))/(v_forward*v_vol*SQRT(v_t1));
192 p_out_rec.p_vega := v_forward*SQRT(v_t1)*v_n_d1_a*EXP(-v_spot*v_t1);
193
194 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
195 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.BLACK_OPTION_SENS');
196 END IF;
197
198 END black_option_sens;
199
200 --########################################################################
201 --# #
202 --# Functions #
203 --# #
204 --########################################################################
205
206 -- addition by fhu 6/13/01
207 /*
208 Calculates DURATION of the following instruments:
209 - bond
210 - discounted securities
211 - forward rate agreement
212 - wholesale term money
213 - interest rate swap
214 as specified in: Robert Steiner, Mastering Financial Calculations, p.108
215
216 The arguments are defined as follows:
217 - p_pvc_array = contains present values stored in xtr_num_table;
218 value at index k corresponds to present value of kth
219 cashflow; = null for discounted securities and FRA;
220 k = 1,2,3,...
221 - p_days_array = number of days until kth cashflow; each kth element
222 corresponds to kth present value; for discounted
223 securities and FRA, array contains only one element
224 representing days to maturity
225 - p_days_in_year = number of days in a year
226 */
227
228 FUNCTION duration(p_pvc_array IN XTR_MD_NUM_TABLE,
229 p_days_array IN XTR_MD_NUM_TABLE,
230 p_days_in_year IN NUMBER)
231 RETURN NUMBER IS
232
233 p_num_sum NUMBER := 0;
234 p_denom_sum NUMBER := 0;
235
236 BEGIN
237
238 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
239 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.DURATION');
240 END IF;
241
242 -- fra or ni calculation if p_pvc_array is null
243 if (p_pvc_array is null) then
244 RETURN p_days_array(1)/p_days_in_year;
245 -- otherwise, if arrays not the same size, arguments are incorrect
246 elsif (p_pvc_array.count <> p_days_array.count
247 and p_pvc_array is not null) then
248 -- exception handling here
249 RAISE_APPLICATION_ERROR
250 (-20001,'Arrays must be the same size.');
251 elsif (p_days_in_year = 0)then
252 RAISE_APPLICATION_ERROR
253 (-20001,'Cannot have 0 days in a year.');
254 -- arrays are same size, p_days_in_year is positive
255 else
256 for i IN 1..p_pvc_array.count
257 LOOP
258 p_num_sum := p_num_sum
259 + p_pvc_array(i)*p_days_array(i)/p_days_in_year;
260 p_denom_sum := p_denom_sum + p_pvc_array(i);
261 END LOOP;
262 -- now divide the numerator and denominator
263 -- this is the value to return
264 RETURN p_num_sum/p_denom_sum;
265 end if;
266
267 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
268 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.DURATION');
269 END IF;
270
271 END duration;
272
273
274 -- addition by fhu 6/13/01
275 /*
276 Calculates MODIFIED DURATION of the following instruments:
277 - bond
278 - discounted securities
279 - interest rate swap
280
281 as specified in: Robert Steiner, Mastering Financial Calculations, p.110
282
283 The arguments are defined as follows:
284 - p_duration = duration of instrument
285 - p_yield = if bond, is yield per annum based on p_num_payments per
286 year (YTM); if discounted security, is yield rate;
287 if interest rate swap, is internal rate of return (IRR)
288 - p_num_payments = number of payments per year; if discounted security,
289 value = 1
290
291 Note: yield rate is assumed to be in percentage form.
292 */
293
294 FUNCTION mod_duration(p_duration IN NUMBER,
295 p_yield IN NUMBER,
296 p_num_payments IN NUMBER)
297 RETURN NUMBER IS
298
299 p_yld number := p_yield/100;
300
301 BEGIN
302
303 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
304 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.MOD_DURATION');
305 END IF;
306
307 if (p_num_payments = 0) then
308 RAISE_APPLICATION_ERROR
312 end if;
309 (-20001,'Cannot have 0 payments per year.');
310 else
311 RETURN p_duration/(1 + p_yld/p_num_payments);
313
314 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
315 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.MOD_DURATION');
316 END IF;
317
318 END mod_duration;
319
320
321 -- addition by fhu 6/13/01
322 /*
323 Calculates BOND CONVEXITY as specified in: Robert Steiner, Mastering Financial Calculations, p.112
324
325 The arguments are defined as follows:
326 - p_cf_array = cashflows stored in xtr_md_num_table; value at index k
327 corresponds to kth cashflow; k = 1,2,3,...
328 - p_days_array = number of days until kth cashflow, stored in
329 xtr_md_num_table; each kth element correspons to kth
330 cashflow; k = 1,2,3,...
331 - p_num_payments = number of payments per year
332 - p_yield = yield per annum based on p_num_payments per year (YTM)
333 - p_days_in_year = number of days in year
334 - p_dirty_price = dirty price of bond
335
336 Note: yield rate is assumed to be in percentage form.
337 */
338
339 FUNCTION bond_convexity(p_cf_array IN XTR_MD_NUM_TABLE,
340 p_days_array IN XTR_MD_NUM_TABLE,
341 p_num_payments IN NUMBER,
342 p_yield IN NUMBER,
343 p_days_in_year IN NUMBER,
344 p_dirty_price IN NUMBER)
345 RETURN NUMBER IS
346
347 p_num_sum NUMBER := 0;
348 p_yld NUMBER := p_yield/100;
349
350 BEGIN
351 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
352 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.BOND_CONVEXITY');
353 END IF;
354 -- arrays should be the same size
355 if (p_cf_array.count <> p_days_array.count) then
356 -- do exception handling here
357 RAISE_APPLICATION_ERROR
358 (-20001,'Arrays must be the same size.');
359 elsif (p_dirty_price = 0) then
360 RAISE_APPLICATION_ERROR
361 (-20001,'Dirty price cannot equal 0.');
362 elsif (p_days_in_year = 0) then
363 RAISE_APPLICATION_ERROR
364 (-20001,'Cannot have 0 days in a year.');
365 else
366 -- calculate numerator
367 FOR i IN 1..p_cf_array.count
368 LOOP
369 p_num_sum := p_num_sum +
370 p_cf_array(i)/(1 + p_yld/p_num_payments)**(p_num_payments*p_days_array(i)/p_days_in_year + 2)*(p_days_array(i)/p_days_in_year)*(p_days_array(i)/p_days_in_year + 1/p_num_payments);
371 --modified from - to + above
372 END LOOP;
373 -- now divide numerator and denominator
374 XTR_RISK_DEBUG_PKG.dlog('convexity before 100: '||p_num_sum/p_dirty_price);
375 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
376 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.BOND_CONVEXITY');
377 END IF;
378 RETURN p_num_sum/p_dirty_price;
379 end if;
380 END bond_convexity;
381
382
383 -- addition by fhu 6/13/01
384 /*
385 Calculates DELTA/DOLLAR DURATION,given modified duration, of the following
386 instruments:
387 - bond
388 - discounted security
389 as specified in: Robert Steiner, Mastering Financial Calculations, p.110
390
391 The arguments are defined as follows:
392 - p_OUT = 'DELTA' if output is to be delta, 'DOLLAR' if value is to be
393 dollar duration
394 - p_dirty_price = dirty price of bond
395 - p_mod_duration = modified duration
396
397 Note: a delta yield of 1% (0.01) is assumed for sensitivities calculations
398 */
399
400
401 FUNCTION delta_md(p_out IN VARCHAR2,
402 p_dirty_price IN NUMBER,
403 p_mod_duration IN NUMBER)
404 RETURN NUMBER IS
405
406 p_delta_yield NUMBER := 0.01;
407 BEGIN
408 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
409 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.DELTA_MD');
410 END IF;
411 if (p_out = 'DELTA') then
412 RETURN -1 * p_dirty_price * p_delta_yield * p_mod_duration;
413 elsif (p_out = 'DOLLAR') then
414 RETURN p_dirty_price * p_delta_yield * p_mod_duration;
415 else
416 RAISE_APPLICATION_ERROR
417 (-20001,'p_OUT must be ''DELTA'' or ''DOLLAR''.');
418 end if;
419 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
420 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.DELTA_MD');
421 END IF;
422 END delta_md;
423
424 -- addition by fhu 6/13/01
425 /*
426 Calculates DELTA/DOLLAR DURATION of a bond, given bond convexity, as specified
427 in: Robert Steiner, Mastering Financial Calculations, p.112
428
429 The arguments are defined as follows:
430 - p_out = 'DELTA' if p_VALUE is to be delta, 'DOLLAR' if is to be
431 dollar duration
432 - p_dirty_price = dirty price of bond
433 - p_mod_duration = modified duration of bond
434 - p_convexity = convexity of bond
435
436 Note: a delta yield of 1% (0.01) is assumed for sensitivities calculations
437 */
438
439 FUNCTION bond_delta_convexity(p_out IN VARCHAR2,
440 p_dirty_price IN NUMBER,
441 p_mod_duration IN NUMBER,
442 p_convexity IN NUMBER)
443 RETURN NUMBER IS
444 p_delta_yield NUMBER := 0.01;
445 BEGIN
446 if (p_out = 'DELTA') then
447 RETURN delta_md('DELTA', p_dirty_price, p_mod_duration) + (p_dirty_price/2)*p_convexity*(p_delta_yield)**2;
448 elsif (p_out = 'DOLLAR') then
449 RETURN -1 * (delta_md('DELTA', p_dirty_price, p_mod_duration) + (p_dirty_price/2)*p_convexity*(p_delta_yield)**2);
450 else
451 RAISE_APPLICATION_ERROR
452 (-20001,'p_OUT must be ''DELTA'' or ''DOLLAR''.');
453 end if;
454 END bond_delta_convexity;
455
456
457 -- addition by fhu 6/13/01
458 /*
459 Calculates BPV(YR), or change in price due to a 1 basis point change in yield
460 rate, of discounted security or bond. See Deal Calculations HLD.
461
465 */
462 The arguments are defined as follows:
463 - p_dirty_price = dirty price of discounted security or bond
464 - p_mod_duration = modified duration of discounted security or bond
466
467 FUNCTION bpv_yr(p_dirty_price IN NUMBER,
468 p_mod_duration IN NUMBER)
469 RETURN NUMBER IS
470 BEGIN
471 RETURN p_dirty_price*(0.0001)*p_mod_duration;
472
473 End bpv_yr;
474
475
476 -- addition by fhu 6/13/01
477 /*
478 Calculates BPV(DR), or change in price due to a 1 basis point change in
479 discount rate, of discounted security. See Deal Calculations HLD.
480
481 The arguments are defined as follows:
482 - p_principle = principle amount or face value
483 - p_days_to_mat = days to maturity
484 - p_days_in_year = days in year
485 */
486
487 FUNCTION ni_bpv_dr(p_principle IN NUMBER,
488 p_days_to_mat IN NUMBER,
489 p_days_in_year IN NUMBER)
490 RETURN NUMBER IS
491 BEGIN
492 if (p_days_in_year = 0) then
493 RAISE_APPLICATION_ERROR
494 (-20001,'Cannot have 0 days in a year.');
495 else
496 RETURN p_principle*(0.0001)*p_days_to_mat/p_days_in_year;
497 end if;
498 END ni_bpv_dr;
499
500
501 -- addition by fhu 6/13/01
502 /*
503 Calculates DELTA/DOLLAR DURATION of discounted security, given BPV(YR) or
504 BPV(DR). See Deal Calculations HLD.
505
506 The arguments are defined as follows:
507 - p_out = 'DELTA' if output is to be delta, 'DOLLAR' if is to be
508 dollar duration
509 - p_bpv = BPV(DR) or BPV(YR)
510 */
511
512 FUNCTION ni_delta_bpv(p_out IN VARCHAR2,
513 p_bpv IN NUMBER)
514 RETURN NUMBER IS
515 BEGIN
516 if (p_out = 'DELTA') then
517 RETURN -1*100*p_bpv;
518 elsif (p_out = 'DOLLAR') then
519 RETURN 100*p_bpv;
520 else
521 RAISE_APPLICATION_ERROR
522 (-20001,'p_OUT must be ''DELTA'' or ''DOLLAR''.');
523 end if;
524 END ni_delta_bpv;
525 --added by sankim 8/8/01
526 /*
527 Calculates NI CONVEXITY or FRA CONVEXITY as specified in: Robert Steiner,
528 Mastering Financial
529 Calculations, p.112
530
531 The arguments are defined as follows:
532 - p_num_days = number of days until cash flow occurs
533 i.e. number of days till maturity for NI or
534 number of days till settlement for FRA
535 - p_rate = yield rate of discounted security or
536 settlement rate of FRA
537 - p_days_in_year = number of days in year
538
539 Note: rate is assumed to be in percentage form.
540 */
541
542 FUNCTION ni_fra_convexity( p_num_days IN NUMBER,
543 p_rate IN NUMBER,
544 p_days_in_year IN NUMBER)
545 RETURN NUMBER IS
546
547 v_n NUMBER;
548 -- variable n as defined in the formula
549 v_rate NUMBER := p_rate/100;
550 v_result NUMBER;
551
552 BEGIN
553
554
555 v_n:= p_days_in_year/p_num_days;
556 v_result:= (1/(1+v_rate/v_n)**2)*(p_num_days/p_days_in_year)*
557 (p_num_days/p_days_in_year+1/v_n);
558 RETURN v_result;
559
560 END ni_fra_convexity;
561
562 -- addition by fhu 6/13/01
563 /*
564 Calcuation of BPV for interest rate swaps (IRS), wholesale term money (TMM),
565 and forward rate agreement(FRA).
566 This call also be used to calculate the BPV of any instrument, given its fair
567 values. See: Deal Calculations HLD, Deal Valuations HLD, FRA Calculator HLD.
568 Arguments defined as follows:
569 - p_fair_value_base = fair value with regular yield curve/rate
570 - p_fair_value_shifted = fair value with yield curve/rate shifted up
571 one basis point
572 */
573
574
575 -- addition by fhu 6/13/01
576 FUNCTION bpv(p_fair_value_base IN NUMBER,
577 p_fair_value_shifted IN NUMBER)
578 RETURN NUMBER IS
579 BEGIN
580 RETURN p_fair_value_shifted - p_fair_value_base;
581 -- flipped shift and base by sankim 8/14/01
582 END bpv;
583
584
585 -- addition by jbrodsky 9/20/01
586 /*
587 Calculation of Implied Volatility using Bisection for Forward Exchange Options.
588
589 */
590
591 FUNCTION calculate_implied_volatility(p_indicator IN VARCHAR2,
592 p_spot_date IN DATE,
593 p_expiration_date IN DATE,
594 p_interest_rates IN XTR_MD_NUM_TABLE,
595 p_day_count_basis IN SYSTEM.QRM_VARCHAR_TABLE,
596 p_rate_type IN SYSTEM.QRM_VARCHAR_TABLE,
597 p_compound_freq IN XTR_MD_NUM_TABLE,
598 p_spot_rate IN NUMBER,
599 p_strike_rate IN NUMBER,
600 p_option_price IN NUMBER,
601 p_option_type IN VARCHAR2,
602 p_start_date IN DATE,
603 p_principal IN NUMBER,
604 p_error_tol IN NUMBER,
605 p_max_iterations IN NUMBER,
606 p_max_value IN NUMBER,
607 p_vol_first_guess IN NUMBER)
608 RETURN NUMBER IS
609
610
611
612 v_vol_low NUMBER := 0.00001;
613 v_vol_mid NUMBER;
614 v_vol_high NUMBER := p_vol_first_guess;
615 v_price NUMBER;
616 v_count NUMBER;
617 v_test NUMBER;
618 fx_option_price_in XTR_FX_FORMULAS.GK_OPTION_CV_IN_REC_TYPE;
619 fx_option_price_out XTR_FX_FORMULAS.GK_OPTION_CV_OUT_REC_TYPE;
620 iro_option_price_in XTR_MM_COVERS.BLACK_OPT_CV_IN_REC_TYPE;
621 iro_option_price_out XTR_MM_COVERS.BLACK_OPT_CV_OUT_REC_TYPE;
622
623 BEGIN
624 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
625 xtr_risk_debug_pkg.dpush(null,'QRM_MM_FORMULAS.CALCULATE_IMPLIED_VOL');
626 END IF;
627 if (p_indicator='FXO') THEN
628 fx_option_price_in.p_SPOT_DATE:= p_spot_date;
629 fx_option_price_in.p_MATURITY_DATE := p_expiration_date;
633 fx_option_price_in.p_DAY_COUNT_BASIS_DOM:=p_day_count_basis(1);
630 fx_option_price_in.p_RATE_DOM:=p_interest_rates(1);
631 fx_option_price_in.p_RATE_TYPE_DOM:=p_rate_type(1);
632 fx_option_price_in.p_COMPOUND_FREQ_DOM:= p_compound_freq(1);
634 fx_option_price_in.p_RATE_FOR:=p_interest_rates(2);
635 fx_option_price_in.p_RATE_TYPE_FOR:=p_rate_type(2);
636 fx_option_price_in.p_COMPOUND_FREQ_FOR:= p_compound_freq(2);
637 fx_option_price_in.p_DAY_COUNT_BASIS_FOR:=p_day_count_basis(2);
638 fx_option_price_in.p_SPOT_RATE:=p_spot_rate;
639 fx_option_price_in.p_STRIKE_RATE:=p_strike_rate;
640 fx_option_price_in.p_VOLATILITY:= v_vol_low;
641
642
643
644
645 XTR_FX_FORMULAS.FX_GK_OPTION_PRICE_CV(fx_option_price_in, fx_option_price_out);
646
647 if (p_option_type='C') THEN
648 v_price:=fx_option_price_out.p_CALL_PRICE;
649 elsif (p_option_type='P') THEN
650 v_price:=fx_option_price_out.p_PUT_PRICE;
651 end if;
652
653 elsif (p_indicator='IRO') THEN
654 iro_option_price_in.p_PRINCIPAL := p_principal;
655 iro_option_price_in.p_STRIKE_RATE := p_interest_rates(1);
656 iro_option_price_in.p_RATE_TYPE_STRIKE := p_rate_type(1);
657 iro_option_price_in.p_COMPOUND_FREQ_STRIKE := p_compound_freq(1);
658 iro_option_price_in.p_DAY_COUNT_BASIS_STRIKE := p_day_count_basis(1);
659 iro_option_price_in.p_IR_SHORT:= p_interest_rates(2);
660 iro_option_price_in.p_RATE_TYPE_SHORT := p_rate_type(2);
661 iro_option_price_in.p_COMPOUND_FREQ_SHORT := p_compound_freq(2);
662 iro_option_price_in.p_DAY_COUNT_BASIS_SHORT := p_day_count_basis(2);
663 iro_option_price_in.p_IR_LONG:= p_interest_rates(3);
664 iro_option_price_in.p_RATE_TYPE_LONG := p_rate_type(3);
665 iro_option_price_in.p_COMPOUND_FREQ_LONG := p_compound_freq(3);
666 iro_option_price_in.p_DAY_COUNT_BASIS_LONG := p_day_count_basis(3);
667 iro_option_price_in.p_SPOT_DATE := p_spot_date;
668 iro_option_price_in.p_START_DATE := p_start_date;
669 iro_option_price_in.p_MATURITY_DATE := p_expiration_date;
670 iro_option_price_in.p_VOLATILITY := v_vol_low;
671 XTR_MM_COVERS.BLACK_OPTION_PRICE_CV(iro_option_price_in, iro_option_price_out);
672
673 if (p_option_type='C') THEN
674 v_price:=iro_option_price_out.p_CAPLET_PRICE;
675 elsif (p_option_type='P') THEN
676 v_price:=iro_option_price_out.p_FLOORLET_PRICE;
677 end if;
678
679 elsif (p_indicator='BS') THEN
680 v_price:=-1;
681 end if;
682
683
684 if (v_price > p_option_price) THEN
685 RETURN 0;
686 end if;
687
688 -- Binomial search
689 if (p_indicator='FXO') THEN
690 fx_option_price_in.p_VOLATILITY:= v_vol_high;
691
692 XTR_FX_FORMULAS.FX_GK_OPTION_PRICE_CV(fx_option_price_in, fx_option_price_out);
693
694 if (p_option_type='C') THEN
695 v_price:=fx_option_price_out.p_CALL_PRICE;
696 elsif (p_option_type='P') THEN
697 v_price:=fx_option_price_out.p_PUT_PRICE;
698 end if;
699
700 elsif (p_indicator='IRO') THEN
701 iro_option_price_in.p_VOLATILITY := v_vol_high;
702 XTR_MM_COVERS.BLACK_OPTION_PRICE_CV(iro_option_price_in, iro_option_price_out);
703
704 if (p_option_type='C') THEN
705 v_price:=iro_option_price_out.p_CAPLET_PRICE;
706 elsif (p_option_type='P') THEN
707 v_price:=iro_option_price_out.p_FLOORLET_PRICE;
708 end if;
709
710 elsif (p_indicator='BS') THEN
711 v_price:=-1;
712 end if;
713
714 WHILE (v_price < p_option_price) LOOP
715 v_vol_high := 2 * v_vol_high;
716
717 if (p_indicator='FXO') THEN
718 fx_option_price_in.p_VOLATILITY:= v_vol_high;
719
720 XTR_FX_FORMULAS.FX_GK_OPTION_PRICE_CV(fx_option_price_in, fx_option_price_out);
721
722 if (p_option_type='C') THEN
723 v_price:=fx_option_price_out.p_CALL_PRICE;
724 elsif (p_option_type='P') THEN
725 v_price:=fx_option_price_out.p_PUT_PRICE;
726 end if;
727
728 elsif (p_indicator='IRO') THEN
729 iro_option_price_in.p_VOLATILITY := v_vol_high;
730 XTR_MM_COVERS.BLACK_OPTION_PRICE_CV(iro_option_price_in, iro_option_price_out);
731
732 if (p_option_type='C') THEN
733 v_price:=iro_option_price_out.p_CAPLET_PRICE;
734 elsif (p_option_type='P') THEN
735 v_price:=iro_option_price_out.p_FLOORLET_PRICE;
736 end if;
737
738 elsif (p_indicator='BS') THEN
739 v_price:=-1;
740 end if;
741 if (v_vol_high > p_max_value) THEN
742 FND_MESSAGE.SET_NAME('QRM','QRM_CALC_EXCEED_VOL_BOUND');
743 raise e_exceed_vol_upper_bound;
744 end if;
745 END LOOP;
746 FOR v_count in 0..p_max_iterations LOOP
747 v_vol_mid := (v_vol_low + v_vol_high)/2;
748 if (p_indicator='FXO') THEN
749 fx_option_price_in.p_VOLATILITY:= v_vol_mid;
750
751 XTR_FX_FORMULAS.FX_GK_OPTION_PRICE_CV(fx_option_price_in, fx_option_price_out);
752
753 if (p_option_type='C') THEN
754 v_price:=fx_option_price_out.p_CALL_PRICE;
755 elsif (p_option_type='P') THEN
756 v_price:=fx_option_price_out.p_PUT_PRICE;
757 end if;
758
759 elsif (p_indicator='IRO') THEN
760 iro_option_price_in.p_VOLATILITY := v_vol_mid;
761 XTR_MM_COVERS.BLACK_OPTION_PRICE_CV(iro_option_price_in, iro_option_price_out);
762
763 if (p_option_type='C') THEN
764 v_price:=iro_option_price_out.p_CAPLET_PRICE;
765 elsif (p_option_type='P') THEN
766 v_price:=iro_option_price_out.p_FLOORLET_PRICE;
767 end if;
768
769 elsif (p_indicator='BS') THEN
770 v_price:=-1;
771 end if;
772 v_test := v_price - p_option_price;
773 if (ABS(v_test) < p_error_tol) THEN
774 RETURN v_vol_mid;
775 end if;
776 if (v_test<0) THEN
777 v_vol_low:=v_vol_mid;
778 else
779 v_vol_high:= v_vol_mid;
780 end if;
784 END IF;
781 END LOOP;
782 IF (g_proc_level>=g_debug_level) THEN --bug 3236479
783 xtr_risk_debug_pkg.dpop(null,'QRM_MM_FORMULAS.CALCULATE_IMPLIED_VOL');
785 END calculate_implied_volatility;
786
787
788 /* Fair Value Calculations -- fhu 12/13/01 */
789
790
791 FUNCTION calculate_fwd_rate( p_set_code VARCHAR2,
792 -- enter 'Y' add 1BP to underlying rates
793 p_bpv VARCHAR2, -- 'Y' or 'N'
794 p_deal_subtype VARCHAR2,
795 p_day_count_basis VARCHAR2,
796 p_ccy VARCHAR2,
797 p_interpolation_method VARCHAR2,
798 p_spot_date DATE,
799 p_start_date DATE,
800 p_maturity_date DATE)
801 RETURN NUMBER IS
802
803 p_side VARCHAR2(5);
804 p_days1 NUMBER;
805 p_annual_basis NUMBER;
806 p_days2 NUMBER;
807 p_rate1 NUMBER;
808 p_rate2 NUMBER;
809 p_fwd_rate NUMBER;
810 p_md_in XTR_MARKET_DATA_P.md_from_set_in_rec_type;
811 p_md_out XTR_MARKET_DATA_P.md_from_set_out_rec_type;
812 p_mm_in XTR_MM_COVERS.int_forw_rate_in_rec_type;
813 p_mm_out XTR_MM_COVERS.int_forw_rate_out_rec_type;
814
815
816 BEGIN
817 IF (g_proc_level>=g_debug_level) THEN
818 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.calculate_fwd_rate');
819 END IF;
820 if p_deal_subtype in ('BUY', 'FUND', 'BCAP', 'SCAP') then
821 p_side := 'A';
822 else
823 p_side := 'B';
824 end if;
825
826
827 -- get yield rate from spot to start date
828 IF (g_proc_level>=g_debug_level) THEN
829 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'spot date: '||p_spot_date);
830 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'start date: '||p_start_date);
831 END IF;
832 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
833 p_day_count_basis, null, p_days1, p_annual_basis);
834 p_md_in.p_md_set_code := p_set_code;
835 p_md_in.p_source := 'C';
836 p_md_in.p_indicator := 'Y';
837 p_md_in.p_spot_date := p_spot_date;
838 p_md_in.p_future_date := p_start_date;
839 p_md_in.p_ccy := p_ccy;
840 p_md_in.p_contra_ccy := NULL;
841 p_md_in.p_day_count_basis_out := p_day_count_basis;
842 p_md_in.p_interpolation_method := p_interpolation_method;
843 p_md_in.p_side := p_side;
844 p_md_in.p_batch_id := NULL;
845 p_md_in.p_bond_code := NULL;
846 IF (g_proc_level>=g_debug_level) THEN
847 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'deal subtype: '||p_deal_subtype);
848 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'set_code: '||p_set_code);
849 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'spot date: '||p_spot_date);
850 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'future date: '||p_start_date);
851 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'ccy: '||p_ccy);
852 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'day count basis: '||p_day_count_basis);
853 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'interp method: '||p_interpolation_method);
854 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'data side: '||p_side);
855 END IF;
856
857 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
858 p_rate1 := p_md_out.p_md_out;
859
860 IF (p_bpv = 'Y') THEN -- fwd rate used in bpv calculation, so add 1 BP
861 p_rate1 := p_rate1 + 0.01;
862 END IF;
863
864 -- get yield rate from spot to maturity date
865 IF (g_proc_level>=g_debug_level) THEN
866 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'spot date: '||p_spot_date);
867 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'maturity date: '||p_maturity_date);
868 END IF;
869 XTR_CALC_P.calc_days_run_c(p_spot_date, p_maturity_date,
870 p_day_count_basis, null, p_days2, p_annual_basis);
871 p_md_in.p_md_set_code := p_set_code;
872 p_md_in.p_source := 'C';
873 p_md_in.p_indicator := 'Y';
874 p_md_in.p_spot_date := p_spot_date;
875 p_md_in.p_future_date := p_maturity_date;
876 p_md_in.p_ccy := p_ccy;
877 p_md_in.p_contra_ccy := NULL;
878 p_md_in.p_day_count_basis_out := p_day_count_basis;
879 p_md_in.p_interpolation_method := p_interpolation_method;
880 p_md_in.p_side := p_side;
881 p_md_in.p_batch_id := NULL;
882 p_md_in.p_bond_code := NULL;
883 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
884 p_rate2 := p_md_out.p_md_out;
885
886 IF (p_bpv = 'Y') THEN -- fwd rate used in bpv calculation, so add 1 BP
887 p_rate2 := p_rate2 + 0.01;
888 END IF;
889
890 -- calculate fwd rate
891 IF p_days1 = p_days2 THEN
892 p_fwd_rate := 0;
893 ELSE
894 IF (g_proc_level>=g_debug_level) THEN
895 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'calc fwd rate days 1: '||p_days1);
896 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'calc fwd rate days 2: '||p_days2);
897 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'calc fwd rate rate 1: '||p_rate1);
898 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'calc fwd rate rate 2: '||p_rate2);
899 XTR_RISK_DEBUG_PKG.dlog('calculate_fwd_rate: ' || 'calc fwd rate annual basis: '||p_annual_basis);
900 END IF;
901
902 p_mm_in.p_indicator := 'Y';
903 p_mm_in.p_t := p_days1;
904 p_mm_in.p_T1 := p_days2;
905 p_mm_in.p_Rt := p_rate1;
906 p_mm_in.p_Rt1 := p_rate2;
907 p_mm_in.p_year_basis:= p_annual_basis;
908 XTR_MM_COVERS.interest_forward_rate(p_mm_in, p_mm_out);
909 p_fwd_rate := p_mm_out.p_fra_rate;
910 END IF;
911
912 IF (g_proc_level>=g_debug_level) THEN
913 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.calculate_fwd_rate');
914 END IF;
915 RETURN p_fwd_rate;
916
917
918 END calculate_fwd_rate;
922 RETURN BOOLEAN IS
919
920
921 FUNCTION within_one_year(p_start_date DATE, p_end_date DATE)
923
924 BEGIN
925 IF (ADD_MONTHS(p_start_date, 12) >= p_end_date) THEN
926 RETURN true;
927 ELSE
928 RETURN false;
929 END IF;
930 END within_one_year;
931
932
933 PROCEDURE fv_fra(p_price_model IN VARCHAR2,
934 p_set_code IN VARCHAR2,
935 p_bpv IN VARCHAR2, -- 'Y' or 'N'
936 p_deal_subtype IN VARCHAR2,
937 p_ccy IN VARCHAR2,
938 p_interpolation_method IN VARCHAR2,
939 p_spot_date IN DATE,
940 p_start_date IN DATE,
941 p_maturity_date IN DATE,
942 p_face_value IN NUMBER,
943 p_contract_rate IN NUMBER,
944 p_day_count_basis IN VARCHAR2, -- for contract rate
945 p_side IN OUT NOCOPY VARCHAR2,
946 -- settle rate
947 p_fwd_fwd_rate IN OUT NOCOPY NUMBER,
948 p_fair_value IN OUT NOCOPY NUMBER) IS
949
950 p_fra_dis_price_model VARCHAR2(30) := 'FRA_DISC';
951 p_fra_yld_price_model VARCHAR2(30) := 'FRA_YIELD';
952
953 p_fwd_fwd_day_count_basis VARCHAR2(15) := 'ACTUAL365';
954
955 p_days NUMBER;
956 p_annual_basis NUMBER;
957 p_settle_amount NUMBER;
958 p_discount_rate NUMBER;
959
960 p_md_in xtr_market_data_p.md_from_set_in_rec_type;
961 p_md_out xtr_market_data_p.md_from_set_out_rec_type;
962 p_fra_in XTR_MM_COVERS.fra_settlement_in_rec_type;
963 p_fra_out XTR_MM_COVERS.fra_settlement_out_rec_type;
964 p_mm_in XTR_MM_COVERS.presentValue_in_rec_type;
965 p_mm_out XTR_MM_COVERS.presentValue_out_rec_type;
966 p_conv_in XTR_RATE_CONVERSION.rate_conv_in_rec_type;
967 p_conv_out XTR_RATE_CONVERSION.rate_conv_out_rec_type;
968
969 BEGIN
970 IF (g_proc_level>=g_debug_level) THEN
971 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_fra');
972 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'contract rate day count basis: '||p_day_count_basis);
973 END IF;
974
975 IF (p_price_model = p_fra_dis_price_model OR
976 p_price_model = p_fra_yld_price_model) THEN
977 -- fwd fwd rate is calculated fra price/settle rate
978 -- for FRA calc of BPV, add 1 BP to resulting fwd fwd rate
979 -- no need to add 1BP to underlying rates
980 p_fwd_fwd_rate := calculate_fwd_rate(p_set_code, 'N', p_deal_subtype,
981 p_day_count_basis, p_ccy,
982 p_interpolation_method, p_spot_date,
983 p_start_date, p_maturity_date);
984
985 IF (p_bpv='Y') THEN
986 p_fwd_fwd_rate := p_fwd_fwd_rate + 0.01;
987 END IF;
988
989 IF (g_proc_level>=g_debug_level) THEN
990 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'settle/reval rate is: '||p_fwd_fwd_rate);
991 END IF;
992
993 IF (p_deal_subtype = 'FUND') THEN
994 p_side := 'A';
995 ELSE
996 p_side := 'B';
997 END IF;
998
999 XTR_CALC_P.calc_days_run_c(p_start_date, p_maturity_date,
1000 p_day_count_basis, null, p_days, p_annual_basis);
1001
1002 -- get settlement amount
1003 IF(p_price_model = p_fra_dis_price_model) then -- 'FRA_DISC'
1004 p_fra_in.p_indicator := 'DR';
1005 ELSIF (p_price_model = p_fra_yld_price_model) then -- 'FRA_YIELD'
1006 p_fra_in.p_indicator := 'Y';
1007 ELSE
1008 p_fair_value := null;
1009 END IF;
1010
1011
1012 IF (g_proc_level>=g_debug_level) THEN
1013 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'contract rate: '||p_contract_rate);
1014 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'fwd fwd rate: '||p_fwd_fwd_rate);
1015 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'face value: '||p_face_value);
1016 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'days to mat: '||p_days);
1017 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'annual basis: '||p_annual_basis);
1018 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'deal subtype: '||p_deal_subtype);
1019 END IF;
1020 p_fra_in.p_fra_price := p_contract_rate; -- contract rate
1021 p_fra_in.p_settlement_rate := p_fwd_fwd_rate;
1022 p_fra_in.p_face_value := p_face_value;
1023 p_fra_in.p_day_count := p_days;
1024 p_fra_in.p_annual_basis := p_annual_basis;
1025 p_fra_in.p_deal_subtype := p_deal_subtype;
1026 XTR_MM_COVERS.fra_settlement_amount(p_fra_in, p_fra_out);
1027 -- settlement amount is fair value
1028 p_settle_amount := p_fra_out.p_settlement_amount;
1029 IF (g_proc_level>=g_debug_level) THEN
1030 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'settlement amount is: '||p_settle_amount);
1031 END IF;
1032
1033 -- discount to spot date
1034 IF (p_deal_subtype = 'FUND') THEN
1035 IF (p_settle_amount < 0) THEN
1036 p_side := 'A';
1037 ELSE
1038 p_side := 'B';
1039 END IF;
1040 ELSE -- deal_subtype = 'INVEST'
1041 IF (p_settle_amount >= 0) THEN
1042 p_side := 'A';
1043 ELSE
1044 p_side := 'B';
1045 END IF;
1046 END IF;
1047
1048 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
1049 p_day_count_basis, null, p_days, p_annual_basis);
1050
1051 p_md_in.p_md_set_code := p_set_code;
1052 p_md_in.p_source := 'C';
1053 p_md_in.p_indicator := 'Y';
1054 p_md_in.p_spot_date := p_spot_date;
1055 p_md_in.p_future_date := p_start_date;
1056 p_md_in.p_ccy := p_ccy;
1057 p_md_in.p_day_count_basis_out := p_day_count_basis;
1058 p_md_in.p_interpolation_method := p_interpolation_method;
1059 p_md_in.p_side := p_side;
1060 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1061 p_discount_rate := p_md_out.p_md_out;
1062 IF (g_proc_level>=g_debug_level) THEN
1063 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'discount rate: '||p_discount_rate);
1064 END IF;
1065
1066 p_mm_in.p_indicator := 'Y';
1067 p_mm_in.p_future_val := p_settle_amount;
1068 p_mm_in.p_rate := p_discount_rate;
1069 p_mm_in.p_pv_date := p_spot_date;
1073 p_mm_in.p_rate_type := 'S';
1070 p_mm_in.p_fv_date := p_start_date;
1071 p_mm_in.p_day_count_basis := p_day_count_basis;
1072 IF within_one_year(p_spot_date, p_start_date) THEN
1074 ELSE
1075 p_mm_in.p_rate_type := 'P';
1076 p_mm_in.p_compound_freq := 1;
1077 END IF;
1078
1079 IF (g_proc_level>=g_debug_level) THEN
1080 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'fra fv before discounting: '||p_settle_amount);
1081 END IF;
1082
1083 XTR_MM_COVERS.present_value(p_mm_in, p_mm_out);
1084 p_fair_value := p_mm_out.p_present_val;
1085
1086 IF (g_proc_level>=g_debug_level) THEN
1087 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'fra fv after discounting: '||p_fair_value);
1088 END IF;
1089
1090
1091 -- convert fwd fwd rate into ACTUAL365
1092 -- fwd fwd rate is interest rate
1093 IF (g_proc_level>=g_debug_level) THEN
1094 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'fwd fwd rate bf conv to actual365: '||p_fwd_fwd_rate);
1095 END IF;
1096 IF (p_day_count_basis <> p_fwd_fwd_day_count_basis) THEN
1097 p_conv_in.p_start_date := p_start_date;
1098 p_conv_in.p_end_date := p_maturity_date;
1099 p_conv_in.p_day_count_basis_in := p_day_count_basis;
1100 p_conv_in.p_day_count_basis_out := p_fwd_fwd_day_count_basis;
1101 IF (within_one_year(p_start_date, p_maturity_date)) THEN
1102 p_conv_in.p_rate_type_in := 'S';
1103 p_conv_in.p_rate_type_out := 'S';
1104 ELSE
1105 p_conv_in.p_rate_type_in := 'P';
1106 p_conv_in.p_rate_type_out := 'P';
1107 p_conv_in.p_compound_freq_in := 1;
1108 p_conv_in.p_compound_freq_out := 1;
1109 END IF;
1110 p_conv_in.p_rate_in := p_fwd_fwd_rate;
1111 XTR_RATE_CONVERSION.rate_conversion(p_conv_in, p_conv_out);
1112 p_fwd_fwd_rate := p_conv_out.p_rate_out;
1113 IF (g_proc_level>=g_debug_level) THEN
1114 XTR_RISK_DEBUG_PKG.dlog('fv_fra: ' || 'fwd fwd rate after conv to actual365: '||p_fwd_fwd_rate);
1115 END IF;
1116 END IF;
1117
1118 END IF;
1119 IF (g_proc_level>=g_debug_level) THEN
1120 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_fra');
1121 END IF;
1122 END fv_fra;
1123
1124
1125 PROCEDURE fv_iro(p_price_model IN VARCHAR2,
1126 p_set_code IN VARCHAR2,
1127 p_deal_subtype IN VARCHAR2,
1128 p_ccy IN VARCHAR2,
1129 p_interpolation_method IN VARCHAR2,
1130 p_spot_date IN DATE,
1131 p_start_date IN DATE,
1132 p_maturity_date IN DATE,
1133 p_strike IN NUMBER,
1134 p_day_count_basis_strike IN VARCHAR2, -- for strike rate
1135 p_amount IN NUMBER,
1136 p_side IN OUT NOCOPY VARCHAR2,
1137 p_fwd_fwd_rate IN OUT NOCOPY NUMBER,
1138 p_fair_value IN OUT NOCOPY NUMBER) IS
1139
1140 p_strike_rate NUMBER := p_strike;
1141 p_fwd_fwd_day_count_basis VARCHAR2(15) := 'ACTUAL365';
1142 p_day_count_basis VARCHAR2(15) := 'ACTUAL365'; -- bug 3611158
1143
1144 p_md_in xtr_market_data_p.md_from_set_in_rec_type;
1145 p_md_out xtr_market_data_p.md_from_set_out_rec_type;
1146
1147 p_black_in XTR_MM_COVERS.black_opt_cv_in_rec_type;
1148 p_black_out XTR_MM_COVERS.black_opt_cv_out_rec_type;
1149 p_conv_in XTR_RATE_CONVERSION.rate_conv_in_rec_type;
1150 p_conv_out XTR_RATE_CONVERSION.rate_conv_out_rec_type;
1151
1152 p_days1 NUMBER;
1153 p_days2 NUMBER;
1154 p_annual_basis1 NUMBER;
1155 p_annual_basis2 NUMBER;
1156 p_volatility NUMBER;
1157 p_short_rate NUMBER;
1158 p_long_rate NUMBER;
1159
1160 BEGIN
1161 IF (g_proc_level>=g_debug_level) THEN
1162 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_iro');
1163 END IF;
1164 IF (p_price_model = 'BLACK') THEN
1165 -- convert strike rate to Actual/365
1166 IF (p_day_count_basis_strike <> p_day_count_basis) THEN
1167 p_conv_in.p_start_date := p_start_date;
1168 p_conv_in.p_end_date := p_maturity_date;
1169 p_conv_in.p_day_count_basis_in := p_day_count_basis_strike;
1170 p_conv_in.p_day_count_basis_out := p_day_count_basis;
1171 IF (within_one_year(p_start_date, p_maturity_date)) THEN
1172 p_conv_in.p_rate_type_in := 'S';
1173 p_conv_in.p_rate_type_out := 'S';
1174 ELSE
1175 p_conv_in.p_rate_type_in := 'P';
1176 p_conv_in.p_rate_type_out := 'P';
1177 p_conv_in.p_compound_freq_in := 1;
1178 p_conv_in.p_compound_freq_out := 1;
1179 END IF;
1180 p_conv_in.p_rate_in := p_strike_rate;
1181 XTR_RATE_CONVERSION.rate_conversion(p_conv_in, p_conv_out);
1182 p_strike_rate := p_conv_out.p_rate_out;
1183 END IF;
1184 IF (g_proc_level>=g_debug_level) THEN
1185 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'final strike rate: '||p_strike_rate);
1186 END IF;
1187
1188 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
1189 p_day_count_basis, null, p_days1, p_annual_basis1);
1190 IF (g_proc_level>=g_debug_level) THEN
1191 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'spot to start date: '||p_days1);
1192 END IF;
1193 XTR_CALC_P.calc_days_run_c(p_spot_date, p_maturity_date,
1194 p_day_count_basis, null, p_days2, p_annual_basis2);
1195 IF (g_proc_level>=g_debug_level) THEN
1196 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'spot to maturity date: '||p_days2);
1197 END IF;
1198
1199 -- get volatility from MDS
1200 -- set up data side
1201 IF p_deal_subtype in ('BCAP', 'BFLOOR') THEN
1202 p_side := 'A';
1203 ELSE
1204 p_side := 'B';
1205 END IF;
1206 p_md_in.p_md_set_code := p_set_code;
1207 p_md_in.p_source := 'C';
1208 p_md_in.p_indicator := 'V';
1209 p_md_in.p_spot_date := p_spot_date;
1210 p_md_in.p_future_date := p_maturity_date;
1211 p_md_in.p_ccy := p_ccy;
1212 p_md_in.p_contra_ccy := null;
1216 p_md_in.p_batch_id := null;
1213 p_md_in.p_day_count_basis_out := p_day_count_basis;
1214 p_md_in.p_interpolation_method := p_interpolation_method;
1215 p_md_in.p_side := p_side;
1217 p_md_in.p_bond_code := null;
1218 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1219 p_volatility := p_md_out.p_md_out;
1220 IF (p_volatility = 0) THEN
1221 raise e_option_vol_zero;
1222 END IF;
1223
1224 IF (g_proc_level>=g_debug_level) THEN
1225 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'volatility is: '||p_volatility);
1226 END IF;
1227
1228 -- get int rates
1229 -- set up data side
1230 IF p_deal_subtype in ('BCAP', 'SCAP') THEN
1231 p_side := 'A';
1232 ELSE
1233 p_side := 'B';
1234 END IF;
1235
1236 -- get int rate between spot date and maturity date
1237 p_md_in.p_indicator := 'Y';
1238 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1239 p_long_rate := p_md_out.p_md_out;
1240 IF (g_proc_level>=g_debug_level) THEN
1241 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'rate between spot and maturity date: '||p_long_rate);
1242 END IF;
1243
1244 -- get int rate between spot date and start date
1245 p_md_in.p_future_date := p_start_date;
1246 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1247 p_short_rate := p_md_out.p_md_out;
1248 IF (g_proc_level>=g_debug_level) THEN
1249 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'rate between spot and start date: '||p_short_rate);
1250 END IF;
1251
1252 -- calculate price using Black's formula
1253 p_black_in.p_principal := p_amount;
1254 IF (g_proc_level>=g_debug_level) THEN
1255 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_principal: '||p_amount);
1256 END IF;
1257 p_black_in.p_strike_rate := p_strike_rate;
1258 IF (within_one_year(p_start_date, p_maturity_date)) THEN
1259 IF (g_proc_level>=g_debug_level) THEN
1260 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'strike rate within one year: ' ||p_strike_rate);
1261 END IF;
1262 p_black_in.p_rate_type_strike := 'S';
1263 ELSE
1264 IF (g_proc_level>=g_debug_level) THEN
1265 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'strike rate greater than one year: '||p_strike_rate);
1266 END IF;
1267 p_black_in.p_rate_type_strike := 'P';
1268 p_black_in.p_compound_freq_strike := 1;
1269 END IF;
1270 IF (g_proc_level>=g_debug_level) THEN
1271 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_rate_type_strike: '||p_black_in.p_rate_type_strike);
1272 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_compound_freq_strike: '||p_black_in.p_compound_freq_strike);
1273 END IF;
1274
1275 p_black_in.p_day_count_basis_strike := p_day_count_basis;
1276 p_black_in.p_day_count_basis_short := p_day_count_basis;
1277 p_black_in.p_day_count_basis_long := p_day_count_basis;
1278 IF (g_proc_level>=g_debug_level) THEN
1279 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_day_count_basis_strike: '||p_day_count_basis);
1280 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_day_count_basis_short: '||p_day_count_basis);
1281 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_day_count_basis_long: '||p_day_count_basis);
1282 END IF;
1283 p_black_in.p_ir_short := p_short_rate;
1284 IF (within_one_year(p_spot_date, p_start_date)) THEN
1285 IF (g_proc_level>=g_debug_level) THEN
1286 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'short rate within one year: '||p_short_rate);
1287 END IF;
1288 p_black_in.p_rate_type_short := 'S';
1289 ELSE
1290 IF (g_proc_level>=g_debug_level) THEN
1291 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'short rate greater than one year: '||p_short_rate);
1292 END IF;
1293 p_black_in.p_rate_type_short := 'P';
1294 p_black_in.p_compound_freq_short := 1;
1295 END IF;
1296 IF (g_proc_level>=g_debug_level) THEN
1297 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_rate_type_short: '||p_black_in.p_rate_type_short);
1298 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_compound_freq_short: '||p_black_in.p_compound_freq_short);
1299 END IF;
1300 p_black_in.p_ir_long := p_long_rate;
1301 IF (within_one_year(p_spot_date, p_maturity_date)) THEN
1302 IF (g_proc_level>=g_debug_level) THEN
1303 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'long rate within one year: '||p_long_rate);
1304 END IF;
1305 p_black_in.p_rate_type_long := 'S';
1306 ELSE
1307 IF (g_proc_level>=g_debug_level) THEN
1308 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'long rate greater than one year: '||p_long_rate);
1309 END IF;
1310 p_black_in.p_rate_type_long := 'P';
1311 p_black_in.p_compound_freq_long := 1;
1312 END IF;
1313 IF (g_proc_level>=g_debug_level) THEN
1314 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_rate_type_long: '||p_black_in.p_rate_type_long);
1315 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'p_compound_freq_long: '||p_black_in.p_compound_freq_long);
1316 END IF;
1317 p_black_in.p_spot_date := p_spot_date;
1318 p_black_in.p_start_date := p_start_date;
1319 p_black_in.p_maturity_date := p_maturity_date;
1320 p_black_in.p_volatility := p_volatility;
1321 IF (g_proc_level>=g_debug_level) THEN
1322 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'spot date: '||p_spot_date);
1323 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'start date: '||p_start_date);
1324 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'maturity date: '||p_maturity_date);
1325 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'volatility: '||p_volatility);
1326 END IF;
1327 XTR_MM_COVERS.black_option_price_cv(p_black_in, p_black_out);
1328
1329 -- forward forward rate
1330 p_fwd_fwd_rate := p_black_out.p_forward_forward_rate;
1331 IF (g_proc_level>=g_debug_level) THEN
1332 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'fwd fwd rate is: '||p_fwd_fwd_rate);
1333 END IF;
1334
1335 -- convert fwd fwd rate into ACTUAL365
1336 -- fwd fwd rate is interest rate
1337 IF (g_proc_level>=g_debug_level) THEN
1338 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'fwd fwd rate bf conv to actual365: '||p_fwd_fwd_rate);
1342 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'in day count basis: '||p_day_count_basis);
1339 END IF;
1340 IF (p_day_count_basis <> p_fwd_fwd_day_count_basis) THEN
1341 IF (g_proc_level>=g_debug_level) THEN
1343 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'fwd fwd day count basis: '||p_fwd_fwd_day_count_basis);
1344 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'rate in: '||p_fwd_fwd_rate);
1345 END IF;
1346 p_conv_in.p_start_date := p_start_date;
1347 p_conv_in.p_end_date := p_maturity_date;
1348 p_conv_in.p_day_count_basis_in := p_day_count_basis;
1349 p_conv_in.p_day_count_basis_out := p_fwd_fwd_day_count_basis;
1350 IF (within_one_year(p_start_date, p_maturity_date)) THEN
1351 p_conv_in.p_rate_type_in := 'S';
1352 p_conv_in.p_rate_type_out := 'S';
1353 ELSE
1354 p_conv_in.p_rate_type_in := 'P';
1355 p_conv_in.p_rate_type_out := 'P';
1356 p_conv_in.p_compound_freq_in := 1;
1357 p_conv_in.p_compound_freq_out := 1;
1358 END IF;
1359 p_conv_in.p_rate_in := p_fwd_fwd_rate;
1360 XTR_RATE_CONVERSION.rate_conversion(p_conv_in, p_conv_out);
1361 p_fwd_fwd_rate := p_conv_out.p_rate_out;
1362 IF (g_proc_level>=g_debug_level) THEN
1363 XTR_RISK_DEBUG_PKG.dlog('fv_iro: ' || 'fwd fwd rate after conv to actual365: '||p_fwd_fwd_rate);
1364 END IF;
1365 END IF;
1366
1367 -- fair value
1368 IF p_deal_subtype in ('BCAP', 'SCAP') THEN
1369 p_fair_value := p_black_out.p_caplet_price;
1370 ELSE
1371 p_fair_value := p_black_out.p_floorlet_price;
1372 END IF;
1373
1374 IF p_deal_subtype in ('SCAP', 'SFLOOR') THEN
1375 p_fair_value := p_fair_value * (-1);
1376 END IF;
1377 END IF;
1378 IF (g_proc_level>=g_debug_level) THEN
1379 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_iro');
1380 END IF;
1381 END fv_iro;
1382
1383
1384
1385 PROCEDURE fv_ni(p_price_model IN VARCHAR2,
1386 p_set_code IN VARCHAR2,
1387 p_deal_subtype IN VARCHAR2,
1388 p_discount_basis IN VARCHAR2, --'Y' or 'N'
1389 p_ccy IN VARCHAR2,
1390 p_interpolation_method IN VARCHAR2,
1391 p_day_count_basis IN VARCHAR2, -- for reval rate
1392 p_spot_date IN DATE,
1393 p_start_date IN DATE,
1394 p_maturity_date IN DATE,
1395 p_face_value IN NUMBER,
1396 p_margin IN NUMBER,
1397 p_side IN OUT NOCOPY VARCHAR2,
1398 p_reval_rate IN OUT NOCOPY NUMBER,
1399 p_fair_value IN OUT NOCOPY NUMBER) IS
1400
1401 p_reval_day_count_basis VARCHAR2(15) := 'ACTUAL365';
1402
1403 p_int_rate NUMBER;
1404 p_days NUMBER;
1405 p_annual_basis NUMBER;
1406
1407 -- for holding the later of spot date and start date
1408 p_date DATE;
1409 p_days_start NUMBER;
1410 p_days_mature NUMBER;
1411 p_int_start NUMBER;
1412 p_int_mature NUMBER;
1413 p_rate_type VARCHAR2(1);
1414
1415 p_md_in xtr_market_data_p.md_from_set_in_rec_type;
1416 p_md_out xtr_market_data_p.md_from_set_out_rec_type;
1417 p_present_in XTR_MM_COVERS.presentValue_in_rec_type;
1418 p_present_out XTR_MM_COVERS.presentValue_out_rec_type;
1419 p_conv_in XTR_RATE_CONVERSION.rate_conv_in_rec_type;
1420 p_conv_out XTR_RATE_CONVERSION.rate_conv_out_rec_type;
1421 p_if_in XTR_MM_COVERS.int_forw_rate_in_rec_type;
1422 p_if_out XTR_MM_COVERS.int_forw_rate_out_rec_type;
1423
1424 BEGIN
1425 IF (g_proc_level>=g_debug_level) THEN
1426 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_ni');
1427 END IF;
1428 IF (p_price_model = 'DISC_METHOD') THEN
1429 -- get market data side
1430 -- only calculate BUY, SHORT, and ISSUE b/c COVER/SELL updates original
1431 -- transaction
1432 IF (p_deal_subtype = 'BUY') THEN
1433 p_side := 'B';
1434 ELSIF (p_deal_subtype IN ('SHORT', 'ISSUE')) THEN
1435 p_side := 'A';
1436 END IF;
1437
1438
1439 IF (p_spot_date >= p_start_date) THEN
1440 p_date := p_spot_date;
1441 p_rate_type := 'Y';
1442 ELSE
1443 p_date := p_start_date;
1444 p_rate_type := 'F';
1445 END IF;
1446
1447 -- get interest yield rate from market data set
1448 p_md_in.p_md_set_code := p_set_code;
1449 p_md_in.p_source := 'C';
1450 p_md_in.p_indicator := 'Y';
1451 p_md_in.p_ccy := p_ccy;
1452 p_md_in.p_contra_ccy := NULL;
1453 p_md_in.p_day_count_basis_out := p_day_count_basis;
1454 p_md_in.p_interpolation_method := p_interpolation_method;
1455 p_md_in.p_side := p_side;
1456 p_md_in.p_batch_id := NULL;
1457 p_md_in.p_bond_code := NULL;
1458
1459 IF (p_rate_type = 'Y') THEN
1460 p_md_in.p_spot_date := p_date;
1461 p_md_in.p_future_date := p_maturity_date;
1462 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1463 p_int_rate := p_md_out.p_md_out;
1464 ELSIF (p_rate_type = 'F') THEN
1465 -- get days to start, and int rate from spot to start
1466 p_md_in.p_spot_date := p_spot_date;
1467 p_md_in.p_future_date := p_start_date;
1468 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1469 p_int_start := p_md_out.p_md_out;
1470 IF (g_proc_level>=g_debug_level) THEN
1471 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'int rate to start: '||p_int_start);
1472 END IF;
1473 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
1474 p_day_count_basis, null, p_days_start, p_annual_basis);
1475 IF (g_proc_level>=g_debug_level) THEN
1476 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'days to start: '||p_days_start);
1477 END IF;
1478 -- get days to maturity, and int rate from spot to maturity
1479 p_md_in.p_future_date := p_maturity_date;
1480 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1481 p_int_mature := p_md_out.p_md_out;
1482 IF (g_proc_level>=g_debug_level) THEN
1486 p_day_count_basis, null, p_days_mature, p_annual_basis);
1483 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'int rate to maturity: '||p_int_mature);
1484 END IF;
1485 XTR_CALC_P.calc_days_run_c(p_spot_date, p_maturity_date,
1487 IF (g_proc_level>=g_debug_level) THEN
1488 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'days to maturity: '||p_days_mature);
1489 END IF;
1490 -- get interest forward rate
1491 p_if_in.p_indicator := 'Y';
1492 p_if_in.p_t := p_days_start;
1493 p_if_in.p_t1 := p_days_mature;
1494 p_if_in.p_rt := p_int_start;
1495 p_if_in.p_rt1 := p_int_mature;
1496 p_if_in.p_year_basis := p_annual_basis;
1497 XTR_MM_COVERS.interest_forward_rate(p_if_in, p_if_out);
1498 p_int_rate := p_if_out.p_fra_rate;
1499 END IF;
1500
1501 IF (g_proc_level>=g_debug_level) THEN
1502 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || '(forward) int rate: '||p_int_rate);
1503 END IF;
1504
1505 -- if basis is DISCOUNT, convert yield rate to discount rate
1506 XTR_CALC_P.calc_days_run_c(p_date, p_maturity_date,
1507 p_day_count_basis, null, p_days, p_annual_basis);
1508 IF (p_discount_basis = 'Y') THEN
1509 XTR_RATE_CONVERSION.yield_to_discount_rate(p_int_rate,
1510 p_days, p_annual_basis, p_int_rate);
1511 IF (g_proc_level>=g_debug_level) THEN
1512 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'int rate w/o margin: '||p_int_rate);
1513 END IF;
1514 END IF;
1515
1516 -- add margin on top of yield/discount rate
1517 p_reval_rate := p_int_rate + NVL(p_margin, 0)/100;
1518
1519 IF (g_proc_level>=g_debug_level) THEN
1520 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'reval rate with margin: '||p_reval_rate);
1521 END IF;
1522 -- if basis is DISCOUNT, convert back to yield rate
1523 IF (p_discount_basis = 'Y') THEN -- 'Y' for yes
1524 -- reval rate now is yield rate
1525 XTR_RATE_CONVERSION.discount_to_yield_rate(p_reval_rate,
1526 p_days, p_annual_basis, p_reval_rate);
1527 END IF;
1528
1529 -- calculate present value using yield reval rate
1530 p_present_in.p_indicator := 'Y';
1531 --bug 3058003
1532 if nvl(p_deal_subtype,'BUY')='ISSUE' then
1533 p_present_in.p_future_val := -p_face_value;
1534 else
1535 p_present_in.p_future_val := p_face_value;
1536 end if;
1537 p_present_in.p_rate := p_reval_rate;
1538 p_present_in.p_pv_date := p_date;
1539 p_present_in.p_fv_date := p_maturity_date;
1540 p_present_in.p_day_count_basis := p_day_count_basis;
1541 IF (within_one_year(p_date, p_maturity_date)) THEN
1542 p_present_in.p_rate_type := 'S';
1543 ELSE
1544 p_present_in.p_rate_type := 'P';
1545 p_present_in.p_compound_freq := 1;
1546 END IF;
1547
1548 XTR_MM_COVERS.present_value(p_present_in, p_present_out);
1549 p_fair_value := p_present_out.p_present_val;
1550
1551 -- now present value to spot date
1552 -- this is only necessary if spot date < start date
1553 -- and so the previously calculate fair value is discounted to
1554 -- start date only
1555 IF (p_spot_date < p_start_date) THEN
1556 p_md_in.p_indicator := 'Y';
1557 p_md_in.p_spot_date := p_spot_date;
1558 p_md_in.p_future_date := p_start_date;
1559 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1560 p_int_rate := p_md_out.p_md_out;
1561
1562 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
1563 p_day_count_basis, null, p_days, p_annual_basis);
1564 p_present_in.p_indicator := 'Y';
1565 p_present_in.p_future_val := p_fair_value;
1566 p_present_in.p_rate := p_int_rate;
1567 p_present_in.p_pv_date := p_spot_date;
1568 p_present_in.p_fv_date := p_start_date;
1569 p_present_in.p_day_count_basis := p_day_count_basis;
1570 IF (within_one_year(p_spot_date, p_start_date)) THEN
1571 p_present_in.p_rate_type := 'S';
1572 ELSE
1573 p_present_in.p_rate_type := 'P';
1574 p_present_in.p_compound_freq := 1;
1575 END IF;
1576 XTR_MM_COVERS.present_value(p_present_in, p_present_out);
1577 p_fair_value := p_present_out.p_present_val;
1578
1579 -- account for buy/sell sign
1580 IF (p_deal_subtype in ('SHORT', 'ISSUE')) THEN
1581 p_fair_value := p_fair_value * (-1);
1582 END IF;
1583 END IF;
1584 IF (g_proc_level>=g_debug_level) THEN
1585 XTR_RISK_DEBUG_PKG.dlog('fv_ni: ' || 'conversion of ACTUAL365');
1586 END IF;
1587 -- convert reval rate into ACTUAL365
1588 IF (p_day_count_basis <> p_reval_day_count_basis) THEN
1589 IF (p_rate_type = 'Y') THEN
1590 p_conv_in.p_start_date := p_date;
1591 ELSE
1592 p_conv_in.p_start_date := p_spot_date;
1593 END IF;
1594 p_conv_in.p_end_date := p_maturity_date;
1595 p_conv_in.p_day_count_basis_in := p_day_count_basis;
1596 p_conv_in.p_day_count_basis_out := p_reval_day_count_basis;
1597 IF (within_one_year(p_date, p_maturity_date)) THEN
1598 p_conv_in.p_rate_type_in := 'S';
1599 p_conv_in.p_rate_type_out := 'S';
1600 ELSE
1601 p_conv_in.p_rate_type_in := 'P';
1602 p_conv_in.p_rate_type_out := 'P';
1603 p_conv_in.p_compound_freq_in := 1;
1604 p_conv_in.p_compound_freq_out := 1;
1605 END IF;
1606 p_conv_in.p_rate_in := p_reval_rate;
1607 XTR_RATE_CONVERSION.rate_conversion(p_conv_in, p_conv_out);
1608 p_reval_rate := p_conv_out.p_rate_out;
1609 END IF;
1610 END IF;
1611 IF (g_proc_level>=g_debug_level) THEN
1612 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_ni');
1613 END IF;
1614 END fv_ni;
1615
1616
1617
1618 PROCEDURE fv_bond( p_price_model IN VARCHAR2,
1619 p_set_code IN VARCHAR2,
1620 p_deal_subtype IN VARCHAR2,
1621 /* xtr_bond_issues.ric_code */
1622 p_bond_code IN VARCHAR2,
1623 p_bond_issue_code IN VARCHAR2,
1624 p_ccy IN VARCHAR2,
1628 p_day_count_basis IN VARCHAR2,
1625 p_interpolation_method IN VARCHAR2,
1626 p_coupon_action IN VARCHAR2,
1627 /* for coupon rate */
1629 p_spot_date IN DATE,
1630 /* WDK: don't need this
1631 p_start_date IN DATE,
1632 */
1633 p_maturity_date IN DATE,
1634 p_coupon_rate IN NUMBER,
1635 p_face_value IN NUMBER,
1636 p_margin IN NUMBER,
1637 p_rounding_type IN VARCHAR2,
1638 p_day_count_type IN VARCHAR2,
1639 p_side IN OUT NOCOPY VARCHAR2,
1640 p_clean_price_reval IN OUT NOCOPY NUMBER,
1641 p_dirty_price IN OUT NOCOPY NUMBER,
1642 p_ytm IN OUT NOCOPY NUMBER,
1643 p_accrued_interest IN OUT NOCOPY NUMBER,
1644 p_fair_value IN OUT NOCOPY NUMBER,
1645 --bug 2804548
1646 p_actual_ytm OUT NOCOPY NUMBER) IS
1647
1648 p_yield NUMBER := NULL;
1649 p_bond_yield_with_margin NUMBER;
1650 p_dummy1 NUMBER;
1651 p_dummy2 NUMBER;
1652 p_days_start NUMBER;
1653 p_annual_basis NUMBER;
1654
1655 p_settle_date DATE;
1656
1657 p_md_in XTR_MARKET_DATA_P.md_from_set_in_rec_type;
1658 p_md_out XTR_MARKET_DATA_P.md_from_set_out_rec_type;
1659 p_py_in XTR_MM_COVERS.bond_price_yield_in_rec_type;
1660 p_py_out XTR_MM_COVERS.bond_price_yield_out_rec_type;
1661
1662 BEGIN
1663 IF (g_proc_level>=g_debug_level) THEN
1664 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_bond');
1665 END IF;
1666 IF (p_price_model = 'MARKET') THEN
1667 IF (p_deal_subtype = 'BUY') THEN
1668 p_side := 'B';
1669 ELSIF (p_deal_subtype = 'ISSUE') THEN
1670 p_side := 'A';
1671 END IF;
1672
1673 p_md_in.p_md_set_code := p_set_code;
1674 p_md_in.p_source := 'C';
1675 p_md_in.p_indicator := 'B';
1676 p_md_in.p_spot_date := p_spot_date;
1677 p_md_in.p_future_date := NULL;
1678 p_md_in.p_ccy := p_ccy;
1679 p_md_in.p_day_count_basis_out := p_day_count_basis;
1680 p_md_in.p_interpolation_method := p_interpolation_method;
1681 p_md_in.p_side := p_side;
1682 p_md_in.p_batch_id := NULL;
1683 p_md_in.p_bond_code := p_bond_code;
1684 IF (g_proc_level>=g_debug_level) THEN
1685 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'calling market data api');
1686 END IF;
1687 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1688 IF (g_proc_level>=g_debug_level) THEN
1689 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'returned from market data api');
1690 END IF;
1691 p_clean_price_reval := p_md_out.p_md_out;-- clean price as of ref date
1692 IF (g_proc_level>=g_debug_level) THEN
1693 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond clean price reval: '||p_clean_price_reval);
1694 END IF;
1695
1696 -- get accrued int per 100
1697 -- accrued interest exists only if coupon already started
1698
1699 /* WDK: this code is no longer needed!
1700 XTR_CALC_P.calc_days_run_c(p_start_date, p_spot_date,
1701 p_day_count_basis, null, p_days_start, p_annual_basis);
1702 */
1703 /* bug 2426008
1704 p_accrued_interest := (100*p_coupon_rate*p_days_start)/
1705 (100*p_annual_basis);
1706 IF (g_proc_level>=g_debug_level) THEN
1707 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'accrued int per 100: '||p_accrued_interest);
1708 END IF;
1709 */
1710
1711
1712 -- p_yield gives us the bond price converted to YTM
1713 IF (g_proc_level>=g_debug_level) THEN
1714 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond issue code: '||p_bond_issue_code);
1715 END IF;
1716 p_py_in.p_bond_issue_code := p_bond_issue_code;
1717 p_py_in.p_settlement_date := p_spot_date;
1718 p_py_in.p_ex_cum_next_coupon := p_coupon_action;
1719 p_py_in.p_calculate_yield_or_price := 'Y';
1720 p_py_in.p_clean_price := p_clean_price_reval;
1721 p_py_in.p_input_or_calculator := 'I';
1722
1723 p_py_in.p_currency := p_ccy; -- COMPOUND COUPON
1724 p_py_in.p_face_value := p_face_value; -- COMPOUND COUPON
1725 p_py_in.p_rounding_type := p_rounding_type; -- COMPOUND COUPON
1726 p_py_in.p_day_count_type := p_day_count_type;
1727 p_py_in.p_first_trans_flag := 'Y';
1728 p_py_in.p_deal_subtype := p_deal_subtype;
1729
1730 XTR_MM_COVERS.calculate_bond_price_yield(p_py_in, p_py_out);
1731 p_ytm := p_py_out.p_yield;
1732 p_actual_ytm := p_py_out.p_actual_ytm; --bug 2804548 QRM BPV
1733 -- bug 2426008
1734 p_accrued_interest := p_py_out.p_accrued_interest;
1735
1736 IF (g_proc_level>=g_debug_level) THEN
1737 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond price converted to YTM: '||p_ytm);
1738 END IF;
1739 -- if margin exists, convert bond price to YTM, add margin,
1740 -- then convert sum back to bond price
1741 IF (p_margin IS NOT NULL) THEN
1742 IF (g_proc_level>=g_debug_level) THEN
1743 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond margin: '||p_margin);
1744 END IF;
1745 p_ytm := p_ytm + p_margin/100;
1746 IF (g_proc_level>=g_debug_level) THEN
1747 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond YTM with margin: '||p_ytm);
1748 END IF;
1749
1750 -- convert everything back to bond price
1751 IF (p_spot_date < p_maturity_date) THEN
1752 p_settle_date := p_spot_date;
1753 ELSE
1754 p_settle_date := p_maturity_date;
1755 END IF;
1756
1757 -- clean price now includes margin
1758 p_py_in.p_bond_issue_code := p_bond_issue_code;
1759 p_py_in.p_settlement_date := p_settle_date;
1760 p_py_in.p_ex_cum_next_coupon := p_coupon_action;
1761 p_py_in.p_calculate_yield_or_price := 'P';
1762 p_py_in.p_yield := p_ytm;
1763 p_py_in.p_input_or_calculator := 'I';
1764
1765 p_py_in.p_currency := p_ccy; -- COMPOUND COUPON
1769 p_py_in.p_first_trans_flag := 'Y';
1766 p_py_in.p_face_value := p_face_value; -- COMPOUND COUPON
1767 p_py_in.p_rounding_type := p_rounding_type; -- COMPOUND COUPON
1768 p_py_in.p_day_count_type := p_day_count_type;
1770 p_py_in.p_deal_subtype := p_deal_subtype;
1771
1772
1773 XTR_MM_COVERS.calculate_bond_price_yield(p_py_in, p_py_out);
1774 p_clean_price_reval := p_py_out.p_clean_price;
1775
1776 IF (g_proc_level>=g_debug_level) THEN
1777 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'clean price with margin: '||
1778 p_clean_price_reval);
1779 END IF;
1780 END IF;
1781
1782 p_dirty_price := p_clean_price_reval + p_accrued_interest;
1783
1784 -- convert accrued interest into actual amount
1785 p_accrued_interest := (NVL(p_accrued_interest, 0)/100)*
1786 p_face_value;
1787 p_fair_value := (p_dirty_price/100) * p_face_value;
1788
1789 IF (g_proc_level>=g_debug_level) THEN
1790 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'final dirty price: '||p_dirty_price);
1791 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'accrued int: '||p_accrued_interest);
1792 END IF;
1793
1794 IF (p_deal_subtype = 'ISSUE') THEN
1795 p_fair_value := (-1)*p_fair_value;
1796 END IF;
1797
1798 IF (g_proc_level>=g_debug_level) THEN
1799 XTR_RISK_DEBUG_PKG.dlog('fv_bond: ' || 'bond fair value: '||p_fair_value);
1800 END IF;
1801 END IF;
1802 IF (g_proc_level>=g_debug_level) THEN
1803 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_bond');
1804 END IF;
1805 END fv_bond;
1806
1807
1808
1809 PROCEDURE fv_tmm_irs_rtmm(
1810 p_price_model IN VARCHAR2,
1811 p_deal_type IN VARCHAR2,
1812 p_set_code IN VARCHAR2,
1813 p_bpv IN VARCHAR2,--'Y' or 'N'
1814 p_deal_subtype IN VARCHAR2,
1815 p_interpolation_method IN VARCHAR2,
1816 p_ccy IN VARCHAR2,
1817 p_discount_basis IN VARCHAR2, -- for IRS
1818 p_initial_basis IN VARCHAR2, -- for IRS
1819 p_spot_date IN DATE,
1820 p_settle_date IN DATE, -- for TMM/RTMM
1821 p_margin IN NUMBER,
1822 p_last_rec_trans_no IN NUMBER,
1823 p_day_count_basis IN VARCHAR2,-- int rates
1824 p_transaction_nos IN XTR_MD_NUM_TABLE,--inc order
1825 p_start_dates IN SYSTEM.QRM_DATE_TABLE,
1826 p_maturity_dates IN SYSTEM.QRM_DATE_TABLE,
1827 p_settle_dates IN SYSTEM.QRM_DATE_TABLE,
1828 p_coupon_due_on_dates IN SYSTEM.QRM_DATE_TABLE, -- prepaid interest
1829 p_interest_refunds IN XTR_MD_NUM_TABLE, -- prepaid interest
1830 p_principal_actions IN SYSTEM.QRM_VARCHAR_TABLE,
1831 p_interest_rates IN XTR_MD_NUM_TABLE,
1832 -- interest settled for TMM/IRS
1833 -- amount due for RTMM
1834 p_interest_settled IN XTR_MD_NUM_TABLE,
1835 -- nvl(p_principal_adjusts, 0) before calling
1836 p_principal_adjusts IN XTR_MD_NUM_TABLE,
1837 p_accum_interests IN XTR_MD_NUM_TABLE,
1838 p_accum_interests_bf IN XTR_MD_NUM_TABLE, -- bug 2807340
1839 p_balance_outs IN XTR_MD_NUM_TABLE,
1840 p_settle_term_interests IN SYSTEM.QRM_VARCHAR_TABLE,--TMM
1841 p_side IN OUT NOCOPY VARCHAR2,
1842 p_pv_cashflows IN OUT NOCOPY XTR_MD_NUM_TABLE,
1843 p_cf_days IN OUT NOCOPY XTR_MD_NUM_TABLE,
1844 p_annual_basis IN OUT NOCOPY NUMBER,
1845 p_trans_rate IN OUT NOCOPY NUMBER,
1846 p_accrued_int IN OUT NOCOPY NUMBER,
1847 p_fair_value IN OUT NOCOPY NUMBER) IS
1848
1849 p_length NUMBER := p_start_dates.count;
1850 p_days1 NUMBER;
1851 p_days2 NUMBER;
1852 p_accum_int_sum NUMBER := 0;
1853 p_coupon_rate NUMBER;
1854 p_rate1 NUMBER;
1855 p_rate2 NUMBER;
1856 p_coupon_int NUMBER;
1857 p_future_val NUMBER;
1858
1859 p_principal NUMBER := 0;
1860 p_coupon_cf NUMBER := 0;
1861 p_accrued_interest NUMBER := 0;
1862 p_cf_counter NUMBER := 0;
1863
1864 p_mm_day_count_basis VARCHAR2(15) := 'ACTUAL365';
1865
1866 p_md_in xtr_market_data_p.md_from_set_in_rec_type;
1867 p_md_out xtr_market_data_p.md_from_set_out_rec_type;
1868 p_mm_in XTR_MM_COVERS.int_forw_rate_in_rec_type;
1869 p_mm_out XTR_MM_COVERS.int_forw_rate_out_rec_type;
1870 p_rc_in XTR_RATE_CONVERSION.rate_conv_in_rec_type;
1871 p_rc_out XTR_RATE_CONVERSION.rate_conv_out_rec_type;
1872 p_df_in XTR_RATE_CONVERSION.df_in_rec_type;
1873 p_df_out XTR_RATE_CONVERSION.df_out_rec_type;
1874
1875
1876 FUNCTION present_val_tmm(p_set_code VARCHAR2,
1877 p_bpv VARCHAR2,
1878 p_spot_date DATE,
1879 p_start_date DATE,
1880 p_ccy VARCHAR2,
1881 p_day_count_basis VARCHAR2,
1882 p_interpolation_method VARCHAR2,
1883 p_side VARCHAR2,
1884 p_future_val NUMBER)
1885 RETURN NUMBER IS
1886
1887 p_md_in xtr_market_data_p.md_from_set_in_rec_type;
1888 p_md_out xtr_market_data_p.md_from_set_out_rec_type;
1889 p_present_in XTR_MM_COVERS.presentValue_in_rec_type;
1890 p_present_out XTR_MM_COVERS.presentValue_out_rec_type;
1891
1892 BEGIN
1893 IF (g_proc_level>=g_debug_level) THEN
1894 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_tmm_irs_rtmm.present_value_tmm');
1895 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'spot date', p_spot_date);
1896 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'start date', p_start_date);
1897 END IF;
1898 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_date,
1899 p_day_count_basis, null, p_days1, p_annual_basis);
1900 p_md_in.p_md_set_code := p_set_code;
1901 p_md_in.p_source := 'C'; -- for xtr_market_prices table
1902 p_md_in.p_indicator := 'Y'; -- yield rate
1903 p_md_in.p_spot_date := p_spot_date;
1904 p_md_in.p_future_date := p_start_date;
1905 p_md_in.p_ccy := p_ccy;
1906 p_md_in.p_contra_ccy := NULL;
1910 p_md_in.p_batch_id := NULL;
1907 p_md_in.p_day_count_basis_out := p_day_count_basis;
1908 p_md_in.p_interpolation_method := p_interpolation_method;
1909 p_md_in.p_side := p_side;
1911 p_md_in.p_bond_code := NULL;
1912 XTR_MARKET_DATA_P.get_md_from_set(p_md_in, p_md_out);
1913 p_present_in.p_indicator := 'Y'; -- yield rate
1914 p_present_in.p_future_val := p_future_val;
1915 IF (g_proc_level>=g_debug_level) THEN
1916 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'future val: '||p_future_val);
1917 END IF;
1918 IF (p_bpv = 'Y') THEN
1919 p_present_in.p_rate := p_md_out.p_md_out + 0.01;
1920 ELSE
1921 p_present_in.p_rate := p_md_out.p_md_out;
1922 END IF;
1923 IF (g_proc_level>=g_debug_level) THEN
1924 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'yield rate', p_present_in.p_rate);
1925 END IF;
1926 p_present_in.p_pv_date := p_spot_date;
1927 p_present_in.p_fv_date := p_start_date;
1928 p_present_in.p_day_count_basis := p_day_count_basis;
1929 IF (g_proc_level>=g_debug_level) THEN
1930 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'day count basis', p_day_count_basis);
1931 END IF;
1932 IF within_one_year(p_spot_date, p_start_date) THEN
1933 IF (g_proc_level>=g_debug_level) THEN
1934 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'within one year');
1935 END IF;
1936 p_present_in.p_rate_type := 'S';
1937 ELSE
1938 IF (g_proc_level>=g_debug_level) THEN
1939 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'greater than one year');
1940 END IF;
1941 p_present_in.p_rate_type := 'P';
1942 p_present_in.p_compound_freq := 1;
1943 END IF;
1944 XTR_MM_COVERS.present_value(p_present_in, p_present_out);
1945 IF (g_proc_level>=g_debug_level) THEN
1946 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'present val', p_present_out.p_present_val);
1947 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_tmm_irs_rtmm.present_val_tmm');
1948 END IF;
1949 return p_present_out.p_present_val;
1950 END present_val_tmm;
1951 BEGIN
1952 IF (g_proc_level>=g_debug_level) THEN
1953 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.fv_tmm_irs_rtmm');
1954 END IF;
1955 IF ((p_maturity_dates.count <> p_length) OR
1956 (p_settle_dates.count <> p_length) OR
1957 (p_principal_actions.count <> p_length) OR
1958 (p_interest_rates.count <> p_length) OR
1959 (p_interest_settled.count <> p_length) OR
1960 (p_principal_adjusts.count <> p_length) OR
1961 (p_accum_interests.count <> p_length) OR
1962 (p_coupon_due_on_dates.count <> p_length) OR -- prepaid interest
1963 (p_interest_refunds.count <> p_length) OR -- prepaid interest
1964 (p_balance_outs.count <> p_length)) THEN
1965
1966 -- do exception handling here
1967 RAISE_APPLICATION_ERROR
1968 (-20001,'Arrays must be the same size.');
1969
1970 ELSIF (p_price_model = 'DISC_CASHFLOW') THEN
1971 p_fair_value := 0;
1972 p_accrued_int := 0;
1973 p_pv_cashflows.DELETE;
1974 p_cf_days.DELETE;
1975
1976 FOR i IN 1..p_length LOOP
1977
1978 IF (p_spot_date < p_maturity_dates(i)) THEN
1979 --******* Calculate Principal ********-----
1980 IF (p_deal_type = 'IRS' and p_discount_basis = 'N') THEN
1981 p_principal := 0;
1982 ELSE
1983 IF (p_spot_date < p_start_dates(i)) THEN
1984 IF (p_principal_actions(i) = 'INCRSE') THEN
1985 p_future_val := nvl(p_principal_adjusts(i),0);
1986 IF (p_deal_subtype = 'FUND') THEN
1987 p_side := 'B';
1988 p_future_val := nvl((-1)*p_principal_adjusts(i),0);
1989 ELSE
1990 p_side := 'A';
1991 END IF;
1992 ELSIF (p_principal_actions(i) = 'DECRSE') THEN
1993 p_future_val := nvl(p_principal_adjusts(i),0);
1994 IF (p_deal_subtype = 'FUND') THEN
1995 p_side := 'A';
1996 ELSE
1997 p_side := 'B';
1998 END IF;
1999 ELSE
2000 -- if no principal adjustment, principal is zero
2001 p_future_val := 0;
2002 END IF;
2003
2004 -- p_future_val := nvl(p_principal_adjusts(i),0);
2005 p_principal := present_val_tmm(p_set_code, p_bpv, p_spot_date,
2006 p_start_dates(i), p_ccy, p_day_count_basis,
2007 p_interpolation_method, p_side, p_future_val);
2008
2009 ELSE -- spot date is past start date
2010 -- present value of principal is zero
2011 p_principal := 0;
2012 END IF;
2013 END IF;
2014
2015 IF (p_deal_subtype = 'FUND') THEN
2016 p_side := 'A';
2017 ELSE
2018 p_side := 'B';
2019 END IF;
2020
2021 ----******** Calculate Coupon CF *********-----
2022 IF (p_deal_type = 'TMM' AND
2023 p_last_rec_trans_no = p_transaction_nos(i)) THEN
2024 -- !!! - interest settled here
2025 p_future_val := p_interest_settled(i) - p_accum_int_sum + nvl(p_interest_refunds(i),0); -- prepaid interest
2026 p_coupon_cf := present_val_tmm(p_set_code, p_bpv, p_spot_date,
2027 p_settle_dates(i), p_ccy, p_day_count_basis, -- prepaid interest
2028 p_interpolation_method, p_side, p_future_val);
2029 -- settle_date = null means transaction is floating
2030 -- else it is fixed
2031 ELSIF (p_deal_type = 'RTMM' AND
2032 p_last_rec_trans_no = p_transaction_nos(i)) THEN -- bug 3436334
2033 p_future_val := p_interest_settled(i) - p_accum_int_sum;
2034 p_coupon_cf := present_val_tmm(p_set_code, p_bpv, p_spot_date,
2035 p_maturity_dates(i), p_ccy, p_day_count_basis,
2036 p_interpolation_method, p_side, p_future_val);
2037 ELSIF ( (p_deal_type IN ('TMM', 'RTMM') AND
2038 p_spot_date <= p_settle_date AND
2039 p_settle_date IS NOT NULL AND
2043 IF (g_proc_level>=g_debug_level) THEN
2040 p_start_dates(i) <= p_settle_date)
2041 OR (p_deal_type = 'IRS' AND p_initial_basis = 'FIXED')) THEN
2042 -- fixed rate
2044 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'FIXED LEG');
2045 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'settle date: '||p_settle_date);
2046 END IF;
2047 p_side := 'A';
2048 p_future_val := p_interest_settled(i) + nvl(p_interest_refunds(i),0); -- prepaid interest
2049 p_coupon_rate := p_interest_rates(i);
2050 IF (g_proc_level>=g_debug_level) THEN
2051 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'pv future val: '||p_future_val);
2052 END IF;
2053
2054 if p_deal_type = 'RTMM' then -- bug 3436334
2055 p_coupon_cf := present_val_tmm(p_set_code, p_bpv, p_spot_date,
2056 p_maturity_dates(i), p_ccy, p_day_count_basis,
2057 p_interpolation_method, p_side, p_future_val);
2058 else
2059 p_coupon_cf := present_val_tmm(p_set_code, p_bpv, p_spot_date,
2060 p_settle_dates(i), p_ccy, p_day_count_basis, -- prepaid interest
2061 p_interpolation_method, p_side, p_future_val);
2062 end if;
2063
2064 ELSE
2065 IF (g_proc_level>=g_debug_level) THEN
2066 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'FLOATING LEG');
2067 END IF;
2068 -- floating rate
2069 IF (g_proc_level>=g_debug_level) THEN
2070 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'spot date: '||p_spot_date);
2071 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'start date: '||p_start_dates(i));
2072 END IF;
2073 IF (p_spot_date >= p_start_dates(i)) THEN
2074 p_coupon_rate := p_interest_rates(i);
2075 ELSE
2076 -- get forward rate
2077 IF (g_proc_level>=g_debug_level) THEN
2078 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'transaction no: '||p_transaction_nos(i));
2079 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'deal_type: '||p_deal_type);
2080 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'calling calculate fwd rate');
2081 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'maturity date is: '||p_maturity_dates(i));
2082 END IF;
2083 -- FOR TMM/IRS calc of bpv, need to add 1 BPV to underlying rates
2084 p_coupon_rate := calculate_fwd_rate(p_set_code, p_bpv,
2085 p_deal_subtype, p_day_count_basis, p_ccy,
2086 p_interpolation_method, p_spot_date,
2087 p_start_dates(i), p_maturity_dates(i));
2088 IF (g_proc_level>=g_debug_level) THEN
2089 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'fwd coupon rate w/o margin: '||p_coupon_rate);
2090 END IF;
2091
2092 p_coupon_rate := p_coupon_rate + NVL(p_margin/100, 0);
2093 END IF;
2094
2095 IF (g_proc_level>=g_debug_level) THEN
2096 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'coupon rate w/margin: '||p_coupon_rate);
2097 END IF;
2098
2099 p_coupon_int := qrm_calc_interest(p_balance_outs(i),
2100 p_start_dates(i), p_maturity_dates(i), p_coupon_rate,
2101 p_day_count_basis);
2102 IF (g_proc_level>=g_debug_level) THEN
2103 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'coupon amt: '||p_coupon_int);
2104 END IF;
2105
2106 IF ((p_deal_type IN ('TMM', 'RTMM') and p_settle_term_interests(i) = 'Y')
2107 OR (p_deal_type = 'IRS')) THEN
2108 IF (p_deal_subtype = 'FUND') THEN
2109 p_side := 'A';
2110 ELSE
2111 p_side := 'B';
2112 END IF;
2113
2114 p_future_val := p_coupon_int;
2115
2116 p_coupon_cf := present_val_tmm(p_set_code, p_bpv,
2117 p_spot_date, p_settle_dates(i), p_ccy, -- prepaid interest
2118 p_day_count_basis, p_interpolation_method,
2119 p_side, p_future_val);
2120 -- interest settled, so no accrued interest
2121 ELSE
2122 p_accum_int_sum := p_accum_int_sum + p_coupon_int
2123 + p_accum_interests(i);
2124 IF (g_proc_level>=g_debug_level) THEN
2125 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int now: '||p_accrued_interest);
2126 END IF;
2127 END IF;
2128 END IF; -- ends floating part
2129 END IF; -- end spot date < coupon due on date for prepaid interest
2130
2131 IF (g_proc_level>=g_debug_level) THEN
2132 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'pv coupon cf: '||p_coupon_cf);
2133 END IF;
2134
2135 p_accrued_interest := 0;
2136 -- calculate interest rate, accrued interest for current transaction
2137 IF ((p_spot_date >= p_start_dates(i)) AND
2138 (p_spot_date < p_maturity_dates(i))) THEN
2139 p_coupon_rate := p_interest_rates(i);
2140 IF (g_proc_level>=g_debug_level) THEN
2141 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int balance out: '||p_balance_outs(i));
2142 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int start date: '||p_start_dates(i));
2143 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int spot date: '||p_spot_date);
2144 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int coupon rate: '||p_coupon_rate);
2145 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int DCB: '||p_day_count_basis);
2146 END IF;
2147 -- accrued interest for TMM/IRS is simple interest
2148 -- for RTMM is it fraction of amount due
2149 IF (p_deal_type = 'RTMM') THEN
2150 XTR_CALC_P.calc_days_run_c(p_start_dates(i), p_spot_date,
2151 p_day_count_basis, null, p_days1, p_annual_basis);
2152 XTR_CALC_P.calc_days_run_c(p_start_dates(i),
2153 p_maturity_dates(i), p_day_count_basis, null, p_days2,
2154 p_annual_basis);
2155 p_accrued_interest := p_interest_settled(i)*(p_days1/p_days2);
2156 ELSE
2157 if (p_coupon_due_on_dates(i)<p_maturity_dates(i) and (nvl(p_settle_term_interests(i),'Y')='Y')) then -- prepaid interest
2161 - qrm_calc_interest(p_balance_outs(i),
2158 p_accrued_interest := qrm_calc_interest(p_balance_outs(i),
2159 p_start_dates(i), p_spot_date, p_coupon_rate,
2160 p_day_count_basis)
2162 p_start_dates(i), p_maturity_dates(i), p_coupon_rate,
2163 p_day_count_basis);
2164 else -- if not prepaid interest
2165 p_accrued_interest := qrm_calc_interest(p_balance_outs(i),
2166 p_start_dates(i), p_spot_date, p_coupon_rate,
2167 p_day_count_basis);
2168 end if; -- prepaid interest
2169 p_accrued_interest := p_accrued_interest + nvl(p_accum_interests_bf(i),0); -- bug 2807340
2170 END IF;
2171 -- transaction rate: int rate converted to Act/365
2172 IF (g_proc_level>=g_debug_level) THEN
2173 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'dcb in : '||p_day_count_basis);
2174 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'start date: '||p_start_dates(i));
2175 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'int rate in: '||p_interest_rates(i));
2176 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'coupon rate in: '||p_coupon_rate);
2177 END IF;
2178 p_rc_in.p_start_date := p_start_dates(i);
2179 p_rc_in.p_end_date := p_maturity_dates(i);
2180 p_rc_in.p_day_count_basis_in := p_day_count_basis;
2181 p_rc_in.p_day_count_basis_out := p_mm_day_count_basis;
2182 IF (within_one_year(p_start_dates(i), p_maturity_dates(i))) THEN
2183 p_rc_in.p_rate_type_in := 'S';
2184 p_rc_in.p_rate_type_out := 'S';
2185 ELSE
2186 p_rc_in.p_rate_type_in := 'P';
2187 p_rc_in.p_rate_type_out := 'P';
2188 p_rc_in.p_compound_freq_in := 1;
2189 p_rc_in.p_compound_freq_out := 1;
2190 END IF;
2191 p_rc_in.p_rate_in := p_interest_rates(i);
2192 XTR_RATE_CONVERSION.rate_conversion(p_rc_in, p_rc_out);
2193 p_trans_rate := p_rc_out.p_rate_out;
2194 IF (g_proc_level>=g_debug_level) THEN
2195 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'trans rate: '||p_trans_rate);
2196 END IF;
2197 END IF;
2198
2199 IF (g_proc_level>=g_debug_level) THEN
2200 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'entering pv cashflow');
2201 END IF;
2202 -- output present value of cashflow
2203 IF (g_proc_level>=g_debug_level) THEN
2204 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'principal is: '||p_principal);
2205 END IF;
2206 IF (p_principal <> 0) THEN
2207 p_cf_counter := p_cf_counter + 1;
2208 p_pv_cashflows.EXTEND;
2209 p_pv_cashflows(p_cf_counter) := p_principal;
2210 p_cf_days.EXTEND;
2211 IF (g_proc_level>=g_debug_level) THEN
2212 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'spot date: '||p_spot_date);
2213 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'start date: '||p_start_dates(i));
2214 END IF;
2215 XTR_CALC_P.calc_days_run_c(p_spot_date, p_start_dates(i),
2216 p_day_count_basis, NULL, p_cf_days(p_cf_counter),
2217 p_annual_basis);
2218 IF (p_deal_subtype = 'FUND') THEN
2219 p_pv_cashflows(p_cf_counter) := (-1)*p_pv_cashflows(p_cf_counter);
2220 END IF;
2221 IF (g_proc_level>=g_debug_level) THEN
2222 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'pv cashflow: '||p_pv_cashflows(p_cf_counter));
2223 END IF;
2224 XTR_RISK_DEBUG_PKG.dlog('day/year ratio: '||p_cf_days(p_cf_counter)/p_annual_basis);
2225 END IF;
2226 IF (p_coupon_cf <> 0) THEN
2227 p_cf_counter := p_cf_counter + 1;
2228 p_pv_cashflows.EXTEND;
2229 p_pv_cashflows(p_cf_counter) := p_coupon_cf;
2230 p_cf_days.EXTEND;
2231 XTR_CALC_P.calc_days_run_c(p_spot_date,
2232 p_settle_dates(i), p_day_count_basis, NULL, -- prepaid interest
2233 p_cf_days(p_cf_counter), p_annual_basis);
2234 IF (p_deal_subtype = 'FUND') THEN
2235 p_pv_cashflows(p_cf_counter) := (-1)*p_pv_cashflows(p_cf_counter);
2236 END IF;
2237 IF (g_proc_level>=g_debug_level) THEN
2238 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'pv cashflow: '||p_pv_cashflows(p_cf_counter));
2239 END IF;
2240 XTR_RISK_DEBUG_PKG.dlog('day/year ratio: '||p_cf_days(p_cf_counter)/p_annual_basis);
2241 END IF;
2242
2243 -- QRM does not exclude accrued interest from FV calculation
2244 p_fair_value := p_fair_value + nvl(p_principal,0) + p_coupon_cf;
2245 IF (g_proc_level>=g_debug_level) THEN
2246 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'accrued int before adding: '||p_accrued_interest);
2247 END IF;
2248 p_accrued_int := p_accrued_int + p_accrued_interest;
2249 IF (g_proc_level>=g_debug_level) THEN
2250 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'interation is: '||i);
2251 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'temp principal: '||p_principal);
2252 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'temp accrued int: '||p_accrued_interest);
2253 XTR_RISK_DEBUG_PKG.dlog('fv_tmm_irs_rtmm: ' || 'temp fair value is: '||p_fair_value);
2254 END IF;
2255 END LOOP;
2256
2257
2258 IF (p_deal_subtype = 'FUND') THEN
2259 p_fair_value := (-1) * p_fair_value;
2260 p_accrued_int := (-1) * p_accrued_int;
2261
2262 END IF;
2263 END IF;
2264 IF (g_proc_level>=g_debug_level) THEN
2265 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.fv_tmm_irs_rtmm');
2266 END IF;
2267 END fv_tmm_irs_rtmm;
2268
2269
2270
2271 /*******************************************************/
2272 /* This function return interest base on principle, */
2273 /* rate and number of days */
2274 /*******************************************************/
2275 FUNCTION qrm_calc_interest(
2276 p_principle IN NUMBER,
2277 p_start_date IN DATE,
2278 p_end_date IN DATE,
2279 p_rate IN NUMBER,
2280 p_day_count_basis IN VARCHAR2) return NUMBER IS
2281
2282 p_day NUMBER;
2283 p_year NUMBER;
2284 begin
2285 XTR_CALC_P.calc_days_run_c(p_start_date, p_end_date,
2286 p_day_count_basis, NULL, p_day, p_year);
2287 return (p_principle * p_rate * p_day) / (p_year * 100);
2288 END qrm_calc_interest;
2289
2290
2291 -- p_indicator = 'R': calculate accrued interest to ref date
2292 -- 'M': calculate accrued interest to maturity date
2293 FUNCTION calculate_accrued_interest(p_indicator VARCHAR2,
2294 p_ref_date DATE,
2295 p_start_date DATE,
2296 p_maturity_date DATE,
2297 p_interest_rate NUMBER,
2298 p_interest NUMBER,
2299 p_accum_interest_bf NUMBER,
2300 p_balance_out NUMBER,
2301 p_no_of_days NUMBER,
2302 p_day_count_basis VARCHAR2,
2303 p_accum_int_action VARCHAR2)
2304 RETURN NUMBER IS
2305
2306 p_day_count NUMBER;
2307 p_annual_basis NUMBER;
2308 p_accrued_interest NUMBER;
2309 BEGIN
2310 IF (g_proc_level>=g_debug_level) THEN
2311 XTR_RISK_DEBUG_PKG.dpush(null,'QRM_MM_FORMULAS.calculate_accrued_interest');
2312 END IF;
2313 IF (p_start_date <= p_ref_date) THEN
2314 IF (p_indicator='M') THEN
2315 IF (p_maturity_date >= p_ref_date) THEN
2316 IF (g_proc_level>=g_debug_level) THEN
2317 XTR_RISK_DEBUG_PKG.dlog('calculate_accrued_interest: ' || 'mat date >= ref date');
2318 END IF;
2319 XTR_CALC_P.calc_days_run_c(trunc(p_start_date),
2320 trunc(p_ref_date), p_day_count_basis, null,
2321 p_day_count,p_annual_basis);
2322 p_accrued_interest := p_interest * (p_day_count / p_no_of_days) +
2323 nvl(p_accum_interest_bf,0);
2324 ELSIF (p_maturity_date <= p_ref_date) THEN
2325 IF (g_proc_level>=g_debug_level) THEN
2326 XTR_RISK_DEBUG_PKG.dlog('calculate_accrued_interest: ' || 'mat date <= ref date');
2327 END IF;
2328 p_accrued_interest := 0;
2329 ELSE
2330 IF (g_proc_level>=g_debug_level) THEN
2331 XTR_RISK_DEBUG_PKG.dlog('calculate_accrued_interest: ' || 'mat date else');
2332 END IF;
2333 XTR_CALC_P.calc_days_run_c(trunc(p_start_date),
2334 trunc(p_ref_date), p_day_count_basis, null,
2335 p_day_count,p_annual_basis);
2336 p_accrued_interest := (p_balance_out * (p_interest_rate /
2337 (p_annual_basis * 100)) * p_day_count) +
2338 nvl(p_accum_interest_bf,0);
2339 END IF;
2340 ELSIF (p_indicator='R') THEN
2341 IF (g_proc_level>=g_debug_level) THEN
2342 XTR_RISK_DEBUG_PKG.dlog('calculate_accrued_interest: ' || 'to ref date');
2343 END IF;
2344 XTR_CALC_P.calc_days_run_c(trunc(p_start_date),
2345 trunc(p_ref_date), p_day_count_basis, null,
2346 p_day_count,p_annual_basis);
2347 p_accrued_interest := (p_balance_out * (p_interest_rate /
2348 (p_annual_basis * 100)) * p_day_count) +
2349 nvl(p_accum_interest_bf,0);
2350 END IF;
2351 ELSIF (p_accum_int_action IS NULL) THEN
2352 p_accrued_interest := nvl(p_accum_interest_bf,0);
2353 ELSE
2354 p_accrued_interest := 0;
2355 END IF;
2356 IF (g_proc_level>=g_debug_level) THEN
2357 XTR_RISK_DEBUG_PKG.dpop(null,'QRM_MM_FORMULAS.calculate_accrued_interest');
2358 END IF;
2359 RETURN p_accrued_interest;
2360
2361 END calculate_accrued_interest;
2362
2363 END;