/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.equity.trs.definition;
import org.apache.commons.lang.ObjectUtils;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.equity.Equity;
import com.opengamma.analytics.financial.equity.EquityDefinition;
import com.opengamma.analytics.financial.instrument.InstrumentDefinitionVisitor;
import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinition;
import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition;
import com.opengamma.analytics.financial.instrument.swap.TotalReturnSwapDefinition;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.util.time.TimeCalculator;
import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* Description of an equity total return swap.
*/
public class EquityTotalReturnSwapDefinition extends TotalReturnSwapDefinition {
/** The notional amount */
private final double _notionalAmount;
/** The notional currency */
private final Currency _notionalCurrency;
/** The dividend percentage */
private final double _dividendPercentage;
/**
* @param effectiveDate The effective date.
* @param terminationDate The termination date.
* @param fundingLeg The funding leg, not null
* @param equity The equity, not null
* @param notionalAmount The notional amount
* @param notionalCurrency The notional currency, not null
* @param dividendPercentage The dividend percentage received, >= 0 and <= 1
*/
public EquityTotalReturnSwapDefinition(final ZonedDateTime effectiveDate, final ZonedDateTime terminationDate,
final AnnuityDefinition<? extends PaymentDefinition> fundingLeg, final EquityDefinition equity,
final double notionalAmount, final Currency notionalCurrency, final double dividendPercentage) {
super(effectiveDate, terminationDate, fundingLeg, equity);
ArgumentChecker.notNull(notionalCurrency, "notionalCurrency");
ArgumentChecker.isTrue(ArgumentChecker.isInRangeInclusive(0, 1, dividendPercentage), "Dividend percentage must be >= 0 and <= 1 "
+ "have {}", dividendPercentage);
_dividendPercentage = dividendPercentage;
_notionalAmount = notionalAmount;
_notionalCurrency = notionalCurrency;
}
/**
* Gets the dividend percentage.
* @return The dividend percentage
*/
public double getDividendPercentage() {
return _dividendPercentage;
}
/**
* Gets the notional amount.
* @return The notional amount
*/
public double getNotionalAmount() {
return _notionalAmount;
}
/**
* Gets the notional currency.
* @return The notional currency
*/
public Currency getNotionalCurrency() {
return _notionalCurrency;
}
@Override
public <U, V> V accept(final InstrumentDefinitionVisitor<U, V> visitor, final U data) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitEquityTotalReturnSwapDefinition(this, data);
}
@Override
public <V> V accept(final InstrumentDefinitionVisitor<?, V> visitor) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitEquityTotalReturnSwapDefinition(this);
}
@Override
public EquityTotalReturnSwap toDerivative(final ZonedDateTime date, final ZonedDateTimeDoubleTimeSeries data) {
final double effectiveTime = TimeCalculator.getTimeBetween(date, getEffectiveDate());
final double terminationTime = TimeCalculator.getTimeBetween(date, getTerminationDate());
final Annuity<? extends Payment> fundingLeg = getFundingLeg().toDerivative(date, data);
final Equity equity = (Equity) getAsset().toDerivative(date);
return new EquityTotalReturnSwap(effectiveTime, terminationTime, fundingLeg, equity, _notionalAmount, _notionalCurrency, _dividendPercentage);
}
@Override
public EquityTotalReturnSwap toDerivative(final ZonedDateTime date) {
final double effectiveTime = TimeCalculator.getTimeBetween(date, getEffectiveDate());
final double terminationTime = TimeCalculator.getTimeBetween(date, getTerminationDate());
final Annuity<? extends Payment> fundingLeg = getFundingLeg().toDerivative(date);
final Equity equity = (Equity) getAsset().toDerivative(date);
return new EquityTotalReturnSwap(effectiveTime, terminationTime, fundingLeg, equity, _notionalAmount, _notionalCurrency, _dividendPercentage);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
long temp;
temp = Double.doubleToLongBits(_dividendPercentage);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_notionalAmount);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + _notionalCurrency.hashCode();
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 (!(obj instanceof EquityTotalReturnSwapDefinition)) {
return false;
}
final EquityTotalReturnSwapDefinition other = (EquityTotalReturnSwapDefinition) obj;
if (Double.compare(_notionalAmount, other._notionalAmount) != 0) {
return false;
}
if (!ObjectUtils.equals(_notionalCurrency, other._notionalCurrency)) {
return false;
}
if (Double.compare(_dividendPercentage, other._dividendPercentage) != 0) {
return false;
}
return true;
}
}