final Pair<String, Currency> issuerCcy = futures.getDeliveryBasket()[0].getIssuerCcy();
ArgumentChecker.isTrue(data.getHullWhiteIssuerCurrency().equals(issuerCcy), "Incompatible data and futures");
final int nbBond = futures.getDeliveryBasket().length;
final String issuerName = futures.getDeliveryBasket()[0].getIssuer();
final HullWhiteOneFactorPiecewiseConstantParameters parameters = data.getHullWhiteParameters();
final IssuerProviderInterface issuer = data.getIssuerProvider();
final MulticurveProviderInterface multicurvesDecorated = new MulticurveProviderDiscountingDecoratedIssuer(issuer, futures.getCurrency(), issuerName);
final double expiry = futures.getNoticeLastTime();
final double delivery = futures.getDeliveryLastTime();
final double dfdelivery = data.getIssuerProvider().getDiscountFactor(issuerCcy, delivery);
// Constructing non-homogeneous point series for the numerical estimations.
final int nbPtWing = ((int) Math.floor(nbPoint / 20.)); // Number of point on each wing.
final int nbPtCenter = nbPoint - 2 * nbPtWing;
final double prob = 1.0 / (2.0 * nbPtCenter);
final double xStart = NORMAL.getInverseCDF(prob);
final double[] x = new double[nbPoint];
for (int loopwing = 0; loopwing < nbPtWing; loopwing++) {
x[loopwing] = xStart * (1.0 + (nbPtWing - loopwing) / 2.0);
x[nbPoint - 1 - loopwing] = -xStart * (1.0 + (nbPtWing - loopwing) / 2.0);
}
for (int loopcent = 0; loopcent < nbPtCenter; loopcent++) {
x[nbPtWing + loopcent] = xStart + loopcent * (-2.0 * xStart) / (nbPtCenter - 1);
}
// Figures for each bond
final double[][] cfTime = new double[nbBond][];
final double[][] df = new double[nbBond][];
final double[][] alpha = new double[nbBond][];
final double[][] beta = new double[nbBond][];
final double[][] cfaAdjusted = new double[nbBond][];
final double[] e = new double[nbBond];
final double[][] pv = new double[nbPoint][nbBond];
final AnnuityPaymentFixed[] cf = new AnnuityPaymentFixed[nbBond];
for (int loopbnd = 0; loopbnd < nbBond; loopbnd++) {
cf[loopbnd] = futures.getDeliveryBasket()[loopbnd].accept(CFEC, multicurvesDecorated);
final int nbCf = cf[loopbnd].getNumberOfPayments();
cfTime[loopbnd] = new double[nbCf];
df[loopbnd] = new double[nbCf];
alpha[loopbnd] = new double[nbCf];
beta[loopbnd] = new double[nbCf];
cfaAdjusted[loopbnd] = new double[nbCf];
for (int loopcf = 0; loopcf < nbCf; loopcf++) {
cfTime[loopbnd][loopcf] = cf[loopbnd].getNthPayment(loopcf).getPaymentTime();
df[loopbnd][loopcf] = issuer.getDiscountFactor(issuerCcy, cfTime[loopbnd][loopcf]);
alpha[loopbnd][loopcf] = MODEL.alpha(parameters, 0.0, expiry, delivery, cfTime[loopbnd][loopcf]);
beta[loopbnd][loopcf] = MODEL.futuresConvexityFactor(parameters, expiry, cfTime[loopbnd][loopcf], delivery);
cfaAdjusted[loopbnd][loopcf] = df[loopbnd][loopcf] / dfdelivery * beta[loopbnd][loopcf] * cf[loopbnd].getNthPayment(loopcf).getAmount() / futures.getConversionFactor()[loopbnd];
for (int looppt = 0; looppt < nbPoint; looppt++) {
pv[looppt][loopbnd] += cfaAdjusted[loopbnd][loopcf] * Math.exp(-alpha[loopbnd][loopcf] * alpha[loopbnd][loopcf] / 2.0 - alpha[loopbnd][loopcf] * x[looppt]);