for (int i=0; i<values.length-1; i++) {
QL.debug(values[i].toString());
final StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike);
final Date exDate = today.add( timeToDays(values[i].t) );
final Exercise exercise = new EuropeanExercise(exDate);
spot.setValue(values[i].s);
qRate.setValue(values[i].q);
rRate.setValue(values[i].r);
vol.setValue(values[i].v);
final BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(
new Handle<Quote>(spot),
new Handle<YieldTermStructure>(qTS),
new Handle<YieldTermStructure>(rTS),
new Handle<BlackVolTermStructure>(volTS));
final PricingEngine engine = new AnalyticEuropeanEngine(stochProcess);
final EuropeanOption option = new EuropeanOption(payoff, exercise);
option.setPricingEngine(engine);
final double calculated = option.NPV();
final double error = Math.abs(calculated-values[i].result);
final double tolerance = values[i].tol;
final StringBuilder sb = new StringBuilder();
sb.append("error ").append(error).append(" .gt. tolerance ").append(tolerance).append('\n');
sb.append(" calculated ").append(calculated).append('\n');
sb.append(" type ").append(values[i].type).append('\n');
sb.append(" strike ").append(values[i].strike).append('\n');
sb.append(" s ").append(values[i].s).append('\n');
sb.append(" q ").append(values[i].q).append('\n');
sb.append(" r ").append(values[i].r).append('\n');
sb.append(" t ").append(values[i].t).append('\n');
sb.append(" v ").append(values[i].v).append('\n');
sb.append(" result ").append(values[i].result).append('\n');
sb.append(" tol ").append(values[i].tol); // .append('\n');
if (error<=tolerance) {
QL.info(" error="+error);
} else {
fail(exercise + " " + payoff.optionType() + " option with " + payoff + " payoff:\n"
+ " spot value: " + values[i].s + "\n"
+ " strike: " + payoff.strike() + "\n"
+ " dividend yield: " + values[i].q + "\n"
+ " risk-free rate: " + values[i].r + "\n"
+ " reference date: " + today + "\n"
+ " maturity: " + values[i].t + "\n"
+ " volatility: " + values[i].v + "\n\n"