/** * Computes the conventional cash annuity from a swap leg. * <p> * The computation is relevant only for standard swaps with constant notional and regular payments. * The swap leg must be a fixed leg. However, this is not checked internally. * * @param fixedLeg the fixed leg of the swap * @param yield the yield * @return the cash annuity */ public double annuityCash(ResolvedSwapLeg fixedLeg, double yield) { int nbFixedPeriod = fixedLeg.getPaymentPeriods().size(); SwapPaymentPeriod paymentPeriod = fixedLeg.getPaymentPeriods().get(0); ArgChecker.isTrue(paymentPeriod instanceof RatePaymentPeriod, "payment period should be RatePaymentPeriod"); RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod) paymentPeriod; int nbFixedPaymentYear = (int) Math.round(1d / ratePaymentPeriod.getDayCount().yearFraction(ratePaymentPeriod.getStartDate(), ratePaymentPeriod.getEndDate())); double notional = Math.abs(ratePaymentPeriod.getNotional()); double annuityCash = notional * annuityCash(nbFixedPaymentYear, nbFixedPeriod, yield); return annuityCash; }
/** * 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(); }
@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); }
/** * Computes the derivative of the conventional cash annuity with respect to the yield from a swap leg. * <p> * The computation is relevant only for standard swaps with constant notional and regular payments. * The swap leg must be a fixed leg. However, this is not checked internally. * * @param fixedLeg the fixed leg of the swap * @param yield the yield * @return the cash annuity */ public ValueDerivatives annuityCashDerivative(ResolvedSwapLeg fixedLeg, double yield) { int nbFixedPeriod = fixedLeg.getPaymentPeriods().size(); SwapPaymentPeriod paymentPeriod = fixedLeg.getPaymentPeriods().get(0); ArgChecker.isTrue(paymentPeriod instanceof RatePaymentPeriod, "payment period should be RatePaymentPeriod"); RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod) paymentPeriod; int nbFixedPaymentYear = (int) Math.round(1d / ratePaymentPeriod.getDayCount().yearFraction(ratePaymentPeriod.getStartDate(), ratePaymentPeriod.getEndDate())); double notional = Math.abs(ratePaymentPeriod.getNotional()); ValueDerivatives annuityUnit = annuityCash1(nbFixedPaymentYear, nbFixedPeriod, yield); return ValueDerivatives.of(annuityUnit.getValue() * notional, annuityUnit.getDerivatives().multipliedBy(notional)); }
public void test_accruedInterest_firstAccrualPeriod() { LocalDate valDate = PAYMENT_PERIOD_FULL_GS.getStartDate().plusDays(7); SimpleRatesProvider prov = createProvider(valDate); double partial = PAYMENT_PERIOD_FULL_GS.getDayCount().yearFraction(ACCRUAL_PERIOD_1_GS.getStartDate(), valDate); double fraction = partial / ACCRUAL_FACTOR_1; double expected = ((RATE_1 * GEARING + SPREAD) * ACCRUAL_FACTOR_1 * NOTIONAL_100) * fraction; double computed = DiscountingRatePaymentPeriodPricer.DEFAULT.accruedInterest(PAYMENT_PERIOD_FULL_GS, prov); assertEquals(computed, expected, TOLERANCE_PV); }
public void test_accruedInterest_lastAccrualPeriod() { LocalDate valDate = PAYMENT_PERIOD_FULL_GS.getEndDate().minusDays(7); SimpleRatesProvider prov = createProvider(valDate); double partial = PAYMENT_PERIOD_FULL_GS.getDayCount().yearFraction(ACCRUAL_PERIOD_3_GS.getStartDate(), valDate); double fraction = partial / ACCRUAL_FACTOR_3; double expected = ((RATE_1 * GEARING + SPREAD) * ACCRUAL_FACTOR_1 * NOTIONAL_100) + ((RATE_2 * GEARING + SPREAD) * ACCRUAL_FACTOR_2 * NOTIONAL_100) + ((RATE_3 * GEARING + SPREAD) * ACCRUAL_FACTOR_3 * NOTIONAL_100 * fraction); double computed = DiscountingRatePaymentPeriodPricer.DEFAULT.accruedInterest(PAYMENT_PERIOD_FULL_GS, prov); assertEquals(computed, expected, TOLERANCE_PV); }
@Override public double accruedInterest(RatePaymentPeriod period, RatesProvider provider) { LocalDate valDate = provider.getValuationDate(); if (valDate.compareTo(period.getStartDate()) <= 0 || valDate.compareTo(period.getEndDate()) > 0) { return 0d; } ImmutableList.Builder<RateAccrualPeriod> truncated = ImmutableList.builder(); for (RateAccrualPeriod rap : period.getAccrualPeriods()) { if (valDate.compareTo(rap.getEndDate()) > 0) { truncated.add(rap); } else { truncated.add(rap.toBuilder() .endDate(provider.getValuationDate()) .unadjustedEndDate(provider.getValuationDate()) .yearFraction(period.getDayCount().yearFraction(rap.getStartDate(), provider.getValuationDate())) .build()); break; } } RatePaymentPeriod adjustedPaymentPeriod = period.toBuilder().accrualPeriods(truncated.build()).build(); return forecastValue(adjustedPaymentPeriod, provider); }
builder.addListEntry( ExplainKey.ACCRUAL_PERIODS, child -> explainPresentValue(accrualPeriod, paymentPeriod.getDayCount(), currency, notional, provider, child));