public virtual void test_parSpread() { double spread = PRICER.parSpread(FWD, PROVIDER); ResolvedFxSingle fwdSp = ResolvedFxSingle.of(CurrencyAmount.of(USD, NOMINAL_USD), FxRate.of(USD, KRW, FX_RATE + spread), PAYMENT_DATE); MultiCurrencyAmount pv = PRICER.presentValue(fwdSp, PROVIDER); assertEquals(pv.convertedTo(USD, PROVIDER).Amount, 0d, NOMINAL_USD * TOL); }
//------------------------------------------------------------------------- public virtual void test_parSpread_beforeStart() { double parSpread = PRICER.parSpread(SWAP_PRODUCT, PROVIDER); ResolvedFxSwap product = ResolvedFxSwap.ofForwardPoints(CurrencyAmount.of(USD, NOMINAL_USD), KRW, FX_RATE, FX_FWD_POINTS + parSpread, PAYMENT_DATE_NEAR, PAYMENT_DATE_FAR); MultiCurrencyAmount pv = PRICER.presentValue(product, PROVIDER); assertEquals(pv.convertedTo(USD, PROVIDER).Amount, 0d, NOMINAL_USD * TOL); }
//------------------------------------------------------------------------- public virtual void test_currencyExposure() { CurrencyAmount pv = PRICER.presentValue(NDF, PROVIDER); MultiCurrencyAmount ce = PRICER.currencyExposure(NDF, PROVIDER); CurrencyAmount ceConverted = ce.convertedTo(pv.Currency, PROVIDER); assertEquals(pv.Amount, ceConverted.Amount, NOMINAL_USD * TOL); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the par spread. /// <para> /// The par spread is the spread that should be added to the FX forward points to have a zero value. /// /// </para> /// </summary> /// <param name="swap"> the product </param> /// <param name="provider"> the rates provider </param> /// <returns> the spread </returns> public virtual double parSpread(ResolvedFxSwap swap, RatesProvider provider) { Payment counterPaymentNear = swap.NearLeg.CounterCurrencyPayment; MultiCurrencyAmount pv = presentValue(swap, provider); double pvCounterCcy = pv.convertedTo(counterPaymentNear.Currency, provider).Amount; double dfEnd = provider.discountFactor(counterPaymentNear.Currency, swap.FarLeg.PaymentDate); double notionalBaseCcy = swap.NearLeg.BaseCurrencyPayment.Amount; return(-pvCounterCcy / (notionalBaseCcy * dfEnd)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the par spread. /// <para> /// This is the spread that should be added to the FX points to have a zero value. /// /// </para> /// </summary> /// <param name="fx"> the product </param> /// <param name="provider"> the rates provider </param> /// <returns> the spread </returns> public virtual double parSpread(ResolvedFxSingle fx, RatesProvider provider) { Payment basePayment = fx.BaseCurrencyPayment; Payment counterPayment = fx.CounterCurrencyPayment; MultiCurrencyAmount pv = presentValue(fx, provider); double pvCounterCcy = pv.convertedTo(counterPayment.Currency, provider).Amount; double dfEnd = provider.discountFactor(counterPayment.Currency, fx.PaymentDate); double notionalBaseCcy = basePayment.Amount; return(pvCounterCcy / (notionalBaseCcy * dfEnd)); }
/// <summary> /// Calculates the par spread sensitivity to the curves. /// <para> /// The sensitivity is reported in the counter currency of the product, but is actually dimensionless. /// /// </para> /// </summary> /// <param name="swap"> the product </param> /// <param name="provider"> the rates provider </param> /// <returns> the spread curve sensitivity </returns> public virtual PointSensitivities parSpreadSensitivity(ResolvedFxSwap swap, RatesProvider provider) { Payment counterPaymentNear = swap.NearLeg.CounterCurrencyPayment; MultiCurrencyAmount pv = presentValue(swap, provider); double pvCounterCcy = pv.convertedTo(counterPaymentNear.Currency, provider).Amount; double dfEnd = provider.discountFactor(counterPaymentNear.Currency, swap.FarLeg.PaymentDate); double notionalBaseCcy = swap.NearLeg.BaseCurrencyPayment.Amount; double ps = -pvCounterCcy / (notionalBaseCcy * dfEnd); // backward sweep double psBar = 1d; double pvCounterCcyBar = -1d / (notionalBaseCcy * dfEnd) * psBar; double dfEndBar = -ps / dfEnd * psBar; ZeroRateSensitivity ddfEnddr = provider.discountFactors(counterPaymentNear.Currency).zeroRatePointSensitivity(swap.FarLeg.PaymentDate); PointSensitivities result = ddfEnddr.multipliedBy(dfEndBar).build(); PointSensitivities dpvdr = presentValueSensitivity(swap, provider); PointSensitivities dpvdrConverted = dpvdr.convertedTo(counterPaymentNear.Currency, provider); return(result.combinedWith(dpvdrConverted.multipliedBy(pvCounterCcyBar))); }