@Override public Optional<FxIndexObservation> getFxResetObservation() { return getFxReset().map(fxr -> fxr.getObservation()); }
@Override public void collectIndices(ImmutableSet.Builder<Index> builder) { accrualPeriods.stream().forEach(accrual -> accrual.getRateComputation().collectIndices(builder)); getFxReset().ifPresent(fxReset -> builder.add(fxReset.getIndex())); }
@Override public void collectCurrencies(ImmutableSet.Builder<Currency> builder) { builder.add(currency); for (RatePaymentPeriod paymentPeriod : paymentPeriods) { builder.add(paymentPeriod.getCurrency()); paymentPeriod.getFxReset().ifPresent(fxr -> builder.add(fxr.getReferenceCurrency())); } paymentEvents.forEach(ev -> builder.add(ev.getCurrency())); }
private double fxRate(RatePaymentPeriod paymentPeriod, RatesProvider provider) { // inefficient to use Optional.orElse because double primitive type would be boxed if (paymentPeriod.getFxReset().isPresent()) { FxReset fxReset = paymentPeriod.getFxReset().get(); FxIndexRates rates = provider.fxIndexRates(fxReset.getObservation().getIndex()); return rates.rate(fxReset.getObservation(), fxReset.getReferenceCurrency()); } else { return 1d; } }
private PointSensitivityBuilder fxRateSensitivity(RatePaymentPeriod paymentPeriod, RatesProvider provider) { if (paymentPeriod.getFxReset().isPresent()) { FxReset fxReset = paymentPeriod.getFxReset().get(); FxIndexRates rates = provider.fxIndexRates(fxReset.getObservation().getIndex()); return rates.ratePointSensitivity(fxReset.getObservation(), fxReset.getReferenceCurrency()); } return PointSensitivityBuilder.none(); }
@Override public double pvbp(RatePaymentPeriod paymentPeriod, RatesProvider provider) { ArgChecker.isTrue(!paymentPeriod.getFxReset().isPresent(), "FX reset is not supported"); int accPeriodCount = paymentPeriod.getAccrualPeriods().size(); ArgChecker.isTrue(accPeriodCount == 1 || paymentPeriod.getCompoundingMethod().equals(CompoundingMethod.FLAT), "Only one accrued period or Flat compounding supported"); // no compounding if (accPeriodCount == 1) { RateAccrualPeriod accrualPeriod = paymentPeriod.getAccrualPeriods().get(0); double df = provider.discountFactor(paymentPeriod.getCurrency(), paymentPeriod.getPaymentDate()); return df * accrualPeriod.getYearFraction() * paymentPeriod.getNotional(); } else { // Flat compounding switch (paymentPeriod.getCompoundingMethod()) { case FLAT: return pvbpCompoundedFlat(paymentPeriod, provider); default: throw new UnsupportedOperationException("PVBP not implemented yet for non FLAT compounding"); } } }
@Override public PointSensitivityBuilder pvbpSensitivity(RatePaymentPeriod paymentPeriod, RatesProvider provider) { ArgChecker.isTrue(!paymentPeriod.getFxReset().isPresent(), "FX reset is not supported"); int accPeriodCount = paymentPeriod.getAccrualPeriods().size(); ArgChecker.isTrue(accPeriodCount == 1 || paymentPeriod.getCompoundingMethod().equals(CompoundingMethod.FLAT), "Only one accrued period or Flat compounding supported"); // no compounding if (accPeriodCount == 1) { RateAccrualPeriod accrualPeriod = paymentPeriod.getAccrualPeriods().get(0); DiscountFactors discountFactors = provider.discountFactors(paymentPeriod.getCurrency()); return discountFactors.zeroRatePointSensitivity(paymentPeriod.getPaymentDate()) .multipliedBy(accrualPeriod.getYearFraction() * paymentPeriod.getNotional()); } else { // Flat compounding switch (paymentPeriod.getCompoundingMethod()) { case FLAT: return pvbpSensitivtyCompoundedFlat(paymentPeriod, provider); default: throw new UnsupportedOperationException("PVBP not implemented yet for non FLAT compounding"); } } }
public void test_builder_twoAccrualPeriods() { RatePaymentPeriod test = RatePaymentPeriod.builder() .paymentDate(DATE_2014_10_01) .accrualPeriods(RAP1, RAP2) .dayCount(ACT_365F) .currency(GBP) .notional(1000d) .compoundingMethod(CompoundingMethod.STRAIGHT) .build(); assertEquals(test.getStartDate(), DATE_2014_03_30); assertEquals(test.getEndDate(), DATE_2014_09_30); assertEquals(test.getPaymentDate(), DATE_2014_10_01); assertEquals(test.getAccrualPeriods(), ImmutableList.of(RAP1, RAP2)); assertEquals(test.getCurrency(), GBP); assertEquals(test.getFxReset(), Optional.empty()); assertEquals(test.getNotional(), 1000d, 0d); assertEquals(test.getCompoundingMethod(), CompoundingMethod.STRAIGHT); assertEquals(test.isCompoundingApplicable(), true); }
public void test_builder_oneAccrualPeriod() { RatePaymentPeriod test = RatePaymentPeriod.builder() .paymentDate(DATE_2014_10_01) .accrualPeriods(RAP2) .dayCount(ACT_365F) .currency(GBP) .notional(1000d) .compoundingMethod(CompoundingMethod.STRAIGHT) .build(); assertEquals(test.getStartDate(), DATE_2014_06_30); assertEquals(test.getEndDate(), DATE_2014_09_30); assertEquals(test.getPaymentDate(), DATE_2014_10_01); assertEquals(test.getAccrualPeriods(), ImmutableList.of(RAP2)); assertEquals(test.getCurrency(), GBP); assertEquals(test.getFxReset(), Optional.empty()); assertEquals(test.getNotional(), 1000d, 0d); assertEquals(test.getNotionalAmount(), CurrencyAmount.of(GBP, 1000d)); assertEquals(test.getCompoundingMethod(), CompoundingMethod.STRAIGHT); assertEquals(test.isCompoundingApplicable(), false); }
public void test_builder_twoAccrualPeriods_compoundingDefaultedToNone_fxReset() { RatePaymentPeriod test = RatePaymentPeriod.builder() .paymentDate(DATE_2014_10_01) .accrualPeriods(RAP1, RAP2) .dayCount(ACT_365F) .currency(GBP) .fxReset(FX_RESET_USD) .notional(1000d) .compoundingMethod(CompoundingMethod.NONE) .build(); assertEquals(test.getStartDate(), DATE_2014_03_30); assertEquals(test.getEndDate(), DATE_2014_09_30); assertEquals(test.getPaymentDate(), DATE_2014_10_01); assertEquals(test.getAccrualPeriods(), ImmutableList.of(RAP1, RAP2)); assertEquals(test.getCurrency(), GBP); assertEquals(test.getFxReset(), Optional.of(FX_RESET_USD)); assertEquals(test.getNotional(), 1000d, 0d); assertEquals(test.getNotionalAmount(), CurrencyAmount.of(USD, 1000d)); assertEquals(test.isCompoundingApplicable(), false); }
ExplainMap explain = builder.build(); FxReset fxReset = PAYMENT_PERIOD_1_FX.getFxReset().get(); Currency currency = PAYMENT_PERIOD_1_FX.getCurrency(); Currency referenceCurrency = fxReset.getReferenceCurrency();
@Override public MultiCurrencyAmount currencyExposure(RatePaymentPeriod period, RatesProvider provider) { double df = provider.discountFactor(period.getCurrency(), period.getPaymentDate()); if (period.getFxReset().isPresent()) { FxReset fxReset = period.getFxReset().get(); LocalDate fixingDate = fxReset.getObservation().getFixingDate(); FxIndexRates rates = provider.fxIndexRates(fxReset.getObservation().getIndex()); if (!fixingDate.isAfter(provider.getValuationDate()) && rates.getFixings().get(fixingDate).isPresent()) { double fxRate = rates.rate(fxReset.getObservation(), fxReset.getReferenceCurrency()); return MultiCurrencyAmount.of(period.getCurrency(), accrualWithNotional(period, period.getNotional() * fxRate * df, provider)); } double fxRateSpotSensitivity = rates.getFxForwardRates() .rateFxSpotSensitivity(fxReset.getReferenceCurrency(), fxReset.getObservation().getMaturityDate()); return MultiCurrencyAmount.of(fxReset.getReferenceCurrency(), accrualWithNotional(period, period.getNotional() * fxRateSpotSensitivity * df, provider)); } return MultiCurrencyAmount.of(period.getCurrency(), accrualWithNotional(period, period.getNotional() * df, provider)); }
builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { paymentPeriod.getFxReset().ifPresent(fxReset -> { builder.addListEntry(ExplainKey.OBSERVATIONS, child -> { child.put(ExplainKey.ENTRY_TYPE, "FxObservation");