DBA Data[Home] [Help]

PACKAGE BODY: APPS.XTR_FX_FORMULAS

Source


1 PACKAGE BODY XTR_FX_FORMULAS AS
2 /* $Header: xtrfxflb.pls 120.5 2005/06/29 08:07:57 badiredd ship $ */
3 
4 /*************************FX FORWARD************************************/
5 
6 /*-----------------------------------------------------------------------
7 Calculates the FX Spot Rate for different currencies exchange.
8 
9 Formula:
10 * If the BASIS_CONTRA/BASE is not 'C' (Commodity Unit Quote) then convert with FX FORWARD (HLD) Formula 1
11 * Check CURRENCY_CONTRA and CURRENCY_BASE if cross-currency pair is involved then  use FX FORWARD (HLD) Formula 2
12 
13 Formula 1 is converting from Base Unit Quote to Commodity Unit Quote, and vice versa.
14 Formula 2 is to calculate the SPOT RATE(=Cross Rate)
15 
16 Assumption: p_RATE_CONTRA and p_RATE_BASE have the same day count basis.
17 
18 For IRS:  BASE = Receive Leg
19           CONTRA = Pay Leg
20 
21 Example for FX:CHFGBP -> CHF = Base Currency
22                          GBP = Contra Currency
23 
24 IF there is a notion of BID and ASK then:
25 To find p_SPOT_RATE (BID/ASK):
26 FOR CONTRA:
27   IF p_BASIS_CONTRA = 'C' THEN
28      p_RATE_CONTRA (BID/ASK) = BID/ASK Rate of
29        Contra Currency
30   ELSE
31      p_RATE_CONTRA (BID/ASK) = ASK/BID Rate of
32         Contra Currency
33 FOR BASE:
34   IF p_BASIS_BASE = 'C' THEN
35     p_RATE_BASE (BID/ASK) = ASK/BID Rate of Base
36         Currency
37   ELSE
38     p_RATE_BASE (BID/ASK) = BID/ASK Rate of Base
39         Currency
40 
41 * p_RATE_CONTRA/BASE = FX rate of the contra/base side against USD
42 (p_RATE_CONTRA = Rate vs. USD Contra, p_RATE_ BASE = Rate vs. USD Base).
43 If the currency is USD then p_RATE = 1;
44 * p_CURRENCY_CONTRA/BASE = the currency for contra/base.
45 * p_BASIS_CONTRA/BASE indicates the quotation basis against USD for the CONTRA
46 BASE side, 'C' for Commodity Unit Quote (=USDGBP) and 'B' for Base Unit Quote=
47 GBPUSD) (Definitions are in FX Calculator HLD)
48 * p_SPOT_RATE = fair exchange rate of two different currencies.
49 -----------------------------------------------------------------------*/
50 
51 PROCEDURE FX_SPOT_RATE (p_currency_contra IN VARCHAR2,
52                         p_currency_base IN VARCHAR2,
53                         p_rate_contra IN NUMBER,
54                         p_rate_base IN NUMBER,
55                         p_basis_contra IN CHAR,
56                         p_basis_base IN CHAR,
57                         p_spot_rate IN OUT NOCOPY NUMBER) is
58 
59   e_basis_code EXCEPTION;
60   e_USD_rate EXCEPTION;
61   v_rate_c NUMBER;
62   v_rate_b NUMBER;
63 
64 BEGIN
65 
66 --CHeck whether the indicator is correct
67   IF (p_basis_contra not IN ('C','B','c','b') or
68       p_basis_base not IN ( 'C','B','c','b')) THEN
69 
70 --    FND_MESSAGE.Set_Name('XTR', 'XTR_1059');
71 --    APP_EXCEPTION.raise_exception;
72 
73     RAISE e_basis_code;
74   END IF;
75 
76 --Check if currency USD then rate has to be 1
77   IF (((UPPER(p_currency_contra)= 'USD') and (p_rate_contra <> 1)) or
78       ((UPPER(p_currency_base)= 'USD') and (p_rate_base <> 1))) THEN
79     RAISE e_USD_rate;
80   END IF;
81 
82 --Use Formula 1 to convert the rate to Commodity Unit Quote
83 --
84   IF (p_basis_contra = 'B') THEN
85     v_rate_c := 1/p_rate_contra;
86    ELSE
87     v_rate_c := p_rate_contra;
88   END IF;
89 
90   IF (p_basis_base = 'B') THEN
91     v_rate_b := 1/p_rate_base;
92    ELSE
93     v_rate_b := p_rate_base;
94   END IF;
95 
96 --Use Formula 2 in FX Forward HLD,
97 --if the exchange involves 2 non USD currencies.
98 --If it involves USD we can still use Formula 2 with the USD RATE = 1.
99 --
100   p_spot_rate := v_rate_c/v_rate_b;
101 
102 EXCEPTION
103   WHEN e_basis_code THEN
104 --  dbms_output.put_line('The basis_contra/base values can only be ''C'' or ''B''.');
105       RAISE_APPLICATION_ERROR
106         (-20001,'The basis_contra/base values can only be ''C'' or ''B''.');
107   WHEN e_USD_rate THEN
108       RAISE_APPLICATION_ERROR
109         (-20002,'If currency is USD then the rate = 1.');
110 
111 END FX_SPOT_RATE;
112 
113 
114 /*-------------------------------------------------------------------------
115 Calculates the FX Forward Rate
116 
117 Formula:
118 FX FORWARD (HLD) Formula 3
119 
120 Example for FX: CHFGBP -> CHF = Base Currency
121                           GBP = Contra Currency
122 
123 IF there is a notion of BID and ASK then:
124 To find p_FORWARD_RATE (BID):
125     p_SPOT_RATE = BID FX Spot Rate
126     p_BASE_CURR_INT_RATE = ASK Base Currency risk free interest rate.
127     p_CONTRA_CURR_INT_RATE = BID Contra Currency risk free interest rate.
128 
129 To find p_FORWARD_RATE (ASK):
130     p_SPOT_RATE = ASK FX Spot Rate
131     p_BASE_CURR_INT_RATE = BID Base Currency risk free interest rate.
132     p_CONTRA_CURR_INT_RATE = ASK Contra Currency risk free interest rate.
133 
134 
135 * p_SPOT_RATE = fair exchange rate of two different currencies.
136 * p_BASE/CONTRA_CURR_INT_RATE = risk free interest rate for the base/contra
137 currency.
138 * p_DAY_COUNT_BASE/CONTRA = number of days between the spot date and the
139 forward
140 date.
141 * p_ANNUAL_BASIS_BASE/CONTRA = number of days in a year of which the
142 * p_DAY_COUNT_BASE/CONTRA and the p_BASE/CONTRA_CURR_INT_RATE are based on.
143 -------------------------------------------------------------------------*/
144 
145 PROCEDURE FX_FORWARD_RATE (p_spot_rate IN NUMBER,
146                            p_base_curr_int_rate IN NUMBER,
147                            p_contra_curr_int_rate IN NUMBER,
148                            p_day_count_base IN NUMBER,
149                            p_day_count_contra IN NUMBER,
150                            p_annual_basis_base IN NUMBER,
151                            p_annual_basis_contra IN NUMBER,
152                            p_forward_rate IN OUT NOCOPY NUMBER) is
153 
154   v_rate_base NUMBER;
155   v_rate_contra NUMBER;
156 
157 BEGIN
158 
159   XTR_MM_FORMULAS.GROWTH_FACTOR(p_base_curr_int_rate,
160                                            p_day_count_base,
161                                            p_annual_basis_base,
162                                            v_rate_base);
163   XTR_MM_FORMULAS.GROWTH_FACTOR(p_contra_curr_int_rate,
164                                               p_day_count_contra,
165                                               p_annual_basis_contra,
166                                               v_rate_contra);
167   p_forward_rate := p_spot_rate*(v_rate_contra/v_rate_base);
168 
169 END FX_FORWARD_RATE;
170 
171 
172 /***********************CALC_FX_OPTION_PRICES*******************************/
173 
174 /*--------------------------------------------------------------------------
175 Calculates the price and sensitivity of a currency option and its associated greek ratio's using Garman-Kohlhagen formula, which is the extension of Black-Scholes formula.
176 
177 Formula:
178 Taken from Currency Option Pricing Formula in Hull's Option, Future, and Other Derivatives, Third Edition p.272, p.317.
179 (Defined in xtrprc2b.pls)
180 
181 IMPORTANT: due to the cumulative normal distribution function used, the
182 procedure is accurate up to 6 decimal places.
183 
184 Currently used in xtrrevlb.pld
185 
186 Call XTR_RATE_CONVERSION.rate_conversion to convert day counts and/or between compounded and simple interest rates.
187 
188 * l_days = time left to maturity in days (assuming Actual/365 day count basis).
189 * l_base_int_rate = annual risk free interest rate for base currency.
190 * l_contra_int_rate = annual risk free interest rate for contra currency.
191 * l_spot_rate = the current market rate for the exchange.
192 * l_strike_price = the strike price agreed in the option.
193 * vol = volatility
194 * l_call_price = theoretical fair value of the call.
195 * l_put_price = theoretical fair value of the put
196 * l_fwd_price = the forward rate of the exchange calculated from the l_spot_rate
197 * l_delta_call/put = delta of the call/put
198 * l_theta_call/put = theta of the call/put
199 * l_rho_call/put = rho of the call/put (with respect to the change in base interest rate)
200 * l_rho_f_call/put = rho of call/put with respect to change in foreign interest rate
201 * l_gamma = gamma
202 * l_vega = vega
203 * l_nd1/2 = cumulative normal probability distribution value = N(x) in Black Formu
204 la
205 * l_nd1/2_a = N'(x) in Black Formula
206 
207 gamma, theta, delta, vega are sensitivity measurements of the model relatives to its different variables and explained extensively in Hull's Option, Future, and Other Derivatives.
208 -----------------------------------------------------------------------*/
209 -- modified fhu 6/12/01:  added sensitivity calculations
210 PROCEDURE FX_GK_OPTION_PRICE(
211                              l_days         IN NUMBER,
212                              l_base_int_rate IN NUMBER,
213                              l_contra_int_rate IN NUMBER,
214                              l_spot_rate     IN NUMBER,
215                              l_strike_rate   IN NUMBER,
216                              vol IN NUMBER,
217                              l_call_price IN OUT NOCOPY NUMBER,
218                              l_put_price IN OUT NOCOPY NUMBER,
219                              l_fwd_rate IN OUT NOCOPY NUMBER,
220                              l_nd1 IN OUT NOCOPY NUMBER,
221                              l_nd2 IN OUT NOCOPY NUMBER,
222                              l_nd1_a IN OUT NOCOPY NUMBER,
223                              l_nd2_a IN OUT NOCOPY NUMBER  ) IS
224 
225 --
226 -- Below are approximations of normal probability and PI (always fixed constant)
227  a1 		NUMBER :=  0.4361836;
228  a2 		NUMBER := -0.1201678;
229  a3 		NUMBER := 0.9372980;
230  pi 		NUMBER  := 3.14159265358979;
231 --
232  r_f 		NUMBER := l_base_int_rate / 100;
233  r 		NUMBER := l_contra_int_rate / 100;
234  t 		NUMBER := l_days / 365;  -- bug 3509267
235  v 		NUMBER := vol / 100;
236  d1 		NUMBER;
237  d2 		NUMBER;
238  n_d1 		NUMBER;
239  n_d2 		NUMBER;
240  n_d1_a         NUMBER;
241  n_d2_a         NUMBER;
242 
243  v_cum_normdist_in_rec  xtr_mm_formulas.cum_normdist_in_rec_type;
244  v_cum_normdist_out_rec xtr_mm_formulas.cum_normdist_out_rec_type;
245 
246 BEGIN
247 
248  d1 := (LN(l_spot_rate/l_strike_rate) + (r-r_f + POWER(v,2)/2)*t)  / (v * SQRT(t));
249  d2 := d1 - v*SQRT(t);
250 
251  v_cum_normdist_in_rec.p_d1 := d1;
252  v_cum_normdist_in_rec.p_d2 := d2;
253  xtr_mm_formulas.cumulative_norm_distribution
254 	(v_cum_normdist_in_rec, v_cum_normdist_out_rec);
255 
256  n_d1 := v_cum_normdist_out_rec.p_n_d1;
257  n_d2 := v_cum_normdist_out_rec.p_n_d2;
258  n_d1_a := v_cum_normdist_out_rec.p_n_d1_a;
259  n_d2_a := v_cum_normdist_out_rec.p_n_d2_a;
260 
261 ---- See Currency Options on the Philadelphia Exchange p272
262  l_fwd_rate :=l_spot_rate*EXP((r-r_f)*t);
263  l_call_price := EXP(-r*t)*(l_fwd_rate * n_d1-l_strike_rate*n_d2);
264  l_put_price := EXP(-r*t)*(l_strike_rate*(1-n_d2)-l_fwd_rate*(1-n_d1));
265 
266  l_nd1 := n_d1;
267  l_nd2 := n_d2;
268  l_nd1_a := n_d1_a;
269  l_nd2_a := n_d2_a;
270 
271 END FX_GK_OPTION_PRICE;
272 
273 /*-----------------------------------------------------------------------
274 FX_GK_OPTION_PRICE_CV
275 Cover procedure to calculate the price of a currency option
276 using Garman-Kohlhagen formula, which is the extension of
277 Black-Scholes formula.
278 
279 IMPORTANT: it is better to supply a Simple Actual/365 (from GET_MD_FROM_SET)
280 interest rates for this procedure in order to avoid redundant conversions.
281 
282 IMPORTANT: this procedure is only accurate up to six decimal places due
283 to CUMULATIVE_NORM_DISTRIBUTION procedure it calls.
284 
285 GK_OPTION_CV_IN_REC_TYPE:
286 p_SPOT_DATE date
287 p_MATURITY_DATE date
288 p_RATE_DOM num
289 p_RATE_TYPE_DOM varchar2(1) DEFAULT 'S'
290 p_COMPOUND_FREQ_DOM num
291 p_DAY_COUNT_BASIS_DOM varchar2(15)
292 p_RF_RATE_FOR num
293 p_RATE_TYPE_FOR varchar2(1) DEFAULT 'S'
294 p_COMPOUND_FREQ_FOR num
295 p_DAY_COUNT_BASIS_FOR varchar2(15)
296 p_SPOT_RATE num
297 p_STRIKE_RATE num
298 p_VOLATILITY num
299 
300 GK_OPTION_CV_OUT_REC_TYPE:
301 p_CALL_PRICE num
302 p_PUT_PRICE num
303 p_FX_FWD_RATE num
304 p_Nd1 num
305 p_Nd2 num
306 p_Nd1_a num
307 p_Nd2_a num
308 
309 Formula:
310 1. Converts interest rates to fit the FX_GK_OPTION_PRICE assumptions.
311 2. Calls FX_GK_OPTION_PRICE.
312 
313 Example to calculate p_SPOT_RATE:
314 Given: CAD = foreign, USD = domestic
315 1 USD = 1.5 CADThen: p_SPOT_RATE = 0.666667
316 
317 p_SPOT_DATE = the spot date where the option value is evaluated
318 p_MATURITY_DATE = the maturity date where the option expires
319 p_RF_RATE_DOM = domestic risk free interest rate.
320 p_RATE_TYPE_DOM/FOR = the p_RF_RATE_DOM/FOR rate's type. 'S' for Simple
321  Rate. 'C' for Continuous Rate, and 'P' for Compounding Rate.
322 Default value = 'S' (Simple IR)
323 p_DAY_COUNT_BASIS_DOM/FOR = day count basis for p_RF_RATE_DOM/FOR.
324 p_RATE_FOR = foreign risk free interest rate.
325 p_SPOT_RATE = the current market exchange rate = the value of one unit
326 of the foreign currency measured in the domestic currency.
327 p_STRIKE_RATE = the strike price agreed in the option.
328 p_VOLATILITY = volatility
329 p_CALL_PRICE = theoretical fair value of the call.
330 p_PUT_PRICE = theoretical fair value of the put
331 p_FX_FWD_RATE = the forward rate of the exchange calculated from the
332 p_SPOT_RATE
333 p_Nd1/2 = cumulative distribution value given limit probability values
334 in Black's formula = N(x) (refer to Hull's Fourth Edition p.252)
335 p_Nd1/2_a = N'(x) in Black's formula (refer to Hull's Fourth Edition p.252)
336 p_COMPOUND_FREQ_DOM/FOR = frequencies of discretely compounded input/output
337 rate. This is only necessary if p_RATE_TYPE_DOM/FOR is 'P'.
338 -----------------------------------------------------------------------*/
339 
340 PROCEDURE FX_GK_OPTION_PRICE_CV(p_in_rec IN GK_OPTION_CV_IN_REC_TYPE,
341 				p_out_rec OUT NOCOPY GK_OPTION_CV_OUT_REC_TYPE) IS
342 
343   v_days         NUMBER;
344   v_base_int_rate NUMBER;
345   v_contra_int_rate NUMBER;
346   v_rate_type_dom VARCHAR2(1):='S';
347   v_rate_type_for VARCHAR2(1):='S';
348 
349   v_dummy NUMBER;
350   v_rc_in xtr_rate_conversion.rate_conv_in_rec_type;
351   v_rc_out xtr_rate_conversion.rate_conv_out_rec_type;
352 
353 BEGIN
354   IF xtr_risk_debug_pkg.g_Debug THEN
355      xtr_risk_debug_pkg.dpush('FX_SPOT_RATE: ' || 'XTR_MM_FORMULAS.FX_GK_OPTION_PRICE_CV');
356   END IF;
357 
358   --get number of days in Actual/365  -- bug 3509267
359   xtr_calc_p.calc_days_run_c(p_in_rec.p_spot_date, p_in_rec.p_maturity_date,
360 			'ACTUAL365', null, v_days, v_dummy);
361 
362   --need to converts all rates to Continuously compounded Actual/365  -- bug 3509267
363   v_rc_in.p_rate_type_out := 'C';
364   v_rc_in.p_day_count_basis_out := 'ACTUAL365';
365 /*
366 IF xtr_risk_debug_pkg.g_Debug THEN
367    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Rate Type Dom',p_in_rec.p_rate_type_dom);
368    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Rate Type For',p_in_rec.p_rate_type_for);
369 END IF;
370 */
371   --convert domestic rate to continuous ACTUAL/365  -- bug 3509267
372   IF NOT (p_in_rec.p_rate_type_dom IN ('C','c') AND
373 	p_in_rec.p_day_count_basis_dom = 'ACTUAL365') THEN
374     v_rc_in.p_rate_type_in := p_in_rec.p_rate_type_dom;
375     v_rc_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_dom;
376     v_rc_in.p_rate_in := p_in_rec.p_rate_dom;
377     v_rc_in.p_start_date := p_in_rec.p_spot_date;
378     v_rc_in.p_end_date := p_in_rec.p_maturity_date;
379     v_rc_in.p_compound_freq_in := p_in_rec.p_compound_freq_dom;
380 IF xtr_risk_debug_pkg.g_Debug THEN
381    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Rate Type Dom',p_in_rec.p_rate_type_dom);
382 END IF;
383     xtr_rate_conversion.rate_conversion(v_rc_in, v_rc_out);
384     v_contra_int_rate := v_rc_out.p_rate_out;
385   ELSE
386     v_contra_int_rate := p_in_rec.p_rate_dom;
387   END IF;
388 
389   --convert foreign rate to continuous Actual/365 -- bug 3509267
390   IF NOT (p_in_rec.p_rate_type_for IN ('C','c') AND
391 	p_in_rec.p_day_count_basis_for = 'ACTUAL365') THEN
392     v_rc_in.p_rate_type_in := p_in_rec.p_rate_type_for;
393     v_rc_in.p_day_count_basis_in := p_in_rec.p_day_count_basis_for;
394     v_rc_in.p_rate_in := p_in_rec.p_rate_for;
395     v_rc_in.p_start_date := p_in_rec.p_spot_date;
396     v_rc_in.p_end_date := p_in_rec.p_maturity_date;
397     v_rc_in.p_compound_freq_in := p_in_rec.p_compound_freq_for;
398     xtr_rate_conversion.rate_conversion(v_rc_in, v_rc_out);
399     v_base_int_rate := v_rc_out.p_rate_out;
400   ELSE
401     v_base_int_rate := p_in_rec.p_rate_for;
402   END IF;
403 /*
404 IF xtr_risk_debug_pkg.g_Debug THEN
405    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'No. of Days',v_days);
406    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Foreign IR C Actual/365',v_base_int_rate);
407    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Domestic IR C Actual365', v_contra_int_rate);
408    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Strike Rate',p_in_rec.p_strike_rate);
409    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Spot Rate',p_in_rec.p_spot_rate);
410    xtr_risk_debug_pkg.dlog('FX_SPOT_RATE: ' || 'Vol',p_in_rec.p_volatility);
411 END IF;
412 */
413   --call fx_gk_option_price
414   fx_gk_option_price(v_days, v_base_int_rate, v_contra_int_rate,
415   		p_in_rec.p_spot_rate, p_in_rec.p_strike_rate,
416 		p_in_rec.p_volatility,
417             	p_out_rec.p_call_price, p_out_rec.p_put_price,
418 		p_out_rec.p_fx_fwd_rate, p_out_rec.p_nd1, p_out_rec.p_nd2,
419   		p_out_rec.p_nd1_a, p_out_rec.p_nd2_a);
420 
421   IF xtr_risk_debug_pkg.g_Debug THEN
422      xtr_risk_debug_pkg.dpop('FX_SPOT_RATE: ' || 'XTR_MM_FORMULAS.FX_GK_OPTION_PRICE_CV');
423   END IF;
424 END fx_gk_option_price_cv;
425 
426 --added by sankim 9/12/01
427 /*
428 FX_SPOT_RATE_CV (FUNCTION)Cover routine that calculates the FX Spot Rate for
429 bid and ask side of different currencies exchange.In order to make the cover
430 routine easier to be called from Java (middle tier) directly, the record type
431 is not used to encapsulate the arguments. Moreover, function is used instead of
432  procedure since function can be called from SQL.
433 Parameters
434 * p_RATE_CONTRA/BASE_BID/ASK = FX rate of the contra/base currency against USD
435 for bid/ask side (p_RATE_ CONTRA = Rate vs. USD Contra, p_RATE_ BASE = Rate vs.
436  USD Base). If the currency is USD then use the default rate (=1).
437 * p_CURRENCY_CONTRA/BASE = the currency for contra/base.
438  p_QUOTATION_BASIS_CONTRA/BASE indicates the quotation basis against USD for
439 the CONTRA /BASE side, 'C' for Commodity Unit Quote (=USDGBP) and 'B' for Base
440 Unit Quote (= GBPUSD) (Definitions are in FX Calculator HLD)
441 * Returned: p_SPOT_RATE (BID/ASK) = fair exchange rate of two different
442 currencies of side bid/ask.
443 */
444 FUNCTION FX_SPOT_RATE_CV( p_currency_contra IN VARCHAR2,
445 			  p_currency_base IN VARCHAR2,
446 			  p_rate_contra_bid IN NUMBER,
447 			  p_rate_contra_ask IN NUMBER,
448 			  p_rate_base_bid IN NUMBER,
449 			  p_rate_base_ask IN NUMBER,
450 			  p_quotation_basis_contra IN VARCHAR2,
451 			  p_quotation_basis_base IN VARCHAR2)
452 			  RETURN XTR_MD_NUM_TABLE IS
453   v_results_array XTR_MD_NUM_TABLE:=XTR_MD_NUM_TABLE();
454 BEGIN
455   v_results_array.extend;
456   v_results_array.extend;
457   if p_quotation_basis_contra = 'C' then
458     if p_quotation_basis_base = 'C' then
459       --base in commodity quotation basis, contra in commodity quotation basis
460       --bid
461       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_bid,p_rate_base_ask,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(1));
462       --ask
463       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_ask,p_rate_base_bid,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(2));
464     elsif p_quotation_basis_base = 'B' then
465     --base in commodity quotation basis, contra in base quotation basis
466       --bid
467       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_bid,p_rate_base_bid,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(1));
468       --ask
469       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_ask,p_rate_base_ask,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(2));
470     else
471       RAISE_APPLICATION_ERROR
472 	(-20001,'p_quotation_basis_base must be ''C'' or ''B''.');
473     end if;
474   elsif p_quotation_basis_contra = 'B' then
475     if p_quotation_basis_base = 'C' then
476     --base in base quotation basis, contra in commodity quotation basis
477       --bid
478       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_ask,p_rate_base_ask,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(1));
479       --ask
480       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_bid,p_rate_base_bid,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(2));
481     elsif p_quotation_basis_base = 'B' then
482     --base in base quotation basis, contra in base quotation basis
483       --bid
484       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_ask,p_rate_base_bid,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(1));
485       --ask
486       fx_spot_rate(p_currency_contra,p_currency_base,p_rate_contra_bid,p_rate_base_ask,p_quotation_basis_contra,p_quotation_basis_base,v_results_array(2));
487     else
488       RAISE_APPLICATION_ERROR
489 	(-20001,'p_quotation_basis_base must be ''C'' or ''B''.');
490     end if;
491   else
492     RAISE_APPLICATION_ERROR
493 	(-20001,'p_quotation_basis_contra must be ''C'' or ''B''.');
494   end if;
495   RETURN v_results_array;
496 END FX_SPOT_RATE_CV;
497 
498 --added by sankim 9/12/01
499 /*
500 FX_FORWARD_RATE_CV (FUNCTION)A cover routine that calculates the FX Forward
501 Rate for  exchange that has USD as the base.In order to make the cover routine
502 easier to be called from Java (middle tier) directly, the record type is not
503 used to encapsulate the arguments. Moreover, function is used instead of
504 procedure since function can be called from SQL.
505 Parameters
506 * p_SPOT_RATE_BASE_BID/ASK = fair exchange rate of between the base currency
507 against USD. If the base currency is USD, then the default value of 1 should be
508  used.
509 * p_SPOT_RATE_CONTRA_BID/ASK = fair exchange rate of between the contra
510 currency against USD. If the contra currency is USD, then the default value of
511  1 should be used.
512 * p_BASE_CURR_INT_RATE_BID/ASK = bid/ask risk free interest rate for the base
513 currency.  This parameter should be null if the base currency is USD.
514 * p_CONTRA_CURR_INT_RATE_BID/ASK = bid/ask risk free interest rate for the
515 contra currency.  This parameter should be null if the contra currency is USD.
516 * p_USD _CURR_INT_RATE = risk free interest rate for the USD.
517 * p_DAY_COUNT_BASE/CONTRA = number of days between the spot date and the
518 forward date. If the contra currency is USD, then p_DAY_COUNT_CONTRA should be
519 null, and vice versa in the case of base is USD.
520 * p_ANNUAL_BASIS_BASE/CONTRA = number of days in a year of which the
521 p_DAY_COUNT_BASE/CONTRA and the p_BASE/CONTRA_CURR_INT_RATE are based on. If
522 the contra currency is USD, then p_ANNUAL_BASIS_CONTRA should be null, and vice
523  versa in the case of base is USD.
524 * p_DAY_COUNT_USD = number of days between the spot date and the forward date.
525 = number of days in a year of which the p_DAY_COUNT_USD and the
526 p_USD _CURR_INT_RATE are based on.
527 * p_ANNUAL_BASIS_USD = number of days in a year of which the p_DAY_COUNT_USD
528 and the p_USD _CURR_INT_RATE are based on.
529 * p_CURRENCY_CONTRA/BASE = the currency for contra/base.
530 * p_QUOTATION_BASIS_CONTRA/BASE indicates the quotation basis against USD for
531 the CONTRA /BASE side, 'C' for Commodity Unit Quote (=USDGBP) and 'B' for Base
532 Unit Quote (= GBPUSD) (Definitions are in FX Calculator HLD). This parameter is
533  required if base/contra is non-USD accordingly.
534 * Returned: p_FORWARD_RATE (BID/ASK) indicates the bid/ask side of forward rate
535  results.
536 */
537 FUNCTION FX_FORWARD_RATE_CV( p_spot_rate_base_bid IN NUMBER,
538 			     p_spot_rate_base_ask IN NUMBER,
539 			     p_spot_rate_contra_bid IN NUMBER,
540 			     p_spot_rate_contra_ask IN NUMBER,
541       			     p_base_curr_int_rate_bid IN NUMBER,
542 			     p_base_curr_int_rate_ask IN NUMBER,
543 			     p_contra_curr_int_rate_bid IN NUMBER,
544 			     p_contra_curr_int_rate_ask IN NUMBER,
545  			     p_usd_curr_int_rate_bid IN NUMBER,
546 			     p_usd_curr_int_rate_ask IN NUMBER,
547  			     p_day_count_base IN NUMBER,
548 			     p_day_count_contra IN NUMBER,
549 			     p_day_count_usd IN NUMBER,
550 			     p_annual_basis_base IN NUMBER,
551 			     p_annual_basis_contra IN NUMBER,
552 			     p_annual_basis_usd IN NUMBER,
553 			     p_currency_base IN VARCHAR2,
554 			     p_currency_contra IN VARCHAR2,
555 			     p_quotation_basis_base IN VARCHAR2,
556 			     p_quotation_basis_contra IN VARCHAR2)
557 			     RETURN XTR_MD_NUM_TABLE IS
558   v_results_array XTR_MD_NUM_TABLE:=XTR_MD_NUM_TABLE();
559   v_forward_rate_base_bid NUMBER;
560   v_forward_rate_base_ask NUMBER;
561   v_forward_rate_contra_bid NUMBER;
562   v_forward_rate_contra_ask NUMBER;
563 BEGIN
564 IF xtr_risk_debug_pkg.g_Debug THEN
565    xtr_risk_debug_pkg.dpush('FX_FORWARD_RATE_CV: ' || 'XTR_FORWARD_RATE_CV');
566 END IF;
567 if (p_currency_base <> 'USD') AND (p_currency_contra <> 'USD') THEN
568  --if cross currency is involved
569  -- calculate forward rates for base currency first
570   if p_quotation_basis_base = 'C' then
571     IF xtr_risk_debug_pkg.g_Debug THEN
572        xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'right base bid');
573     END IF;
574     --bid
575     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_bid, p_usd_curr_int_rate_ask, p_base_curr_int_rate_bid, p_day_count_usd, p_day_count_base, p_annual_basis_usd, p_annual_basis_base, v_forward_rate_base_bid);
576     --ask
577     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_ask, p_usd_curr_int_rate_bid, p_base_curr_int_rate_ask, p_day_count_usd, p_day_count_base, p_annual_basis_usd, p_annual_basis_base, v_forward_rate_base_ask);
578   elsif p_quotation_basis_base = 'B' then
579     --bid
580     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_bid, p_base_curr_int_rate_ask, p_usd_curr_int_rate_bid, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_forward_rate_base_bid);
581     --ask
582     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_ask, p_base_curr_int_rate_bid, p_usd_curr_int_rate_ask, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_forward_rate_base_ask);
583   else
584     RAISE_APPLICATION_ERROR
585 	(-20001,'p_quotation_basis_base must be ''C'' or ''B''.');
586   end if;
587   IF xtr_risk_debug_pkg.g_Debug THEN
588      xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'contra quotation basis',p_quotation_basis_contra);
589   END IF;
590   --now calculate forward rates for contra currency
591   if p_quotation_basis_contra = 'C' then
592     IF xtr_risk_debug_pkg.g_Debug THEN
593        xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'wrong contra bid');
594     END IF;
595     --bid
596     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_bid, p_usd_curr_int_rate_ask, p_contra_curr_int_rate_bid, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_forward_rate_contra_bid);
597     --ask
598     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_ask, p_usd_curr_int_rate_bid, p_contra_curr_int_rate_ask, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_forward_rate_contra_ask);
599   elsif p_quotation_basis_contra = 'B' then
600     IF xtr_risk_debug_pkg.g_Debug THEN
601        xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'right contra bid');
602     END IF;
603     --bid
604     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_bid, p_contra_curr_int_rate_ask, p_usd_curr_int_rate_bid, p_day_count_contra, p_day_count_usd, p_annual_basis_contra, p_annual_basis_usd, v_forward_rate_contra_bid);
605     --ask
606     XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_ask, p_contra_curr_int_rate_bid, p_usd_curr_int_rate_ask, p_day_count_contra, p_day_count_usd, p_annual_basis_contra, p_annual_basis_usd, v_forward_rate_contra_ask);
607   else
608     RAISE_APPLICATION_ERROR
609 	(-20001,'p_quotation_basis_base must be ''C'' or ''B''.');
610   end if;
611   -- calculate cross rate
612   IF xtr_risk_debug_pkg.g_Debug THEN
613      xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'base fwd bid',v_forward_rate_base_bid);
614      xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'base fwd ask',v_forward_rate_base_ask);
615      xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'contra fwd bid',v_forward_rate_contra_bid);
616      xtr_risk_debug_pkg.dlog('FX_FORWARD_RATE_CV: ' || 'contra fwd ask',v_forward_rate_contra_ask);
617   END IF;
618   return XTR_FX_FORMULAS.fx_spot_rate_cv(p_currency_contra,p_currency_base,v_forward_rate_contra_bid,v_forward_rate_contra_ask,v_forward_rate_base_bid,v_forward_rate_base_ask,p_quotation_basis_contra,p_quotation_basis_base);
619 else
620 --simpler case where there is no cross currency involved
621   if (p_currency_base = 'USD') THEN --USD is base
622     v_results_array.extend;
623     v_results_array.extend;
624     if p_quotation_basis_contra = 'C' then
625     -- calculate bid forward rate
626       XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_bid, p_usd_curr_int_rate_ask, p_contra_curr_int_rate_bid, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_results_array(1));
627     --now ask
628       XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_contra_ask, p_usd_curr_int_rate_bid, p_contra_curr_int_rate_ask, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_results_array(2));
629       RETURN v_results_array;
630     elsif  p_quotation_basis_contra = 'B' then
631     -- calculate bid forward rate
632       XTR_FX_FORMULAS.fx_forward_rate(1/p_spot_rate_contra_ask, p_usd_curr_int_rate_ask, p_contra_curr_int_rate_bid, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_results_array(1));
633     --now ask
634       XTR_FX_FORMULAS.fx_forward_rate(1/p_spot_rate_contra_bid, p_usd_curr_int_rate_bid, p_contra_curr_int_rate_ask, p_day_count_usd, p_day_count_contra, p_annual_basis_usd, p_annual_basis_contra, v_results_array(2));
635       RETURN v_results_array;
636     else
637       RAISE_APPLICATION_ERROR
638 	(-20001,'p_quotation_basis_contra must be ''C'' or ''B''.');
639   end if;
640   else  --USD is contra
641     v_results_array.extend;
642     v_results_array.extend;
643     if p_quotation_basis_base = 'B' then
644       -- calculate bid forward rate
645       XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_bid, p_base_curr_int_rate_ask, p_usd_curr_int_rate_bid, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_results_array(1));
646       -- calculate ask forward rate
647       XTR_FX_FORMULAS.fx_forward_rate(p_spot_rate_base_ask, p_base_curr_int_rate_bid, p_usd_curr_int_rate_ask, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_results_array(2));
648       RETURN v_results_array;
649     elsif  p_quotation_basis_base = 'C' then
650       -- calculate bid forward rate
651       XTR_FX_FORMULAS.fx_forward_rate(1/p_spot_rate_base_ask, p_base_curr_int_rate_ask, p_usd_curr_int_rate_bid, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_results_array(1));
652       -- calculate ask forward rate
653       XTR_FX_FORMULAS.fx_forward_rate(1/p_spot_rate_base_bid, p_base_curr_int_rate_bid, p_usd_curr_int_rate_ask, p_day_count_base, p_day_count_usd, p_annual_basis_base, p_annual_basis_usd, v_results_array(2));
654       RETURN v_results_array;
655     else
656       RAISE_APPLICATION_ERROR
657 	(-20001,'p_quotation_basis_base must be ''C'' or ''B''.');
658     end if;
659 
660   end if;
661 end if;
662 IF xtr_risk_debug_pkg.g_Debug THEN
663    xtr_risk_debug_pkg.dpop('FX_FORWARD_RATE_CV: ' || 'XTR_FORWARD_RATE_CV');
664 END IF;
665 END FX_FORWARD_RATE_CV;
666 
667 END XTR_FX_FORMULAS;