ArgumentChecker.notNull(optionForex, "Forex option");
ArgumentChecker.notNull(smileMulticurves, "Smile");
ArgumentChecker.isTrue(smileMulticurves.checkCurrencies(optionForex.getCurrency1(), optionForex.getCurrency2()), "Option currencies not compatible with smile data");
final MulticurveProviderInterface multicurves = smileMulticurves.getMulticurveProvider();
final PresentValueForexBlackVolatilitySensitivity pointSensitivity = presentValueBlackVolatilitySensitivity(optionForex, smileMulticurves); // In dom ccy
final SmileDeltaTermStructureParametersStrikeInterpolation volatilityModel = smileMulticurves.getVolatility();
final double payTime = optionForex.getUnderlyingForex().getPaymentTime();
final double expiry = optionForex.getExpirationTime();
// Forward sweep
final Currency domesticCcy;
final Currency foreignCcy;
final double strike;
if (optionForex.payDomestic()) {
domesticCcy = optionForex.getUnderlyingForex().getCurrency2();
foreignCcy = optionForex.getUnderlyingForex().getCurrency1();
strike = optionForex.getStrike();
} else {
strike = 1.0 / optionForex.getStrike();
domesticCcy = optionForex.getUnderlyingForex().getCurrency1();
foreignCcy = optionForex.getUnderlyingForex().getCurrency2();
}
final double dfDomestic = multicurves.getDiscountFactor(domesticCcy, payTime);
final double dfForeign = multicurves.getDiscountFactor(foreignCcy, payTime);
final double spot = multicurves.getFxRate(foreignCcy, domesticCcy);
final double forward = spot * dfForeign / dfDomestic;
final VolatilityAndBucketedSensitivities volAndSensitivities = smileMulticurves.getVolatilityAndSensitivities(foreignCcy, domesticCcy, expiry, strike, forward);
final double[][] nodeWeight = volAndSensitivities.getBucketedSensitivities();
final DoublesPair point = DoublesPair.of(optionForex.getExpirationTime(), (foreignCcy == smileMulticurves.getCurrencyPair().getFirst()) ? strike : 1.0 / strike);
final double[][] vega = new double[volatilityModel.getNumberExpiration()][volatilityModel.getNumberStrike()];
for (int loopexp = 0; loopexp < volatilityModel.getNumberExpiration(); loopexp++) {
for (int loopstrike = 0; loopstrike < volatilityModel.getNumberStrike(); loopstrike++) {
vega[loopexp][loopstrike] = nodeWeight[loopexp][loopstrike] * pointSensitivity.getVega().getMap().get(point);
}
}
return new PresentValueForexBlackVolatilityNodeSensitivityDataBundle(optionForex.getUnderlyingForex().getCurrency1(), optionForex.getUnderlyingForex().getCurrency2(), new DoubleMatrix1D(
volatilityModel.getTimeToExpiration()), new DoubleMatrix1D(volatilityModel.getDeltaFull()), new DoubleMatrix2D(vega));
}