BatesGeneralizedJumpDiffusionModel extends AnalyticOptionModel<OptionDefinition, BatesGeneralizedJumpDiffusionModelDataBundle> { @Override public Function1D<BatesGeneralizedJumpDiffusionModelDataBundle, Double> getPricingFunction(final OptionDefinition definition) { Validate.notNull(definition); final Function1D<BatesGeneralizedJumpDiffusionModelDataBundle, Double> pricingFunction = new Function1D<BatesGeneralizedJumpDiffusionModelDataBundle, Double>() { @SuppressWarnings("synthetic-access") @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; } }; return pricingFunction; }  @Override Function1D<BatesGeneralizedJumpDiffusionModelDataBundle, Double> getPricingFunction(final OptionDefinition definition);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL.getPricingFunction(new EuropeanVanillaOptionDefinition(100, EXPIRY1, true)).evaluate((BatesGeneralizedJumpDiffusionModelDataBundle) null); }
@Test public void test() { OptionDefinition call = new EuropeanVanillaOptionDefinition(80, EXPIRY1, true); BatesGeneralizedJumpDiffusionModelDataBundle data = new BatesGeneralizedJumpDiffusionModelDataBundle(CURVE, B, SURFACE, SPOT, DATE, 0., -0.04, 0.); assertEquals(BSM.getPricingFunction(call).evaluate(data), MODEL.getPricingFunction(call).evaluate(data), EPS2); call = new EuropeanVanillaOptionDefinition(80, EXPIRY1, true); data = data.withLambda(1.).withDelta(0.1); assertEquals(20.67, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(90, EXPIRY2, true); data = data.withLambda(5.); assertEquals(14.13, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(100, EXPIRY3, true); data = data.withLambda(10.); assertEquals(13.62, MODEL.getPricingFunction(call).evaluate(data), EPS1); data = data.withDelta(0.25); data = data.withLambda(1.); call = new EuropeanVanillaOptionDefinition(90, EXPIRY1, true); assertEquals(11.57, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(100, EXPIRY2, true); data = data.withLambda(5.); assertEquals(12.25, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(110, EXPIRY3, true); data = data.withLambda(10.); assertEquals(20.43, MODEL.getPricingFunction(call).evaluate(data), EPS1); data = data.withDelta(0.5); data = data.withLambda(1.); call = new EuropeanVanillaOptionDefinition(100, EXPIRY1, true); assertEquals(5.18, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(110, EXPIRY2, true); data = data.withLambda(5.); assertEquals(16.52, MODEL.getPricingFunction(call).evaluate(data), EPS1); call = new EuropeanVanillaOptionDefinition(120, EXPIRY3, true); data = data.withLambda(10.); assertEquals(37.03, MODEL.getPricingFunction(call).evaluate(data), EPS1); }