@Test public void ImpliedTreeEuropeanRecoveryTest() { final double interest = 0.06; final YieldAndDiscountCurve yCrv = YieldCurve.from(ConstantDoublesCurve.from(interest)); final double cost = 0.02; final double atmVol = 0.47; final ZonedDateTime date = DateUtils.getUTCDate(2010, 7, 1); final double spot = 100; final Function<Double, Double> smile = new Function<Double, Double>() { @Override public Double evaluate(final Double... tk) { ArgChecker.isTrue(tk.length == 2); final double k = tk[1]; return atmVol + (spot - k) * 0.0005; } }; final StandardOptionDataBundle data = new StandardOptionDataBundle( yCrv, cost, new VolatilitySurface(FunctionalDoublesSurface.from(smile)), spot, date); final double[] strikes = new double[] {spot * 0.9, spot, spot * 1.11}; final int nSteps = 7; final double time = 1.; for (int i = 0; i < strikes.length; ++i) { final double strike = strikes[i]; final boolean isCall = strike >= spot ? true : false; final OptionFunctionProvider1D function = new EuropeanVanillaOptionFunctionProvider(strike, time, nSteps, isCall); final double tree = _modelTrinomial.getPrice(function, data); final double black = BlackScholesFormulaRepository.price( spot, strike * 0.9, time, data.getVolatility(time, strike), interest, cost, isCall); assertEquals(tree, black, black * 0.2); } try { _model.getPrice( new EuropeanVanillaOptionFunctionProvider(strikes[2], time, nSteps, true), data); throw new RuntimeException(); } catch (Exception e) { assertTrue(e instanceof IllegalArgumentException); } }
@Test public void test() { assertEquals(MODEL.getPricingFunction(END).evaluate(DATA), 0, 0); assertEquals( MODEL .getPricingFunction(FORWARD) .evaluate( DATA.withVolatilitySurface( new VolatilitySurface(ConstantDoublesSurface.from(1e-9)))), 0, 0); assertEquals( MODEL.getPricingFunction(NOW).evaluate(DATA), BSM.getPricingFunction(VANILLA).evaluate(DATA), 1e-4); assertEquals(MODEL.getPricingFunction(FORWARD).evaluate(DATA), 4.4064, 1e-4); }