/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.model.option.definition; import com.opengamma.analytics.financial.model.tree.ConstantRecombiningBinomialTree; import com.opengamma.analytics.financial.model.tree.RecombiningBinomialTree; /** * */ public class LeisenReimerBinomialOptionModelDefinition extends BinomialOptionModelDefinition<OptionDefinition, StandardOptionDataBundle> { @Override public double getDownFactor(final OptionDefinition option, final StandardOptionDataBundle data, final int n, final int j) { final double b = data.getCostOfCarry(); final double t = option.getTimeToExpiry(data.getDate()); final double dt = t / n; final double p = getUpProbabilityTree(option, data, n, j).getNode(0, 0); final double u = getUpFactor(option, data, n, j); return (Math.exp(b * dt) - p * u) / (1 - p); } @Override public RecombiningBinomialTree<Double> getUpProbabilityTree(final OptionDefinition option, final StandardOptionDataBundle data, final int n, final int j) { final double b = data.getCostOfCarry(); final double s = data.getSpot(); final double k = option.getStrike(); final double t = option.getTimeToExpiry(data.getDate()); final double sigma = data.getVolatility(t, k); final double d1 = getD1(s, k, t, sigma, b); final double d2 = getD2(d1, sigma, t); return new ConstantRecombiningBinomialTree<>(getH(d2, n)); } @Override public double getUpFactor(final OptionDefinition option, final StandardOptionDataBundle data, final int n, final int j) { final double b = data.getCostOfCarry(); final double s = data.getSpot(); final double k = option.getStrike(); final double t = option.getTimeToExpiry(data.getDate()); final double sigma = data.getVolatility(t, k); final double d1 = getD1(s, k, t, sigma, b); final double d2 = getD2(d1, sigma, t); final double dt = t / n; return Math.exp(b * dt) * getH(d1, n) / getH(d2, n); } private double getD1(final double s, final double k, final double t, final double sigma, final double b) { return (Math.log(s / k) + t * (b + sigma * sigma / 2)) / (sigma * Math.sqrt(t)); } private double getD2(final double d1, final double sigma, final double t) { return d1 - sigma * Math.sqrt(t); } private double getH(final double x, final double n) { final double eta = x >= 0 ? 1 : -1; final double a = Math.pow(x / (n + 1. / 3 + 0.1 / (n + 1)), 2); final double b = n + 1. / 6; return 0.5 + eta * Math.sqrt(0.25 * (1 - Math.exp(-a * b))); } }