// resolve the FX rate sensitivity from the FX reset private PointSensitivityBuilder fxRateSensitivity(RatePaymentPeriod paymentPeriod, RatesProvider provider) { if (paymentPeriod.FxReset.Present) { FxReset fxReset = paymentPeriod.FxReset.get(); FxIndexRates rates = provider.fxIndexRates(fxReset.Observation.Index); return(rates.ratePointSensitivity(fxReset.Observation, fxReset.ReferenceCurrency)); } return(PointSensitivityBuilder.none()); }
//------------------------------------------------------------------------- // resolve the FX rate from the FX reset, returning an FX rate of 1 if not applicable private double fxRate(RatePaymentPeriod paymentPeriod, RatesProvider provider) { // inefficient to use Optional.orElse because double primitive type would be boxed if (paymentPeriod.FxReset.Present) { FxReset fxReset = paymentPeriod.FxReset.get(); FxIndexRates rates = provider.fxIndexRates(fxReset.Observation.Index); return(rates.rate(fxReset.Observation, fxReset.ReferenceCurrency)); } else { return(1d); } }
//------------------------------------------------------------------------- public virtual MultiCurrencyAmount currencyExposure(RatePaymentPeriod period, RatesProvider provider) { double df = provider.discountFactor(period.Currency, period.PaymentDate); if (period.FxReset.Present) { FxReset fxReset = period.FxReset.get(); LocalDate fixingDate = fxReset.Observation.FixingDate; FxIndexRates rates = provider.fxIndexRates(fxReset.Observation.Index); if (!fixingDate.isAfter(provider.ValuationDate) && rates.Fixings.get(fixingDate).HasValue) { double fxRate = rates.rate(fxReset.Observation, fxReset.ReferenceCurrency); return(MultiCurrencyAmount.of(period.Currency, accrualWithNotional(period, period.Notional * fxRate * df, provider))); } double fxRateSpotSensitivity = rates.FxForwardRates.rateFxSpotSensitivity(fxReset.ReferenceCurrency, fxReset.Observation.MaturityDate); return(MultiCurrencyAmount.of(fxReset.ReferenceCurrency, accrualWithNotional(period, period.Notional * fxRateSpotSensitivity * df, provider))); } return(MultiCurrencyAmount.of(period.Currency, accrualWithNotional(period, period.Notional * df, provider))); }
public virtual void currency_exposure_USD() { LocalDate startDate = LocalDate.of(2016, 8, 2); LocalDate fixingDate = LocalDate.of(2016, 11, 2); LocalDate endDate = LocalDate.of(2016, 11, 4); double yearFraction = 0.25; double rate = 0.10; RateAccrualPeriod accrual = RateAccrualPeriod.builder().startDate(startDate).endDate(endDate).yearFraction(yearFraction).rateComputation(FixedRateComputation.of(rate)).build(); double notional = 1000000; RatePaymentPeriod fixedFx = RatePaymentPeriod.builder().accrualPeriods(accrual).fxReset(FxReset.of(FxIndexObservation.of(FxIndices.GBP_USD_WM, fixingDate, REF_DATA), USD)).notional(notional).paymentDate(endDate).dayCount(DayCounts.ONE_ONE).currency(GBP).build(); // 1_000_000 USD paid in GBP at maturity PointSensitivityBuilder pts = PERIOD_PRICER.presentValueSensitivity(fixedFx, PROVIDER); MultiCurrencyAmount ceComputed = PERIOD_PRICER.currencyExposure(fixedFx, PROVIDER); double dfUsd = PROVIDER.discountFactor(USD, endDate); double ceUsdExpected = notional * yearFraction * rate * dfUsd; assertEquals(ceComputed.getAmount(USD).Amount, ceUsdExpected, 1.0E-6); MultiCurrencyAmount ceWithoutPvComputed = PROVIDER.currencyExposure(pts.build().convertedTo(USD, PROVIDER)); CurrencyAmount pvComputed = CurrencyAmount.of(GBP, PERIOD_PRICER.presentValue(fixedFx, PROVIDER)); MultiCurrencyAmount ceComputed2 = ceWithoutPvComputed.plus(pvComputed); assertEquals(ceComputed2.getAmount(USD).Amount, ceUsdExpected, TOLERANCE); assertEquals(ceComputed2.getAmount(GBP).Amount, 0.0, TOLERANCE); }