/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(FixedCouponBondPaymentPeriod beanToCopy) { this.currency = beanToCopy.getCurrency(); this.notional = beanToCopy.getNotional(); this.startDate = beanToCopy.getStartDate(); this.endDate = beanToCopy.getEndDate(); this.unadjustedStartDate = beanToCopy.getUnadjustedStartDate(); this.unadjustedEndDate = beanToCopy.getUnadjustedEndDate(); this.detachmentDate = beanToCopy.getDetachmentDate(); this.fixedRate = beanToCopy.getFixedRate(); this.yearFraction = beanToCopy.getYearFraction(); }
private double currentCashCouponPayment(ResolvedFixedCouponBond product, LocalDate referenceDate) { double cash = 0d; for (FixedCouponBondPaymentPeriod period : product.getPeriodicPayments()) { if (period.getPaymentDate().isEqual(referenceDate)) { cash += period.getFixedRate() * period.getNotional() * period.getYearFraction(); } } return cash; }
@Override public LocalDate getPeriodEndDate(LocalDate date) { // exception should not occur, because input is validated above return periodicPayments.stream() .filter(p -> p.contains(date)) .map(p -> p.getUnadjustedEndDate()) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Date is not contained in any period")); }
public void test_of() { FixedCouponBondPaymentPeriod test = FixedCouponBondPaymentPeriod.builder() .currency(USD) .startDate(START_ADJUSTED) .yearFraction(YEAR_FRACTION) .build(); assertEquals(test.getCurrency(), USD); assertEquals(test.getUnadjustedStartDate(), START); assertEquals(test.getStartDate(), START_ADJUSTED); assertEquals(test.getUnadjustedEndDate(), END); assertEquals(test.getEndDate(), END_ADJUSTED); assertEquals(test.getPaymentDate(), END_ADJUSTED); assertEquals(test.getDetachmentDate(), DETACHMENT_DATE); assertEquals(test.getFixedRate(), FIXED_RATE); assertEquals(test.getNotional(), NOTIONAL); assertEquals(test.getYearFraction(), YEAR_FRACTION); assertEquals(test.hasExCouponPeriod(), true); assertEquals(test.adjustPaymentDate(TemporalAdjusters.ofDateAdjuster(d -> d.plusDays(2))), test); ImmutableSet.Builder<Index> builder = ImmutableSet.builder(); test.collectIndices(builder); assertEquals(test.getCurrency(), USD); assertEquals(test.getUnadjustedStartDate(), START); assertEquals(test.getStartDate(), START_ADJUSTED); assertEquals(test.getUnadjustedEndDate(), END); assertEquals(test.getEndDate(), END_ADJUSTED); assertEquals(test.getPaymentDate(), END_ADJUSTED); assertEquals(test.getDetachmentDate(), DETACHMENT_DATE); assertEquals(test.getFixedRate(), FIXED_RATE);
private double dirtyPriceFromYieldStandard( ResolvedFixedCouponBond bond, LocalDate settlementDate, double yield) { int nbCoupon = bond.getPeriodicPayments().size(); double factorOnPeriod = 1 + yield / ((double) bond.getFrequency().eventsPerYear()); double fixedRate = bond.getFixedRate(); double pvAtFirstCoupon = 0; int pow = 0; for (int loopcpn = 0; loopcpn < nbCoupon; loopcpn++) { FixedCouponBondPaymentPeriod period = bond.getPeriodicPayments().get(loopcpn); if ((period.hasExCouponPeriod() && !settlementDate.isAfter(period.getDetachmentDate())) || (!period.hasExCouponPeriod() && period.getPaymentDate().isAfter(settlementDate))) { pvAtFirstCoupon += fixedRate * period.getYearFraction() / Math.pow(factorOnPeriod, pow); ++pow; } } pvAtFirstCoupon += 1d / Math.pow(factorOnPeriod, pow - 1); return pvAtFirstCoupon * Math.pow(factorOnPeriod, -factorToNextCoupon(bond, settlementDate)); }
private void explainBasics(FixedCouponBondPaymentPeriod period, ExplainMapBuilder builder, Currency currency, LocalDate paymentDate) { builder.put(ExplainKey.ENTRY_TYPE, "FixedCouponBondPaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.START_DATE, period.getStartDate()); builder.put(ExplainKey.UNADJUSTED_START_DATE, period.getUnadjustedStartDate()); builder.put(ExplainKey.END_DATE, period.getEndDate()); builder.put(ExplainKey.UNADJUSTED_END_DATE, period.getUnadjustedEndDate()); builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, period.getYearFraction()); builder.put(ExplainKey.DAYS, (int) DAYS.between(period.getStartDate(), period.getEndDate())); }
public void test_explainPresentValue_past() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PAYMENT_PERIOD, ISSUER_CURVE_AFTER, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FixedCouponBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PAYMENT_PERIOD.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START); assertEquals(explain.get(ExplainKey.END_DATE).get(), END_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_ADJUSTED, END_ADJUSTED)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); }
/** * Calculates the accrued year fraction of the fixed coupon bond with the specified settlement date. * * @param bond the product * @param settlementDate the settlement date * @return the accrued year fraction of the product */ public double accruedYearFraction(ResolvedFixedCouponBond bond, LocalDate settlementDate) { if (bond.getUnadjustedStartDate().isAfter(settlementDate)) { return 0d; } FixedCouponBondPaymentPeriod period = bond.findPeriod(settlementDate) .orElseThrow(() -> new IllegalArgumentException("Date outside range of bond")); LocalDate previousAccrualDate = period.getUnadjustedStartDate(); double accruedYearFraction = bond.yearFraction(previousAccrualDate, settlementDate); double result = 0d; if (settlementDate.isAfter(period.getDetachmentDate())) { result = accruedYearFraction - period.getYearFraction(); } else { result = accruedYearFraction; } return result; }
public void test_yearFraction() { ResolvedFixedCouponBond test = sut(); FixedCouponBondPaymentPeriod period = test.getPeriodicPayments().get(0); assertEquals(test.yearFraction(period.getUnadjustedStartDate(), period.getUnadjustedEndDate()), period.getYearFraction()); }
double presentValueCoupon( ResolvedFixedCouponBond bond, IssuerCurveDiscountFactors discountFactors, LocalDate referenceDate1, LocalDate referenceDate2) { double pvDiff = 0d; for (FixedCouponBondPaymentPeriod period : bond.getPeriodicPayments()) { if (period.getDetachmentDate().isAfter(referenceDate1) && !period.getDetachmentDate().isAfter(referenceDate2)) { pvDiff += periodPricer.presentValue(period, discountFactors); } } return pvDiff; }
private FixedCouponBondPaymentPeriod findPeriod(ResolvedFixedCouponBond bond, LocalDate date1, LocalDate date2) { ImmutableList<FixedCouponBondPaymentPeriod> list = bond.getPeriodicPayments(); for (FixedCouponBondPaymentPeriod period : list) { if (period.getDetachmentDate().equals(period.getPaymentDate())) { if (period.getPaymentDate().isAfter(date1) && period.getPaymentDate().isBefore(date2)) { return period; } } else { if (period.getDetachmentDate().isAfter(date1) && period.getDetachmentDate().isBefore(date2)) { return period; } } } return null; } }
private double factorToNextCoupon(ResolvedFixedCouponBond bond, LocalDate settlementDate) { if (bond.getPeriodicPayments().get(0).getStartDate().isAfter(settlementDate)) { return 0d; } int couponIndex = couponIndex(bond.getPeriodicPayments(), settlementDate); double factorSpot = accruedYearFraction(bond, settlementDate); double factorPeriod = bond.getPeriodicPayments().get(couponIndex).getYearFraction(); return (factorPeriod - factorSpot) / factorPeriod; }
public void test_yearFraction_scheduleInfo() { ResolvedFixedCouponBond base = sut(); FixedCouponBondPaymentPeriod period = base.getPeriodicPayments().get(0); AtomicBoolean eom = new AtomicBoolean(false); DayCount dc = new DayCount() { @Override public double yearFraction(LocalDate firstDate, LocalDate secondDate, ScheduleInfo scheduleInfo) { assertEquals(scheduleInfo.getStartDate(), base.getUnadjustedStartDate()); assertEquals(scheduleInfo.getEndDate(), base.getUnadjustedEndDate()); assertEquals(scheduleInfo.getPeriodEndDate(firstDate), period.getUnadjustedEndDate()); assertEquals(scheduleInfo.getFrequency(), base.getFrequency()); assertEquals(scheduleInfo.isEndOfMonthConvention(), eom.get()); return 0.5; } @Override public int days(LocalDate firstDate, LocalDate secondDate) { return 182; } @Override public String getName() { return ""; } }; ResolvedFixedCouponBond test = base.toBuilder().dayCount(dc).build(); assertEquals(test.yearFraction(period.getUnadjustedStartDate(), period.getUnadjustedEndDate()), 0.5); // test with EOM=true ResolvedFixedCouponBond test2 = test.toBuilder().rollConvention(RollConventions.EOM).build(); eom.set(true); assertEquals(test2.yearFraction(period.getUnadjustedStartDate(), period.getUnadjustedEndDate()), 0.5); }
if (yieldConv.equals(US_STREET) || yieldConv.equals(DE_BONDS)) { FixedCouponBondPaymentPeriod payment = payments.get(payments.size() - 1); return (1d + payment.getFixedRate() * payment.getYearFraction()) / (1d + factorToNextCoupon(bond, settlementDate) * yield / ((double) bond.getFrequency().eventsPerYear()));
SchedulePeriod period = adjustedSchedule.getPeriod(i); SchedulePeriod unadjustedPeriod = unadjustedSchedule.getPeriod(i); accrualPeriods.add(FixedCouponBondPaymentPeriod.builder() .unadjustedStartDate(period.getUnadjustedStartDate()) .unadjustedEndDate(period.getUnadjustedEndDate()) Payment nominalPayment = Payment.of(CurrencyAmount.of(currency, notional), lastPeriod.getPaymentDate()); return ResolvedFixedCouponBond.builder() .securityId(securityId)
@Override public LocalDate getPaymentDate() { return getEndDate(); }
/** * The unadjusted end date. * <p> * This is the unadjusted last coupon period date of the bond. * * @return the unadjusted end date */ public LocalDate getUnadjustedEndDate() { return periodicPayments.get(periodicPayments.size() - 1).getUnadjustedEndDate(); }
/** * Gets the start date of the product. * <p> * This is the first coupon period date of the bond, often known as the effective date. * This date has been adjusted to be a valid business day. * * @return the start date */ public LocalDate getStartDate() { return periodicPayments.get(0).getStartDate(); }
/** * The unadjusted start date. * <p> * This is the unadjusted first coupon period date of the bond. * * @return the unadjusted start date */ public LocalDate getUnadjustedStartDate() { return periodicPayments.get(0).getUnadjustedStartDate(); }
for (int loopcpn = 0; loopcpn < nbCoupon; loopcpn++) { FixedCouponBondPaymentPeriod period = bond.getPeriodicPayments().get(loopcpn); if ((period.hasExCouponPeriod() && !settlementDate.isAfter(period.getDetachmentDate())) || (!period.hasExCouponPeriod() && period.getPaymentDate().isAfter(settlementDate))) { mdAtFirstCoupon += period.getYearFraction() / Math.pow(factorOnPeriod, pow + 1) * (pow + factorToNextCoupon) / couponPerYear; pvAtFirstCoupon += period.getYearFraction() / Math.pow(factorOnPeriod, pow); ++pow;