@Override
public Double evaluate(final BatesGeneralizedJumpDiffusionModelDataBundle data) {
Validate.notNull(data);
final double s = data.getSpot();
final YieldAndDiscountCurve discountCurve = data.getInterestRateCurve();
final VolatilitySurface volSurface = data.getVolatilitySurface();
final ZonedDateTime date = data.getDate();
final double t = definition.getTimeToExpiry(date);
final double k = definition.getStrike();
final double sigma = data.getVolatility(t, k);
double b = data.getCostOfCarry();
final double lambda = data.getLambda();
final double expectedJumpSize = data.getExpectedJumpSize();
final double delta = data.getDelta();
final double gamma = Math.log(1 + expectedJumpSize);
final double sigmaSq = sigma * sigma;
double z;
final double lambdaT = lambda * t;
double mult = Math.exp(-lambdaT);
b -= lambda * expectedJumpSize;
StandardOptionDataBundle bsmData = new StandardOptionDataBundle(discountCurve, b, volSurface, s, date);
final Function1D<StandardOptionDataBundle, Double> bsmFunction = BSM.getPricingFunction(definition);
double price = mult * bsmFunction.evaluate(bsmData);
for (int i = 1; i < N; i++) {
z = Math.sqrt(sigmaSq + delta * delta * i / t);
b += gamma / t;
bsmData = bsmData.withVolatilitySurface(new VolatilitySurface(ConstantDoublesSurface.from(z))).withCostOfCarry(b);
mult *= lambdaT / i;
price += mult * bsmFunction.evaluate(bsmData);
}
return price;
}