/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.model.option.pricing.tree;
import org.apache.commons.lang.Validate;
/**
*
* The formula is valid for odd number of steps.
* The even case is NOT implemented (Since formula for even number of steps has the convergence of order -1, there is no advantage to use Leisen-Reimer.)
*/
public class LeisenReimerLatticeSpecification extends LatticeSpecification {
@Override
public double[] getParameters(final double spot, final double strike, final double timeToExpiry, final double volatility, final double interestRate, final int nSteps, final double dt) {
Validate.isTrue((nSteps % 2 == 1), "The number of steps should be odd");
final double sigmaRootT = volatility * Math.sqrt(timeToExpiry);
final double d1 = (Math.log(spot / strike) + interestRate * timeToExpiry) / sigmaRootT + 0.5 * sigmaRootT;
final double d2 = d1 - sigmaRootT;
final double sig1 = d1 >= 0. ? 1. : -1.;
final double sig2 = d2 >= 0. ? 1. : -1.;
final double coef1 = d1 / (nSteps + 1. / 3. + 0.1 / (nSteps + 1.));
final double coef2 = d2 / (nSteps + 1. / 3. + 0.1 / (nSteps + 1.));
final double p1 = 0.5 + sig1 * 0.5 * Math.sqrt(1. - Math.exp(-coef1 * coef1 * (nSteps + 1. / 6.)));
final double p2 = 0.5 + sig2 * 0.5 * Math.sqrt(1. - Math.exp(-coef2 * coef2 * (nSteps + 1. / 6.)));
final double rr = Math.exp(interestRate * dt);
final double upFactor = rr * p1 / p2;
final double downFactor = (rr - p2 * upFactor) / (1 - p2);
return new double[] {upFactor, downFactor, p2, 1 - p2 };
}
}