/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.payments.derivative; import java.util.Arrays; import com.opengamma.analytics.financial.instrument.index.IborIndex; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; /** * Class describing an average coupon by weighted mean of index values with difference fixing dates. */ public class CouponIborAverageFixingDates extends Coupon { /** The index on which the fixing is done. */ private final IborIndex _index; /** The fixing times of the index. The times are in increasing order. Only the times not yet fixed are in the array.*/ private final double[] _fixingTime; /** The weights or quantity used for each fixing. The total weight is not necessarily 1. Same size as _fixingTime. */ private final double[] _weight; /** The start times of the underlying index period. Same size as _fixingTime. */ private final double[] _fixingPeriodStartTime; /** The end times of the underlying index period. Same size as _fixingTime. */ private final double[] _fixingPeriodEndTime; private final double[] _fixingPeriodAccrualFactor; /** The interest amount accrued over the periods already fixed multiplied by the weights, i.e. the sum (w_i r_i). */ private final double _amountAccrued; /** * Constructor from all details * @param currency The payment currency * @param paymentTime Time (in years) up to the payment * @param paymentAccrualFactor Accrual factor for the coupon payment * @param notional Coupon notional * @param index Ibor-like index * @param fixingTime Time (in years) up to fixing * @param weight The weights * @param fixingPeriodStartTime The fixing period start time (in years) of the index * @param fixingPeriodEndTime The fixing period end time (in years) of the index * @param fixingPeriodAccrualFactor The accrual factor of the fixing periods * @param amountAccrued The interest amount accrued over the periods already fixed multiplied by the weights, i.e. the sum (w_i r_i). */ public CouponIborAverageFixingDates(final Currency currency, final double paymentTime, final double paymentAccrualFactor, final double notional, final IborIndex index, final double[] fixingTime, final double[] weight, final double[] fixingPeriodStartTime, final double[] fixingPeriodEndTime, final double[] fixingPeriodAccrualFactor, final double amountAccrued) { super(currency, paymentTime, paymentAccrualFactor, notional); final int nDates = fixingTime.length; ArgumentChecker.isTrue(nDates == weight.length, "weight length different from fixingTime length"); ArgumentChecker.isTrue(nDates == fixingPeriodStartTime.length, "fixingPeriodStartTime length different from fixingTime length"); ArgumentChecker.isTrue(nDates == fixingPeriodEndTime.length, "fixingPeriodEndTime length different from fixingTime length"); ArgumentChecker.isTrue(nDates == fixingPeriodAccrualFactor.length, "getFixingPeriodAccrualFactor length different from fixingTime length"); ArgumentChecker.isTrue(currency.equals(index.getCurrency()), "index currency different from payment currency"); _fixingTime = Arrays.copyOf(fixingTime, nDates); _index = index; _weight = Arrays.copyOf(weight, nDates); _fixingPeriodStartTime = Arrays.copyOf(fixingPeriodStartTime, nDates); _fixingPeriodEndTime = Arrays.copyOf(fixingPeriodEndTime, nDates); _fixingPeriodAccrualFactor = Arrays.copyOf(fixingPeriodAccrualFactor, nDates); _amountAccrued = amountAccrued; } @Override public <S, T> T accept(final InstrumentDerivativeVisitor<S, T> visitor, final S data) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCouponIborAverageFixingDates(this, data); } @Override public <T> T accept(final InstrumentDerivativeVisitor<?, T> visitor) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCouponIborAverageFixingDates(this); } @Override public CouponIborAverageFixingDates withNotional(double notional) { return new CouponIborAverageFixingDates(getCurrency(), getPaymentTime(), getPaymentYearFraction(), notional, getIndex(), getFixingTime(), getWeight(), getFixingPeriodStartTime(), getFixingPeriodEndTime(), getFixingPeriodAccrualFactor(), _amountAccrued); } /** * Gets the fixingTime. * @return the fixingTime */ public double[] getFixingTime() { return _fixingTime; } /** * Gets the index. * @return the index */ public IborIndex getIndex() { return _index; } /** * Gets the weight. * @return the weight */ public double[] getWeight() { return _weight; } /** * Gets the fixingPeriodStartTime. * @return the fixingPeriodStartTime */ public double[] getFixingPeriodStartTime() { return _fixingPeriodStartTime; } /** * Gets the fixingPeriodEndTime. * @return the fixingPeriodEndTime */ public double[] getFixingPeriodEndTime() { return _fixingPeriodEndTime; } /** * Gets the fixingPeriodAccrualFactor. * @return the fixingPeriodAccrualFactor */ public double[] getFixingPeriodAccrualFactor() { return _fixingPeriodAccrualFactor; } /** * Returns the accrued amount for the period already fixed. * @return The amount accrued. */ public double getAmountAccrued() { return _amountAccrued; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); long temp; temp = Double.doubleToLongBits(_amountAccrued); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + Arrays.hashCode(_fixingPeriodAccrualFactor); result = prime * result + Arrays.hashCode(_fixingPeriodEndTime); result = prime * result + Arrays.hashCode(_fixingPeriodStartTime); result = prime * result + Arrays.hashCode(_fixingTime); result = prime * result + ((_index == null) ? 0 : _index.hashCode()); result = prime * result + Arrays.hashCode(_weight); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (!(obj instanceof CouponIborAverageFixingDates)) { return false; } CouponIborAverageFixingDates other = (CouponIborAverageFixingDates) obj; if (Double.doubleToLongBits(_amountAccrued) != Double.doubleToLongBits(other._amountAccrued)) { return false; } if (!Arrays.equals(_fixingPeriodAccrualFactor, other._fixingPeriodAccrualFactor)) { return false; } if (!Arrays.equals(_fixingPeriodEndTime, other._fixingPeriodEndTime)) { return false; } if (!Arrays.equals(_fixingPeriodStartTime, other._fixingPeriodStartTime)) { return false; } if (!Arrays.equals(_fixingTime, other._fixingTime)) { return false; } if (_index == null) { if (other._index != null) { return false; } } else if (!_index.equals(other._index)) { return false; } if (!Arrays.equals(_weight, other._weight)) { return false; } return true; } }