final double qRates[] = { 0.04, 0.05, 0.06 };
final double rRates[] = { 0.01, 0.05, 0.15 };
final double residualTimes[] = { 1.0, 2.0 };
final double vols[] = { 0.11, 0.50, 1.20 };
final DayCounter dc = new Actual360();
new Settings().setEvaluationDate(Date.todaysDate());
final Date today = new Settings().evaluationDate();
final SimpleQuote spot = new SimpleQuote(0.0);
final SimpleQuote qRate = new SimpleQuote(0.0);
final YieldTermStructure qTS = Utilities.flatRate(qRate, dc);
final SimpleQuote rRate = new SimpleQuote(0.0);
final YieldTermStructure rTS = Utilities.flatRate(rRate, dc);
final SimpleQuote vol = new SimpleQuote(0.0);
final BlackVolTermStructure volTS = Utilities.flatVol(vol, dc);
for (final Type type : types) {
for (final double strike : strikes) {
for (final double residualTime : residualTimes) {
final Date exDate = today.add( timeToDays(residualTime) ); //TODO: code review
final Exercise exercise = new EuropeanExercise(exDate);
for (int kk=0; kk<4; kk++) {
StrikedTypePayoff payoff = null;
// option to check
if (kk==0) {
payoff = new PlainVanillaPayoff(type, strike);
} else if (kk==1) {
//FIXME check constructor
payoff = new CashOrNothingPayoff(type, strike, 100);
} else if (kk==2) {
payoff = new AssetOrNothingPayoff(type, strike);
} else if (kk==3) {
payoff = new GapPayoff(type, strike, 100);
}
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);
if (payoff==null)
throw new IllegalArgumentException();
final EuropeanOption option = new EuropeanOption(payoff, exercise);
option.setPricingEngine(engine);
for (final double u : underlyings) {
for (final double q : qRates) {
for (final double r : rRates) {
for (final double v : vols) {
//something wrong here for vanilla payoff?
spot.setValue(u);
qRate.setValue(q);
rRate.setValue(r);
vol.setValue(v);
final double value = option.NPV();
final double delta = option.delta();
final double gamma = option.gamma();
final double theta = option.theta();
final double rho = option.rho();
final double drho = option.dividendRho();
final double vega = option.vega();
calculated.put("delta", delta);
calculated.put("gamma", gamma);
calculated.put("theta", theta);
calculated.put("rho", rho);
calculated.put("divRho", drho);
calculated.put("vega", vega);
if (value > spot.value()*1.0e-5) {
// perturb spot and get delta and gamma
final double du = u*1.0e-4;
spot.setValue(u+du);
double value_p = option.NPV();
final double delta_p = option.delta();
spot.setValue(u-du);
double value_m = option.NPV();
final double delta_m = option.delta();
spot.setValue(u);
expected.put("delta", (value_p - value_m)/(2*du));
expected.put("gamma", (delta_p - delta_m)/(2*du));
// perturb rates and get rho and dividend rho
final double dr = r*1.0e-4;
rRate.setValue(r+dr);
value_p = option.NPV();
rRate.setValue(r-dr);
value_m = option.NPV();
rRate.setValue(r);
expected.put("rho", (value_p - value_m)/(2*dr));
final double dq = q*1.0e-4;
qRate.setValue(q+dq);
value_p = option.NPV();
qRate.setValue(q-dq);
value_m = option.NPV();
qRate.setValue(q);
expected.put("divRho",(value_p - value_m)/(2*dq));
// perturb volatility and get vega
final double dv = v*1.0e-4;
vol.setValue(v+dv);
value_p = option.NPV();
vol.setValue(v-dv);
value_m = option.NPV();
vol.setValue(v);
expected.put("vega",(value_p - value_m)/(2*dv));
// perturb date and get theta
final Date yesterday = today.sub(1);
final Date tomorrow = today.add(1);
final double dT = dc.yearFraction(yesterday, tomorrow);
new Settings().setEvaluationDate(yesterday);
value_m = option.NPV();
new Settings().setEvaluationDate(tomorrow);
value_p = option.NPV();
new Settings().setEvaluationDate(Date.todaysDate());