* @return The forward gamma
*/
public double forwardGammaTheoretical(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;
final double paymentTime = optionForex.getUnderlyingForex().getPaymentTime();
final Currency domesticCcy;
final Currency foreignCcy;
final double strike;
final String foreignCurveName;
final String domesticCurveName;
boolean isCall;
if (optionForex.payDomestic()) {
foreignCurveName = optionForex.getUnderlyingForex().getPaymentCurrency1().getFundingCurveName();
domesticCurveName = optionForex.getUnderlyingForex().getPaymentCurrency2().getFundingCurveName();
domesticCcy = optionForex.getUnderlyingForex().getCurrency2();
foreignCcy = optionForex.getUnderlyingForex().getCurrency1();
strike = optionForex.getStrike();
isCall = optionForex.isCall();
} else {
foreignCurveName = optionForex.getUnderlyingForex().getPaymentCurrency2().getFundingCurveName();
domesticCurveName = optionForex.getUnderlyingForex().getPaymentCurrency1().getFundingCurveName();
strike = 1.0 / optionForex.getStrike();
domesticCcy = optionForex.getUnderlyingForex().getCurrency1();
foreignCcy = optionForex.getUnderlyingForex().getCurrency2();
isCall = !optionForex.isCall();
}
final double dfDomestic = smile.getCurve(domesticCurveName).getDiscountFactor(paymentTime);
final double dfForeign = smile.getCurve(foreignCurveName).getDiscountFactor(paymentTime);
final double rDomestic = smile.getCurve(domesticCurveName).getInterestRate(paymentTime);
final double rForeign = smile.getCurve(foreignCurveName).getInterestRate(paymentTime);
final double spot = smile.getFxRates().getFxRate(foreignCcy, domesticCcy);
final double forward = spot * dfForeign / dfDomestic;
final double expiry = optionForex.getExpirationTime();
final double volatility = FXVolatilityUtils.getVolatility(smile, foreignCcy, domesticCcy, expiry, forward, forward);
final double longSign = (optionForex.isLong() ? 1.0 : -1.0);
return DigitalOptionFunction.gamma(spot, strike, expiry, volatility, rDomestic, rDomestic - rForeign, isCall) * longSign * dfDomestic / dfForeign / dfForeign;