/**
* 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 org.apache.commons.lang.Validate;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.time.Expiry;
/**
* Class defining a supershare option.
* <p>
* Supershare options have European-style exercise with payoff
* $$
* \begin{align*}
* \mathrm{payoff} =
* \begin{cases}
* \frac{S}{K_L} \quad & \mathrm{if} \quad K_L \leq S \leq K_H\\
* 0\quad & \mathrm{otherwise}
* \end{cases}
* \end{align*}
* $$
* where $K_L$ is the lower bound, $K_H$ the upper bound and $S$ the spot.
*/
public class SupershareOptionDefinition extends OptionDefinition {
private final OptionExerciseFunction<StandardOptionDataBundle> _exerciseFunction = new EuropeanExerciseFunction<>();
private final OptionPayoffFunction<StandardOptionDataBundle> _payoffFunction = new OptionPayoffFunction<StandardOptionDataBundle>() {
@SuppressWarnings("synthetic-access")
@Override
public double getPayoff(final StandardOptionDataBundle data, final Double optionPrice) {
Validate.notNull(data, "data");
final double s = data.getSpot();
return ArgumentChecker.isInRangeExcludingHigh(_lowerBound, _upperBound, s) ? s / _lowerBound : 0;
}
};
private final double _lowerBound;
private final double _upperBound;
/**
* @param expiry The expiry
* @param lowerBound The lower bound
* @param upperBound The upper bound
*/
public SupershareOptionDefinition(final Expiry expiry, final double lowerBound, final double upperBound) {
super(null, expiry, null);
Validate.isTrue(lowerBound >= 0, "lower bound must be >= 0");
Validate.isTrue(upperBound >= 0, "upper bound must be >= 0");
Validate.isTrue(upperBound > lowerBound, "Lower bound must be less than upper bound");
_lowerBound = lowerBound;
_upperBound = upperBound;
}
/**
* {@inheritDoc}
*/
@Override
public OptionExerciseFunction<StandardOptionDataBundle> getExerciseFunction() {
return _exerciseFunction;
}
/**
* {@inheritDoc}
*/
@Override
public OptionPayoffFunction<StandardOptionDataBundle> getPayoffFunction() {
return _payoffFunction;
}
/**
* @return The lower bound
*/
public double getLowerBound() {
return _lowerBound;
}
/**
* @return The upper bound
*/
public double getUpperBound() {
return _upperBound;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
long temp;
temp = Double.doubleToLongBits(_lowerBound);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_upperBound);
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 SupershareOptionDefinition other = (SupershareOptionDefinition) obj;
if (Double.doubleToLongBits(_lowerBound) != Double.doubleToLongBits(other._lowerBound)) {
return false;
}
if (Double.doubleToLongBits(_upperBound) != Double.doubleToLongBits(other._upperBound)) {
return false;
}
return true;
}
}