/**
* 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.twoasset;
import org.apache.commons.lang.Validate;
import com.opengamma.analytics.financial.model.option.definition.EuropeanExerciseFunction;
import com.opengamma.analytics.financial.model.option.definition.OptionDefinition;
import com.opengamma.analytics.financial.model.option.definition.OptionExerciseFunction;
import com.opengamma.analytics.financial.model.option.definition.OptionPayoffFunction;
import com.opengamma.util.time.Expiry;
/**
* Defines a European-style two-asset correlation option.
* <p>
* The payoff of a two-asset correlation call option is:
* $$
* \begin{eqnarray*}
* max\left(S_2 - P, 0\right) \quad\quad\text{if}\quad S_1 > K
* \end{eqnarray*}
* $$
* and 0 otherwise. The payoff of a put is:
* $$
* \begin{eqnarray*}
* max\left(P - S_2, 0\right) \quad\quad\text{if}\quad S_1 < K
* \end{eqnarray*}
* $$
* and 0 otherwise, where $K$ is the strike, $P$ is the payout level, $S_1$ is
* the spot price of the first underlying and $S_2$ is the spot price of the
* second underlying.
*/
public class TwoAssetCorrelationOptionDefinition extends OptionDefinition {
private final OptionExerciseFunction<StandardTwoAssetOptionDataBundle> _exerciseFunction = new EuropeanExerciseFunction<>();
private final OptionPayoffFunction<StandardTwoAssetOptionDataBundle> _payoffFunction = new OptionPayoffFunction<StandardTwoAssetOptionDataBundle>() {
@Override
public double getPayoff(final StandardTwoAssetOptionDataBundle data, final Double optionPrice) {
Validate.notNull(data, "data");
final double s1 = data.getFirstSpot();
final double s2 = data.getSecondSpot();
final double k = getStrike();
final double p = getPayoutLevel();
if (isCall()) {
return s1 > k ? Math.max(s2 - p, 0) : 0;
}
return s1 < k ? Math.max(p - s2, 0) : 0;
}
};
private final double _payoutLevel;
/**
*
* @param strike The strike
* @param expiry The expiry
* @param isCall Is the option a call
* @param payoutLevel The payout level of the option
*/
public TwoAssetCorrelationOptionDefinition(final double strike, final Expiry expiry, final boolean isCall, final double payoutLevel) {
super(strike, expiry, isCall);
_payoutLevel = payoutLevel;
}
/**
* The exercise function of this option is European (see {@link EuropeanExerciseFunction})
* @return The exercise function
*/
@SuppressWarnings("unchecked")
@Override
public OptionExerciseFunction<StandardTwoAssetOptionDataBundle> getExerciseFunction() {
return _exerciseFunction;
}
/**
* @return The payoff function
*/
@SuppressWarnings("unchecked")
@Override
public OptionPayoffFunction<StandardTwoAssetOptionDataBundle> getPayoffFunction() {
return _payoffFunction;
}
/**
*
* @return The payout level
*/
public double getPayoutLevel() {
return _payoutLevel;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
long temp;
temp = Double.doubleToLongBits(_payoutLevel);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TwoAssetCorrelationOptionDefinition other = (TwoAssetCorrelationOptionDefinition) obj;
if (Double.doubleToLongBits(_payoutLevel) != Double.doubleToLongBits(other._payoutLevel)) {
return false;
}
return true;
}
}