/**
* 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.pricing.analytic.twoasset;
import org.apache.commons.lang.Validate;
import com.opengamma.analytics.financial.model.option.definition.twoasset.StandardTwoAssetOptionDataBundle;
import com.opengamma.analytics.financial.model.option.definition.twoasset.TwoAssetCorrelationOptionDefinition;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.statistics.distribution.BivariateNormalDistribution;
import com.opengamma.analytics.math.statistics.distribution.ProbabilityDistribution;
/**
*
* The value of a two-asset correlation call option is:
* $$
* \begin{eqnarray*}
* c = S_2 e ^ {(b_2 - r)T} M(y_2 + \sigma_2\sqrt{T}, y_1 + \rho\sigma_2\sqrt{T}; \rho) - P e^{-rT} M(y_2, y_1; \rho)
* \end{eqnarray*}
* $$
* and that of a put is:
* $$
* \begin{eqnarray*}
* p = P e^{-rT} M(-y_2, -y_1; \rho) - S_2 e^{(b_2 - r)T} M(-y_2 - \sigma_2\sqrt{T}, -y_1 - \rho\sigma_2\sqrt{T}; \rho)
* \end{eqnarray*}
* $$
* where
* $$
* \begin{eqnarray*}
* y_1 &=& \frac{\ln{\frac{S_1}{K_1}} + (b_1 - \frac{\sigma_1^2}{2})T}{\sigma_1\sqrt{T}}\\
* y_2 &=& \frac{\ln{\frac{S_2}{P}} + (b_2 - \frac{\sigma_2^2}{2})T}{\sigma_2\sqrt{T}}
* \end{eqnarray*}
* $$
* and
* $$
* <ul>
* <li>$K$ is the strike</li>
* <li>$P$ is the payoff</li>
* <li>$S_1$ is the spot value of the first asset</li>
* <li>$S_2$ is the spot value of the second asset</li>
* <li>$b_1$ is the cost-of-carry of the first asset</li>
* <li>$b_2$ is the cost-of-carry of the second asset</li>
* <li>$T$ is the time to expiry of the option</li>
* <li>$r$ is the spot interest rate for time $T$</li>
* <li>$\sigma_1$ is the annualized volatility of the first asset</li>
* <li>$\sigma_2$ is the annualized volatility of the second asset</li>
* <li>$\rho$ is the correlation between the returns of the two assets</li>
* <li>$M(x, y; \rho)$ is the CDF of the bivariate normal distribution </li>
* </ul>
*/
public class TwoAssetCorrelationOptionModel extends TwoAssetAnalyticOptionModel<TwoAssetCorrelationOptionDefinition, StandardTwoAssetOptionDataBundle> {
private static final ProbabilityDistribution<double[]> BIVARIATE = new BivariateNormalDistribution();
/**
* Gets the pricing function for a European-style two-asset correlation option
* @param definition The option definition
* @return The pricing function
* @throws IllegalArgumentException If the definition is null
*/
@Override
public Function1D<StandardTwoAssetOptionDataBundle, Double> getPricingFunction(final TwoAssetCorrelationOptionDefinition definition) {
Validate.notNull(definition, "definition");
return new Function1D<StandardTwoAssetOptionDataBundle, Double>() {
@SuppressWarnings("synthetic-access")
@Override
public Double evaluate(final StandardTwoAssetOptionDataBundle data) {
Validate.notNull(data, "data");
final double s1 = data.getFirstSpot();
final double s2 = data.getSecondSpot();
final double k = definition.getStrike();
final double payout = definition.getPayoutLevel();
final double b1 = data.getFirstCostOfCarry();
final double b2 = data.getSecondCostOfCarry();
final double t = definition.getTimeToExpiry(data.getDate());
final double r = data.getInterestRate(t);
final double sigma1 = data.getFirstVolatility(t, k);
final double sigma2 = data.getSecondVolatility(t, k);
final double rho = data.getCorrelation();
final double tSqrt = Math.sqrt(t);
final double sigmaT1 = sigma1 * tSqrt;
final double sigmaT2 = sigma2 * tSqrt;
final double d1 = (Math.log(s1 / k) + t * (b1 - sigma1 * sigma1 / 2)) / sigmaT1;
final double d2 = (Math.log(s2 / payout) + t * (b2 - sigma2 * sigma2 / 2)) / sigmaT2;
final double df1 = Math.exp(t * (b2 - r));
final double df2 = Math.exp(-r * t);
final int sign = definition.isCall() ? 1 : -1;
return sign * (s2 * df1 * BIVARIATE.getCDF(new double[] {sign * (d2 + sigmaT2), sign * (d1 + rho * sigmaT2), rho}) - payout * df2 * BIVARIATE.getCDF(new double[] {sign * d2, sign * d1, rho}));
}
};
}
}