* @return The implied volatility.
*/
public double impliedVolatility(final ForexOptionDigital optionForex, final YieldCurveBundle curves) {
ArgumentChecker.notNull(curves, "Curves");
ArgumentChecker.isTrue(curves instanceof SmileDeltaTermStructureDataBundle, "Yield curve bundle should contain smile data");
final SmileDeltaTermStructureDataBundle smile = (SmileDeltaTermStructureDataBundle) curves;
ArgumentChecker.notNull(optionForex, "Forex option");
ArgumentChecker.isTrue(smile.checkCurrencies(optionForex.getCurrency1(), optionForex.getCurrency2()), "Option currencies not compatible with smile data");
final double payTime = optionForex.getUnderlyingForex().getPaymentTime();
// Forward sweep
final Currency domesticCcy;
final Currency foreignCcy;
final String foreignCurveName;
final String domesticCurveName;
if (optionForex.payDomestic()) {
foreignCurveName = optionForex.getUnderlyingForex().getPaymentCurrency1().getFundingCurveName();
domesticCurveName = optionForex.getUnderlyingForex().getPaymentCurrency2().getFundingCurveName();
domesticCcy = optionForex.getUnderlyingForex().getCurrency2();
foreignCcy = optionForex.getUnderlyingForex().getCurrency1();
} else {
foreignCurveName = optionForex.getUnderlyingForex().getPaymentCurrency2().getFundingCurveName();
domesticCurveName = optionForex.getUnderlyingForex().getPaymentCurrency1().getFundingCurveName();
domesticCcy = optionForex.getUnderlyingForex().getCurrency1();
foreignCcy = optionForex.getUnderlyingForex().getCurrency2();
}
final double dfDomestic = smile.getCurve(domesticCurveName).getDiscountFactor(payTime);
final double dfForeign = smile.getCurve(foreignCurveName).getDiscountFactor(payTime);
final double spot = smile.getFxRates().getFxRate(foreignCcy, domesticCcy);
final double forward = spot * dfForeign / dfDomestic;
final double volatility = FXVolatilityUtils.getVolatility(smile, foreignCcy, domesticCcy, optionForex.getExpirationTime(), forward, forward);
return volatility;
}