/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.volatilityswap;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.financial.convention.frequency.PeriodFrequency;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* A volatility swap is a forward contract on the realised volatility of a generic underlying. This could be a single equity price, the value of an equity index,
* an FX rate or <b>any</b> other financial metric on which a volatility swap contract is based.<p>
*/
public class VolatilitySwap implements InstrumentDerivative {
/** Time to the start of volatility observations */
private final double _timeToObservationStart;
/** Time to the end of volatility observations */
private final double _timeToObservationEnd;
/** The observation frequency */
private final PeriodFrequency _observationFrequency;
/** Time to maturity */
private final double _timeToMaturity;
/** The volatility strike */
private final double _volStrike;
/** The volatility notional */
private final double _volNotional;
/** The currency */
private final Currency _currency;
/** The annualization factor */
private final double _annualizationFactor;
/**
* @param timeToObservationStart Time to first observation. Negative if observations have begun.
* @param timeToObservationEnd Time to final observation. Negative if observations have finished.
* @param observationFrequency The observation frequency, not null
* @param timeToMaturity Time of cash maturity. If negative, the swap has expired.
* @param volStrike Fair value of Variance struck at trade date
* @param volNotional Trade pays the difference between realized and strike variance multiplied by this
* @param currency Currency of cash maturity
* @param annualizationFactor Number of business days per year
*/
public VolatilitySwap(final double timeToObservationStart, final double timeToObservationEnd, final PeriodFrequency observationFrequency,
final double timeToMaturity, final double volStrike, final double volNotional, final Currency currency, final double annualizationFactor) {
ArgumentChecker.notNull(observationFrequency, "observationFrequency");
ArgumentChecker.notNull(currency, "currency");
_timeToObservationStart = timeToObservationStart;
_timeToObservationEnd = timeToObservationEnd;
_observationFrequency = observationFrequency;
_timeToMaturity = timeToMaturity;
_volStrike = volStrike;
_volNotional = volNotional;
_currency = currency;
_annualizationFactor = annualizationFactor;
}
/**
* Copy constructor
* @param other VarianceSwap to copy from
*/
public VolatilitySwap(final VolatilitySwap other) {
ArgumentChecker.notNull(other, "other");
_timeToObservationStart = other._timeToObservationStart;
_timeToObservationEnd = other._timeToObservationEnd;
_observationFrequency = other._observationFrequency;
_timeToMaturity = other._timeToMaturity;
_volStrike = other._volStrike;
_volNotional = other._volNotional;
_currency = other._currency;
_annualizationFactor = other._annualizationFactor;
}
/**
* Gets the time to the start of volatility observation.
* @return The time to the start of volatility observation
*/
public double getTimeToObservationStart() {
return _timeToObservationStart;
}
/**
* Gets the time to the end of volatility observation.
* @return The time to the end of volatility observation
*/
public double getTimeToObservationEnd() {
return _timeToObservationEnd;
}
/**
* Gets the observation frequency.
* @return The observation frequency
*/
public PeriodFrequency getObservationFrequency() {
return _observationFrequency;
}
/**
* Gets the time to maturity.
* @return The time to maturity
*/
public double getTimeToMaturity() {
return _timeToMaturity;
}
/**
* Gets the currency.
* @return the currency
*/
public Currency getCurrency() {
return _currency;
}
/**
* Gets the volatility strike.
* @return The volatility strike
*/
public double getVolatilityStrike() {
return _volStrike;
}
/**
* Gets the volatility notional.
* @return The volatility notional
*/
public double getVolatilityNotional() {
return _volNotional;
}
/**
* Gets the annualization factor.
* @return The annualization factor
*/
public double getAnnualizationFactor() {
return _annualizationFactor;
}
@Override
public <S, T> T accept(final InstrumentDerivativeVisitor<S, T> visitor, final S data) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitVolatilitySwap(this, data);
}
@Override
public <T> T accept(final InstrumentDerivativeVisitor<?, T> visitor) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitVolatilitySwap(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(_annualizationFactor);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + _currency.hashCode();
temp = Double.doubleToLongBits(_timeToObservationEnd);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_timeToObservationStart);
result = prime * result + _observationFrequency.hashCode();
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_timeToMaturity);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_volNotional);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_volStrike);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof VolatilitySwap)) {
return false;
}
final VolatilitySwap other = (VolatilitySwap) obj;
if (Double.doubleToLongBits(_annualizationFactor) != Double.doubleToLongBits(other._annualizationFactor)) {
return false;
}
if (_currency == null) {
if (other._currency != null) {
return false;
}
} else if (!_currency.equals(other._currency)) {
return false;
}
if (Double.doubleToLongBits(_timeToObservationEnd) != Double.doubleToLongBits(other._timeToObservationEnd)) {
return false;
}
if (Double.doubleToLongBits(_timeToObservationStart) != Double.doubleToLongBits(other._timeToObservationStart)) {
return false;
}
if (Double.doubleToLongBits(_timeToMaturity) != Double.doubleToLongBits(other._timeToMaturity)) {
return false;
}
if (Double.doubleToLongBits(_volNotional) != Double.doubleToLongBits(other._volNotional)) {
return false;
}
if (Double.doubleToLongBits(_volStrike) != Double.doubleToLongBits(other._volStrike)) {
return false;
}
if (!ObjectUtils.equals(_observationFrequency, other._observationFrequency)) {
return false;
}
return true;
}
}