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));
}