@Override public double presentValue(RatePaymentPeriod period, RatesProvider provider) { // forecastValue * discountFactor double df = provider.discountFactor(period.getCurrency(), period.getPaymentDate()); return forecastValue(period, provider) * df; }
@Override public double currentCash(RatePaymentPeriod period, RatesProvider provider) { if (provider.getValuationDate().isEqual(period.getPaymentDate())) { return forecastValue(period, provider); } return 0d; }
public void test_currentCash_onPayment() { DiscountingRatePaymentPeriodPricer pricer = DiscountingRatePaymentPeriodPricer.DEFAULT; RatesProvider provider = createProvider(PAYMENT_PERIOD_1.getPaymentDate()); double computed = pricer.currentCash(PAYMENT_PERIOD_1, provider); assertEquals(computed, RATE_1 * ACCRUAL_FACTOR_1 * NOTIONAL_100); }
private double pvbpCompoundedFlat(RatePaymentPeriod paymentPeriod, RatesProvider provider) { int nbCmp = paymentPeriod.getAccrualPeriods().size(); double[] rate = paymentPeriod.getAccrualPeriods().stream() .mapToDouble(ap -> rawRate(ap, provider)) .toArray(); double df = provider.discountFactor(paymentPeriod.getCurrency(), paymentPeriod.getPaymentDate()); double rBar = 1.0; double[] cpaAccumulatedBar = new double[nbCmp + 1]; cpaAccumulatedBar[nbCmp] = paymentPeriod.getNotional() * df * rBar; double spreadBar = 0.0d; for (int j = nbCmp - 1; j >= 0; j--) { cpaAccumulatedBar[j] = (1.0d + paymentPeriod.getAccrualPeriods().get(j).getYearFraction() * rate[j] * paymentPeriod.getAccrualPeriods().get(j).getGearing()) * cpaAccumulatedBar[j + 1]; spreadBar += paymentPeriod.getAccrualPeriods().get(j).getYearFraction() * cpaAccumulatedBar[j + 1]; } return spreadBar; }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(RatePaymentPeriod beanToCopy) { this.paymentDate = beanToCopy.getPaymentDate(); this.accrualPeriods = beanToCopy.getAccrualPeriods(); this.dayCount = beanToCopy.getDayCount(); this.currency = beanToCopy.getCurrency(); this.fxReset = beanToCopy.fxReset; this.notional = beanToCopy.getNotional(); this.compoundingMethod = beanToCopy.getCompoundingMethod(); }
public void test_pvbp_onePeriod() { RatesProvider mockProv = mock(RatesProvider.class); double df = 0.99d; when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate())) .thenReturn(df); double expected = df * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getNotional() * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getAccrualPeriods().get(0).getYearFraction(); DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT; assertEquals(test.pvbp(FIXED_SWAP_LEG_PAY_USD, mockProv), expected, TOLERANCE); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case -1540873516: // paymentDate return ((RatePaymentPeriod) bean).getPaymentDate(); case -92208605: // accrualPeriods return ((RatePaymentPeriod) bean).getAccrualPeriods(); case 1905311443: // dayCount return ((RatePaymentPeriod) bean).getDayCount(); case 575402001: // currency return ((RatePaymentPeriod) bean).getCurrency(); case -449555555: // fxReset return ((RatePaymentPeriod) bean).fxReset; case 1585636160: // notional return ((RatePaymentPeriod) bean).getNotional(); case -1376171496: // compoundingMethod return ((RatePaymentPeriod) bean).getCompoundingMethod(); } return super.propertyGet(bean, propertyName, quiet); }
@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"); } } }
public void test_couponEquivalent_twoPeriods() { ResolvedSwapLeg leg = ResolvedSwapLeg.builder() .type(FIXED) .payReceive(PAY) .paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2) .build(); RatesProvider mockProv = mock(RatesProvider.class); double df1 = 0.99d; when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate())) .thenReturn(df1); double df2 = 0.98d; when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getPaymentDate())) .thenReturn(df2); when(mockProv.getValuationDate()).thenReturn(RatesProviderDataSets.VAL_DATE_2014_01_22); double pvbp = PRICER_LEG.pvbp(leg, mockProv); double ceExpected = PRICER_LEG.presentValuePeriodsInternal(leg, mockProv) / pvbp; double ceComputed = PRICER_LEG.couponEquivalent(leg, mockProv, pvbp); assertEquals(ceComputed, ceExpected, TOLERANCE); }
@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"); } } }
private void assertFixedPaymentPeriod( ResolvedSwapLeg expandedPayLeg, int index, String paymentDateStr, String startDateStr, String endDateStr, double notional, double rate) { RatePaymentPeriod pp = (RatePaymentPeriod) expandedPayLeg.getPaymentPeriods().get(index); assertEquals(pp.getPaymentDate().toString(), paymentDateStr); assertEquals(Math.abs(pp.getNotional()), notional); assertEquals(pp.getAccrualPeriods().size(), 1); RateAccrualPeriod ap = pp.getAccrualPeriods().get(0); assertEquals(ap.getStartDate().toString(), startDateStr); assertEquals(ap.getEndDate().toString(), endDateStr); if (ap.getRateComputation() instanceof FixedRateComputation) { assertEquals(((FixedRateComputation) ap.getRateComputation()).getRate(), rate); } else { fail(); } }
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_pvbp_twoPeriods() { ResolvedSwapLeg leg = ResolvedSwapLeg.builder() .type(FIXED) .payReceive(PAY) .paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2) .build(); RatesProvider mockProv = mock(RatesProvider.class); double df1 = 0.99d; when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate())) .thenReturn(df1); double df2 = 0.98d; when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getPaymentDate())) .thenReturn(df2); double expected = df1 * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getNotional() * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getAccrualPeriods().get(0).getYearFraction(); expected += df2 * FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getNotional() * FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getAccrualPeriods().get(0).getYearFraction(); DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT; assertEquals(test.pvbp(leg, mockProv), expected, TOLERANCE); }
public void test_explainPresentValue_single_paymentDateInPast() { SimpleRatesProvider prov = createProvider(VAL_DATE); prov.setValuationDate(VAL_DATE.plusYears(1)); DiscountingRatePaymentPeriodPricer test = DiscountingRatePaymentPeriodPricer.DEFAULT; ExplainMapBuilder builder = ExplainMap.builder(); test.explainPresentValue(PAYMENT_PERIOD_1, prov, builder); ExplainMap explain = builder.build(); Currency currency = PAYMENT_PERIOD_1.getCurrency(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "RatePaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD_1.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), currency); assertEquals(explain.get(ExplainKey.NOTIONAL).get().getCurrency(), currency); assertEquals(explain.get(ExplainKey.NOTIONAL).get().getAmount(), NOTIONAL_100, TOLERANCE_PV); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().getCurrency(), currency); assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().getAmount(), NOTIONAL_100, TOLERANCE_PV); assertEquals(explain.get(ExplainKey.COMPLETED).get(), Boolean.TRUE); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getCurrency(), currency); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), 0d, TOLERANCE_PV); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getCurrency(), currency); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), 0d, TOLERANCE_PV); }
@Override public PointSensitivityBuilder presentValueSensitivity(RatePaymentPeriod period, RatesProvider provider) { Currency ccy = period.getCurrency(); DiscountFactors discountFactors = provider.discountFactors(ccy); LocalDate paymentDate = period.getPaymentDate(); double df = discountFactors.discountFactor(paymentDate); PointSensitivityBuilder forecastSensitivity = forecastValueSensitivity(period, provider); forecastSensitivity = forecastSensitivity.multipliedBy(df); double forecastValue = forecastValue(period, provider); PointSensitivityBuilder dscSensitivity = discountFactors.zeroRatePointSensitivity(paymentDate); dscSensitivity = dscSensitivity.multipliedBy(forecastValue); return forecastSensitivity.combinedWith(dscSensitivity); }
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); }
private void assertIborPaymentPeriod( ResolvedSwapLeg expandedPayLeg, int index, String paymentDateStr, String startDateStr, String endDateStr, double notional, String fixingDateStr) { RatePaymentPeriod pp = (RatePaymentPeriod) expandedPayLeg.getPaymentPeriods().get(index); assertEquals(pp.getPaymentDate().toString(), paymentDateStr); assertEquals(Math.abs(pp.getNotional()), notional); assertEquals(pp.getAccrualPeriods().size(), 1); RateAccrualPeriod ap = pp.getAccrualPeriods().get(0); assertEquals(ap.getStartDate().toString(), startDateStr); assertEquals(ap.getEndDate().toString(), endDateStr); if (ap.getRateComputation() instanceof IborInterpolatedRateComputation) { assertEquals(((IborInterpolatedRateComputation) ap.getRateComputation()).getFixingDate().toString(), fixingDateStr); } else if (ap.getRateComputation() instanceof IborRateComputation) { assertEquals(((IborRateComputation) ap.getRateComputation()).getFixingDate().toString(), fixingDateStr); } else { fail(); } }
@Override public PointSensitivityBuilder forecastValueSensitivity(RatePaymentPeriod period, RatesProvider provider) { // historic payments have zero sensi if (period.getPaymentDate().isBefore(provider.getValuationDate())) { return PointSensitivityBuilder.none(); } PointSensitivityBuilder sensiFx = fxRateSensitivity(period, provider); double accrual = accrualWithNotional(period, period.getNotional(), provider); sensiFx = sensiFx.multipliedBy(accrual); PointSensitivityBuilder sensiAccrual = PointSensitivityBuilder.none(); if (period.isCompoundingApplicable()) { sensiAccrual = accrueCompoundedSensitivity(period, provider); } else { sensiAccrual = unitNotionalSensitivityNoCompounding(period, provider); } double notional = period.getNotional() * fxRate(period, provider); sensiAccrual = sensiAccrual.multipliedBy(notional); return sensiFx.combinedWith(sensiAccrual); }
@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)); }