FadeInOptionModel extends AnalyticOptionModel<FadeInOptionDefinition, StandardOptionWithSpotTimeSeriesDataBundle> { @Override public Function1D<StandardOptionWithSpotTimeSeriesDataBundle, Double> getPricingFunction(final FadeInOptionDefinition definition) { Validate.notNull(definition, "definition"); return new Function1D<StandardOptionWithSpotTimeSeriesDataBundle, Double>() { @SuppressWarnings("synthetic-access") @Override public Double evaluate(final StandardOptionWithSpotTimeSeriesDataBundle data) { Validate.notNull(data, "data"); final double s = data.getSpot(); final double k = definition.getStrike(); final double b = data.getCostOfCarry(); final ZonedDateTime date = data.getDate(); final double t = definition.getTimeToExpiry(date); final double r = data.getInterestRate(t); final double sigma = data.getVolatility(t, k); final double l = definition.getLowerBound(); final double u = definition.getUpperBound(); final double n = data.getSpotTimeSeries().size(); final double df1 = Math.exp(t * (b - r)); final double df2 = Math.exp(-r * t); final int sign = definition.isCall() ? 1 : -1; double rho, tI, d1, d2, d3, d4, d5, d6; double price = 0; for (int i = 0; i < n; i++) { tI = i * t / n; rho = -sign * Math.sqrt(tI / t); d1 = getD1(s, k, t, sigma, b); d2 = getD2(d1, sigma, t); d3 = getD1(s, l, tI, sigma, b); d4 = getD2(d3, sigma, tI); d5 = getD1(s, u, tI, sigma, b); d6 = getD2(d5, sigma, tI); price += sign * (s * df1 * (BIVARIATE_NORMAL.getCDF(new double[] {-d5, sign * d1, rho}) - BIVARIATE_NORMAL.getCDF(new double[] {-d3, sign * d1, rho})) - k * df2 * (BIVARIATE_NORMAL.getCDF(new double[] {-d6, sign * d2, rho}) - BIVARIATE_NORMAL.getCDF(new double[] {-d4, sign * d2, rho}))); } return price / n; } }; }  @Override Function1D<StandardOptionWithSpotTimeSeriesDataBundle, Double> getPricingFunction(final FadeInOptionDefinition definition);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL.getPricingFunction(DEFINITION).evaluate((StandardOptionWithSpotTimeSeriesDataBundle) null); }
@Test public void testAgainstBSM() { final double eps = 1e-6; FadeInOptionDefinition definition = new FadeInOptionDefinition(SPOT, EXPIRY, false, 20, 180); final StandardOptionWithSpotTimeSeriesDataBundle data = DATA.withVolatilitySurface(new VolatilitySurface(ConstantDoublesSurface.from(0))); assertEquals(BSM.getPricingFunction(definition).evaluate(data), MODEL.getPricingFunction(definition).evaluate(data), eps); definition = new FadeInOptionDefinition(SPOT, EXPIRY, true, 95, 105); assertEquals(BSM.getPricingFunction(definition).evaluate(data), MODEL.getPricingFunction(definition).evaluate(data), eps); definition = new FadeInOptionDefinition(SPOT, EXPIRY, false, 95, 105); assertEquals(BSM.getPricingFunction(definition).evaluate(data), MODEL.getPricingFunction(definition).evaluate(data), eps); }
@Test public void test() { StandardOptionWithSpotTimeSeriesDataBundle data = DATA; FadeInOptionDefinition definition = new FadeInOptionDefinition(SPOT, EXPIRY, true, 85, 115); assertEquals(MODEL.getPricingFunction(definition).evaluate(data), 2.58, 1e-2); data = DATA.withVolatilitySurface(new VolatilitySurface(ConstantDoublesSurface.from(0.4))); definition = new FadeInOptionDefinition(SPOT, EXPIRY, true, 95, 105); assertEquals(MODEL.getPricingFunction(definition).evaluate(data), 2.036, 1e-3); }