final double cmsCap2Pv = _methodCmsCap.presentValue(cmsCap2, sabrData).getAmount(ccy);
final double discountFactorPayment = multicurves.getDiscountFactor(ccy, cmsSpread.getPaymentTime());
final double factor = discountFactorPayment * cmsCap1.getNotional() * cmsCap1.getPaymentYearFraction();
final double expectation1 = cmsCoupon1Pv / factor;
final double expectation2 = cmsCoupon2Pv / factor;
NormalFunctionData dataCap1 = new NormalFunctionData(expectation1, factor, 0.0);
final EuropeanVanillaOption optionCap1 = new EuropeanVanillaOption(strike1, cmsSpread.getFixingTime(), true);
double cmsCap1ImpliedVolatility = 0;
try {
cmsCap1ImpliedVolatility = NORMAL_IMPLIED_VOLATILITY.getImpliedVolatility(dataCap1, optionCap1, cmsCap1Pv);
} catch (final Exception e) {
//TODO
}
NormalFunctionData dataCap2 = new NormalFunctionData(expectation2, factor, cmsCap1ImpliedVolatility);
final EuropeanVanillaOption optionCap2 = new EuropeanVanillaOption(strike2, cmsSpread.getFixingTime(), true);
double cmsCap2ImpliedVolatility = 0;
try {
cmsCap2ImpliedVolatility = NORMAL_IMPLIED_VOLATILITY.getImpliedVolatility(dataCap2, optionCap2, cmsCap2Pv);
} catch (final Exception e) {
//TODO
}
final double rho = _correlation.evaluate(cmsSpread.getStrike());
final double cmsSpreadImpliedVolatility = Math.sqrt(cmsCap1ImpliedVolatility * cmsCap1ImpliedVolatility - 2 * rho * cmsCap1ImpliedVolatility * cmsCap2ImpliedVolatility + cmsCap2ImpliedVolatility
* cmsCap2ImpliedVolatility);
final NormalFunctionData dataSpread = new NormalFunctionData(expectation1 - expectation2, discountFactorPayment * cmsSpread.getNotional() * cmsSpread.getPaymentYearFraction(),
cmsSpreadImpliedVolatility);
final EuropeanVanillaOption optionSpread = new EuropeanVanillaOption(cmsSpread.getStrike(), cmsSpread.getFixingTime(), cmsSpread.isCap());
final double[] cmsSpreadPvDerivative = new double[3];
final double cmsSpreadPv = NORMAL_PRICE.getPriceAdjoint(optionSpread, dataSpread, cmsSpreadPvDerivative);
// Backward sweep
final double cmsSpreadPvBar = 1.0;
final double cmsSpreadImpliedVolatilityBar = cmsSpreadPvDerivative[1] * cmsSpreadPvBar;
final double cmsCap2ImpliedVolatilityBar = (cmsCap2ImpliedVolatility - rho * cmsCap1ImpliedVolatility) / cmsSpreadImpliedVolatility * cmsSpreadImpliedVolatilityBar; // OK
final double cmsCap1ImpliedVolatilityBar = (cmsCap1ImpliedVolatility - rho * cmsCap2ImpliedVolatility) / cmsSpreadImpliedVolatility * cmsSpreadImpliedVolatilityBar; // OK
dataCap2 = new NormalFunctionData(expectation2, factor, cmsCap2ImpliedVolatility);
final double[] cmsCap2PriceNormalDerivative = new double[3];
NORMAL_PRICE.getPriceAdjoint(optionCap2, dataCap2, cmsCap2PriceNormalDerivative);
final double expectation2Bar = -cmsSpreadPvDerivative[0] * cmsSpreadPvBar + -cmsCap2PriceNormalDerivative[0] / cmsCap2PriceNormalDerivative[1] * cmsCap2ImpliedVolatilityBar; // OK
dataCap1 = new NormalFunctionData(expectation1, factor, cmsCap1ImpliedVolatility);
final double[] cmsCap1PriceNormalDerivative = new double[3];
NORMAL_PRICE.getPriceAdjoint(optionCap1, dataCap1, cmsCap1PriceNormalDerivative);
final double expectation1Bar = cmsSpreadPvDerivative[0] * cmsSpreadPvBar + -cmsCap1PriceNormalDerivative[0] / cmsCap1PriceNormalDerivative[1] * cmsCap1ImpliedVolatilityBar; // OK
final double factorBar = -cmsCoupon1Pv / (factor * factor) * expectation1Bar + -cmsCoupon2Pv / (factor * factor) * expectation2Bar - cmsCap2Pv / factor / cmsCap2PriceNormalDerivative[1]
* cmsCap2ImpliedVolatilityBar - cmsCap1Pv / factor / cmsCap1PriceNormalDerivative[1] * cmsCap1ImpliedVolatilityBar; // OK