final Annuity<PaymentFixed> nominal = (Annuity<PaymentFixed>) getNominal().toDerivative(date, data);
final AnnuityDefinition<CouponDefinition> couponDefinition = (AnnuityDefinition<CouponDefinition>) getCoupons().trimBefore(settlementDate);
final CouponDefinition[] couponExPeriodArray = new CouponDefinition[couponDefinition.getNumberOfPayments()];
System.arraycopy(couponDefinition.getPayments(), 0, couponExPeriodArray, 0, couponDefinition.getNumberOfPayments());
if (getExCouponDays() != 0) {
final ZonedDateTime exDividendDate = ScheduleCalculator.getAdjustedDate(couponDefinition.getNthPayment(0).getPaymentDate(), -getExCouponDays(), getCalendar());
if (settlementDate.isAfter(exDividendDate)) {
// Implementation note: Ex-dividend period: the next coupon is not received but its date is required for yield calculation
couponExPeriodArray[0] = new CouponFixedDefinition(couponDefinition.getNthPayment(0), 0.0);
}
}
final AnnuityDefinition<PaymentDefinition> couponDefinitionExPeriod = new AnnuityDefinition<PaymentDefinition>(couponExPeriodArray, getCalendar());
final Annuity<Coupon> couponStandard = (Annuity<Coupon>) couponDefinitionExPeriod.toDerivative(date, data);
final Annuity<PaymentFixed> nominalStandard = nominal.trimBefore(settlementTime);
final double accruedInterest = accruedInterest(settlementDate);
final double factorSpot = getDayCount().getAccruedInterest(couponDefinition.getNthPayment(0).getAccrualStartDate(), settlementDate, couponDefinition.getNthPayment(0).getAccrualEndDate(), 1.0,
_couponPerYear);
final double factorPeriod = getDayCount().getAccruedInterest(couponDefinition.getNthPayment(0).getAccrualStartDate(), couponDefinition.getNthPayment(0).getAccrualEndDate(),
couponDefinition.getNthPayment(0).getAccrualEndDate(), 1.0, _couponPerYear);
final double factorToNextCoupon = (factorPeriod - factorSpot) / factorPeriod;
final PaymentFixedDefinition nominalLast = getNominal().getNthPayment(getNominal().getNumberOfPayments() - 1);
final ZonedDateTime settlementDate2 = settlementDate.isBefore(date) ? date : settlementDate;
final double notional = settlementDate.isBefore(date) ? 0.0 : 1.0;
final PaymentFixedDefinition settlementDefinition = new PaymentFixedDefinition(nominalLast.getCurrency(), settlementDate2, notional);
final PaymentFixed settlement = settlementDefinition.toDerivative(date);
return new BondInterestIndexedSecurity<>(nominalStandard, couponStandard, settlementTime, accruedInterest, factorToNextCoupon, _yieldConvention, _couponPerYear, settlement, getIssuer(),
_priceIndex);