AnalyticOptionModel implements OptionModel<T, U> { @Override public GreekResultCollection getGreeks(final T definition, final U data, final Set<Greek> requiredGreeks) { Validate.notNull(definition); Validate.notNull(data); Validate.notNull(requiredGreeks); final Function1D<U, Double> pricingFunction = getPricingFunction(definition); final GreekResultCollection results = new GreekResultCollection(); final GreekVisitor<Double> visitor = getGreekVisitor(pricingFunction, data, definition); for (final Greek greek : requiredGreeks) { final Double result = greek.accept(visitor); results.put(greek, result); } return results; }  abstract Function1D<U, Double> getPricingFunction(T definition); GreekVisitor<Double> getGreekVisitor(final Function1D<U, Double> pricingFunction, final U data, final T definition); @Override GreekResultCollection getGreeks(final T definition, final U data, final Set<Greek> requiredGreeks);  }
@Test public void testFiniteDifferenceAgainstBSM() { final Set<Greek> greekTypes = new HashSet<>(Greek.getAllGreeks()); greekTypes.remove(Greek.DRIFTLESS_THETA); greekTypes.remove(Greek.STRIKE_DELTA); greekTypes.remove(Greek.STRIKE_GAMMA); greekTypes.remove(Greek.DUAL_DELTA); greekTypes.remove(Greek.DUAL_GAMMA); greekTypes.remove(Greek.ZETA); greekTypes.remove(Greek.ZETA_BLEED); GreekResultCollection bsm = BSM.getGreeks(PUT, DATA, greekTypes); GreekResultCollection finiteDifference = DUMMY_MODEL.getGreeks(PUT, DATA, greekTypes); assertResults(finiteDifference, bsm); bsm = BSM.getGreeks(CALL, DATA, greekTypes); finiteDifference = DUMMY_MODEL.getGreeks(CALL, DATA, greekTypes); assertResults(finiteDifference, bsm); }