Yield calculation for UST bond maturing on 2020-05-31 settling 2019-11-29

You need to look into the use of Period#getEndDate vs Period#getUnadjustedEndDate - as a failing test you can validate the px->yld of US912828XE52 @ 99.94140625 for settlement 2019-11-29

Because DiscountingFixedCouponBondProductPricer#couponIndex usees #getEndDate it thinks there is 1 coupon remaining when in fact there are still 2.

Once the following test is passing I think you’ll have fixed at least 3 different bugs.

@Test
public void ustPenultimateCoupon() {
    ResolvedFixedCouponBond bond = FixedCouponBond.builder()
            .securityId(SECURITY_ID)
            .dayCount(DayCounts.ACT_ACT_ICMA)
            .fixedRate(0.015)
            .legalEntityId(ISSUER_ID)
            .currency(USD)
            .notional(NOTIONAL)
            .accrualSchedule(PeriodicSchedule.of(LocalDate.of(2015, 1, 3), LocalDate.of(2020, 5, 31), Frequency.P6M,
                    BusinessDayAdjustment.of(BusinessDayConventions.MODIFIED_FOLLOWING, HolidayCalendarIds.USNY),
                    StubConvention.SMART_INITIAL, false))
            .settlementDateOffset(DaysAdjustment.ofBusinessDays(1, HolidayCalendarIds.USNY))
            .yieldConvention(FixedCouponBondYieldConvention.GB_BUMP_DMO)
            .exCouponPeriod(DaysAdjustment.NONE)
            .build()
            .resolve(REF_DATA);
    LocalDate settlement = LocalDate.of(2019, 11, 29);
    double dirtyPrice = PRICER.dirtyPriceFromCleanPrice(bond, settlement, 0.9994140625);
    assertThat(dirtyPrice).isCloseTo(1.0068730788934, offset(TOL));
    double yield = PRICER.yieldFromDirtyPrice(bond, settlement, dirtyPrice);
    assertThat(yield).isCloseTo(0.016174628, offset(1e-9));
}