final LegacyVanillaCreditDefaultSwapDefinition cds = new LegacyVanillaCreditDefaultSwapDefinition(buySellProtection, protectionBuyer, protectionSeller, referenceEntity, currency, debtSeniority,
restructuringClause, calendar, startDate, effectiveDate, maturityDate, stubType, couponFrequency, daycountFractionConvention, businessdayAdjustmentConvention, immAdjustMaturityDate,
adjustEffectiveDate, adjustMaturityDate, notional, recoveryRate, includeAccruedPremium, protectionStart, parSpread);
final PresentValueCreditDefaultSwap pvcds = new PresentValueCreditDefaultSwap();
final ISDADateCurve curveISDADate = new ISDADateCurve("Test", BASE_DATE, CURVE_DATES, RATES, 0.0);
// Set the tenors at which we have market observed par CDS spread quotes
final int nbTenors = 10;
final ZonedDateTime[] tenors = new ZonedDateTime[nbTenors];
tenors[0] = DateUtils.getUTCDate(2008, 12, 20);
tenors[1] = DateUtils.getUTCDate(2009, 6, 20);
tenors[2] = DateUtils.getUTCDate(2010, 6, 20);
tenors[3] = DateUtils.getUTCDate(2011, 6, 20);
tenors[4] = DateUtils.getUTCDate(2012, 6, 20);
tenors[5] = DateUtils.getUTCDate(2014, 6, 20);
tenors[6] = DateUtils.getUTCDate(2017, 6, 20);
tenors[7] = DateUtils.getUTCDate(2022, 6, 20);
tenors[8] = DateUtils.getUTCDate(2030, 6, 20);
tenors[9] = DateUtils.getUTCDate(2040, 6, 20);
//Note: The input are in bps. Should we change it to relative number to be coherent with the rest of the library? The scale is hard-coded (/10000.0 in the code).
final double[] flat = {0.0, 1.0, 50.0, 100.0, 200.0, 1000.0 }; // Flat (tight, distressed, blown)
// Note: Flat with 100000.0 fails to calibrate.
final int nbFlat = flat.length;
final double[][] zigzag = { {50.0, 60.0 }, {500.0, 550.0 } };
// Note: Zig-zag with {500.0, 600.0 } fails to calibrate
final int nbZigzag = zigzag.length;
final double[][] upward = { {100.0, 20.0 }, {100.0, 40.0 } }; // Start, step
// Note: Upward with {100.0, 100.0 } or {100.0, 50.0 } fails to calibrate
final int nbUpward = upward.length;
final int nbSpecific = 8;
final int nbSpreads = nbFlat + nbZigzag + nbUpward + nbSpecific;
final double[][] marketSpreads = new double[nbSpreads][nbTenors];
for (int loopflat = 0; loopflat < nbFlat; loopflat++) {
for (int loopten = 0; loopten < nbTenors; loopten++) {
marketSpreads[loopflat][loopten] = flat[loopflat];
}
}
for (int loopzz = 0; loopzz < nbZigzag; loopzz++) {
for (int loopten = 0; loopten < nbTenors / 2; loopten++) {
marketSpreads[nbFlat + loopzz][2 * loopten + 0] = zigzag[loopzz][0];
marketSpreads[nbFlat + loopzz][2 * loopten + 1] = zigzag[loopzz][1];
}
}
for (int loopup = 0; loopup < nbUpward; loopup++) {
for (int loopten = 0; loopten < nbTenors; loopten++) {
marketSpreads[nbFlat + nbZigzag + loopup][loopten] = upward[loopup][0] + loopten * upward[loopup][1];
}
}
final int nbNonSpecific = nbFlat + nbZigzag + nbUpward;
int loopspec = 0; // Upward, steep short end
marketSpreads[nbNonSpecific + loopspec][0] = 100.0;
marketSpreads[nbNonSpecific + loopspec][1] = 200.0;
marketSpreads[nbNonSpecific + loopspec][2] = 300.0;
marketSpreads[nbNonSpecific + loopspec][3] = 400.0;
marketSpreads[nbNonSpecific + loopspec][4] = 500.0;
marketSpreads[nbNonSpecific + loopspec][5] = 520.0;
marketSpreads[nbNonSpecific + loopspec][6] = 540.0;
marketSpreads[nbNonSpecific + loopspec][7] = 560.0;
marketSpreads[nbNonSpecific + loopspec][8] = 580.0;
marketSpreads[nbNonSpecific + loopspec][9] = 600.0;
loopspec++;// Upward, steep long end
marketSpreads[nbNonSpecific + loopspec][0] = 100.0;
marketSpreads[nbNonSpecific + loopspec][1] = 120.0;
marketSpreads[nbNonSpecific + loopspec][2] = 140.0;
marketSpreads[nbNonSpecific + loopspec][3] = 160.0;
marketSpreads[nbNonSpecific + loopspec][4] = 180.0;
marketSpreads[nbNonSpecific + loopspec][5] = 220.0;
marketSpreads[nbNonSpecific + loopspec][6] = 260.0;
marketSpreads[nbNonSpecific + loopspec][7] = 300.0;
marketSpreads[nbNonSpecific + loopspec][8] = 340.0;
marketSpreads[nbNonSpecific + loopspec][9] = 380.0;
loopspec++;//Downward, gentle
marketSpreads[nbNonSpecific + loopspec][0] = 280.0;
marketSpreads[nbNonSpecific + loopspec][1] = 260.0;
marketSpreads[nbNonSpecific + loopspec][2] = 240.0;
marketSpreads[nbNonSpecific + loopspec][3] = 220.0;
marketSpreads[nbNonSpecific + loopspec][4] = 200.0;
marketSpreads[nbNonSpecific + loopspec][5] = 180.0;
marketSpreads[nbNonSpecific + loopspec][6] = 160.0;
marketSpreads[nbNonSpecific + loopspec][7] = 140.0;
marketSpreads[nbNonSpecific + loopspec][8] = 120.0;
marketSpreads[nbNonSpecific + loopspec][9] = 100.0;
loopspec++;//Downward, steep
marketSpreads[nbNonSpecific + loopspec][0] = 1000.0;
marketSpreads[nbNonSpecific + loopspec][1] = 900.0;
marketSpreads[nbNonSpecific + loopspec][2] = 800.0;
marketSpreads[nbNonSpecific + loopspec][3] = 700.0;
marketSpreads[nbNonSpecific + loopspec][4] = 600.0;
marketSpreads[nbNonSpecific + loopspec][5] = 500.0;
marketSpreads[nbNonSpecific + loopspec][6] = 450.0;
marketSpreads[nbNonSpecific + loopspec][7] = 400.0;
marketSpreads[nbNonSpecific + loopspec][8] = 400.0;
marketSpreads[nbNonSpecific + loopspec][9] = 380.0;
loopspec++; //Downward, steep short end
marketSpreads[nbNonSpecific + loopspec][0] = 600.0;
marketSpreads[nbNonSpecific + loopspec][1] = 500.0;
marketSpreads[nbNonSpecific + loopspec][2] = 400.0;
marketSpreads[nbNonSpecific + loopspec][3] = 300.0;
marketSpreads[nbNonSpecific + loopspec][4] = 200.0;
marketSpreads[nbNonSpecific + loopspec][5] = 180.0;
marketSpreads[nbNonSpecific + loopspec][6] = 160.0;
marketSpreads[nbNonSpecific + loopspec][7] = 140.0;
marketSpreads[nbNonSpecific + loopspec][8] = 120.0;
marketSpreads[nbNonSpecific + loopspec][9] = 100.0;
loopspec++; // Downward, steep long end
marketSpreads[nbNonSpecific + loopspec][0] = 680.0;
marketSpreads[nbNonSpecific + loopspec][1] = 660.0;
marketSpreads[nbNonSpecific + loopspec][2] = 640.0;
marketSpreads[nbNonSpecific + loopspec][3] = 620.0;
marketSpreads[nbNonSpecific + loopspec][4] = 600.0;
marketSpreads[nbNonSpecific + loopspec][5] = 580.0;
marketSpreads[nbNonSpecific + loopspec][6] = 480.0;
marketSpreads[nbNonSpecific + loopspec][7] = 380.0;
marketSpreads[nbNonSpecific + loopspec][8] = 280.0;
marketSpreads[nbNonSpecific + loopspec][9] = 180.0;
loopspec++; // Inverted Cavale
marketSpreads[nbNonSpecific + loopspec][0] = 1774.0;
marketSpreads[nbNonSpecific + loopspec][1] = 1805.0;
marketSpreads[nbNonSpecific + loopspec][2] = 1856.0;
marketSpreads[nbNonSpecific + loopspec][3] = 1994.0;
marketSpreads[nbNonSpecific + loopspec][4] = 2045.0;
marketSpreads[nbNonSpecific + loopspec][5] = 2045.0;
marketSpreads[nbNonSpecific + loopspec][6] = 2045.0;
marketSpreads[nbNonSpecific + loopspec][7] = 2045.0;
marketSpreads[nbNonSpecific + loopspec][8] = 2045.0;
marketSpreads[nbNonSpecific + loopspec][9] = 2045.0;
loopspec++; // BCPN
marketSpreads[nbNonSpecific + loopspec][0] = 780.0;
marketSpreads[nbNonSpecific + loopspec][1] = 812.0;
marketSpreads[nbNonSpecific + loopspec][2] = 803.0;
marketSpreads[nbNonSpecific + loopspec][3] = 826.0;
marketSpreads[nbNonSpecific + loopspec][4] = 874.0;
marketSpreads[nbNonSpecific + loopspec][5] = 896.0;
marketSpreads[nbNonSpecific + loopspec][6] = 868.0;
marketSpreads[nbNonSpecific + loopspec][7] = 838.0;
marketSpreads[nbNonSpecific + loopspec][8] = 800.0;
marketSpreads[nbNonSpecific + loopspec][9] = 780.0;
final double[] pv = new double[nbSpreads];
for (int loopspread = 0; loopspread < nbSpreads; loopspread++) {
pv[loopspread] = pvcds.calibrateAndGetPresentValue(valuationDate, cds, tenors, marketSpreads[loopspread], curveISDADate, PRICE_TYPE_CLEAN);
}
final double[] pvExpected = {-5672458.043975232, -5612833.8411497325, -2764265.396014931, 72.73528969381005, 5126779.225961099, 3.2042108339047514E7, -2210334.5968965204, 1.9690546519727346E7,
5196701.133692645, 1.00057853795825E7, 1.9044683964563813E7, 6220964.461377103, 4085113.125930696, 1.686216455050518E7, 4001404.223613698, 2.0290515510249116E7, 4.728163157144226E7,
2.9981696893176883E7 }; // From previous run