/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.payments.derivative;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.analytics.financial.instrument.index.IndexON;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* Class describing a Fed Fund swap-like floating coupon (arithmetic average on overnight rates).
*/
public final class CouponONArithmeticAverageSpreadSimplified extends Coupon {
/**
* The overnight index on which the coupon fixes. The index currency should be the same as the coupon currency. Not null.
*/
private final IndexON _index;
/**
* The fixing period start time (in years).
*/
private final double _fixingPeriodStartTime;
/**
* The fixing period end time (in years).
*/
private final double _fixingPeriodEndTime;
/**
* The fixing period end time (in years).
*/
private final double _fixingPeriodAccrualFactor;
/**
* The spread rate paid above the arithmetic average.
*/
private final double _spread;
/**
* The fixed amount related to the spread.
*/
private final double _spreadAmount;
/**
* Constructor.
* @param currency The coupon currency.
* @param paymentTime The coupon payment time.
* @param notional The coupon notional.
* @param index The index associated to the coupon.
* @param fixingPeriodStartTime The fixing period start time (in years).
* @param fixingPeriodEndTime The fixing period end time (in years).
* @param fixingPeriodAccrualFactor The fixing period accrual factor.
* @param spread The spread rate paid above the arithmetic average.
* @param paymentAccrualFactor The year fraction of the full coupon.
*/
private CouponONArithmeticAverageSpreadSimplified(Currency currency, double paymentTime, double paymentYearFraction, double notional, IndexON index, final double fixingPeriodStartTime,
double fixingPeriodEndTime, double fixingPeriodAccrualFactor, final double spread) {
super(currency, paymentTime, paymentYearFraction, notional);
_index = index;
_fixingPeriodStartTime = fixingPeriodStartTime;
_fixingPeriodEndTime = fixingPeriodEndTime;
_fixingPeriodAccrualFactor = fixingPeriodAccrualFactor;
_spread = spread;
_spreadAmount = spread * paymentYearFraction * notional;
}
/**
* Builder from financial details.
* @param paymentTime The coupon payment time.
* @param paymentAccrualFactor The year fraction of the full coupon.
* @param notional The coupon notional.
* @param index The index associated to the coupon.
* @param fixingPeriodStartTime The fixing period start time (in years).
* @param fixingPeriodEndTime The fixing period end time (in years).
* @param fixingPeriodAccrualFactor The fixing period accrual factor.
* @param spread The spread rate paid above the arithmetic average.
* @return The coupon.
*/
public static CouponONArithmeticAverageSpreadSimplified from(double paymentTime, double paymentAccrualFactor, double notional, IndexON index, final double fixingPeriodStartTime,
double fixingPeriodEndTime, double fixingPeriodAccrualFactor, final double spread) {
ArgumentChecker.notNull(index, "Index");
return new CouponONArithmeticAverageSpreadSimplified(index.getCurrency(), paymentTime, paymentAccrualFactor, notional, index, fixingPeriodStartTime, fixingPeriodEndTime,
fixingPeriodAccrualFactor, spread);
}
/**
* Gets the index.
* @return The index.
*/
public IndexON getIndex() {
return _index;
}
/**
* Returns the spread rate paid above the arithmetic average.
* @return The spread.
*/
public double getSpread() {
return _spread;
}
/**
* Returns the fixed amount related to the spread.
* @return The amount.
*/
public double getSpreadAmount() {
return _spreadAmount;
}
/**
* Returns the fixing period start time (in years).
* @return The time.
*/
public double getFixingPeriodStartTime() {
return _fixingPeriodStartTime;
}
/**
* Returns the fixing period end time (in years).
* @return The time.
*/
public double getFixingPeriodEndTime() {
return _fixingPeriodEndTime;
}
/**
* Returns the fixing period accrual factor.
* @return The factor.
*/
public double getFixingPeriodAccrualFactor() {
return _fixingPeriodAccrualFactor;
}
@Override
public Coupon withNotional(double notional) {
return null; // TODO
}
@Override
public <S, T> T accept(InstrumentDerivativeVisitor<S, T> visitor, S data) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitCouponONArithmeticAverageSpreadSimplified(this, data);
}
@Override
public <T> T accept(InstrumentDerivativeVisitor<?, T> visitor) {
ArgumentChecker.notNull(visitor, "visitor");
return visitor.visitCouponONArithmeticAverageSpreadSimplified(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
long temp;
temp = Double.doubleToLongBits(_fixingPeriodEndTime);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_fixingPeriodStartTime);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + _index.hashCode();
temp = Double.doubleToLongBits(_spread);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(_spreadAmount);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CouponONArithmeticAverageSpreadSimplified other = (CouponONArithmeticAverageSpreadSimplified) obj;
if (Double.doubleToLongBits(_fixingPeriodEndTime) != Double.doubleToLongBits(other._fixingPeriodEndTime)) {
return false;
}
if (Double.doubleToLongBits(_fixingPeriodStartTime) != Double.doubleToLongBits(other._fixingPeriodStartTime)) {
return false;
}
if (!ObjectUtils.equals(_index, other._index)) {
return false;
}
if (Double.doubleToLongBits(_spread) != Double.doubleToLongBits(other._spread)) {
return false;
}
if (Double.doubleToLongBits(_spreadAmount) != Double.doubleToLongBits(other._spreadAmount)) {
return false;
}
return true;
}
}