/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.cash.derivative; import org.apache.commons.lang.ObjectUtils; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.interestrate.InstrumentDerivative; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; /** * Class describing a standard deposit. The notional amount is paid on the start time and received back on the end (maturity) time with interests. * The interest amount is computed based on a fixed rate and a accrual factor. */ public class Cash implements InstrumentDerivative { /** * The deposit currency. */ private final Currency _currency; /** * The deposit start time. */ private final double _startTime; /** * The deposit end (or maturity) time. */ private final double _endTime; /** * The deposit notional. */ private final double _notional; /** * The accrual factor (or year fraction). */ private final double _accrualFactor; /** * The deposit rate. */ private final double _rate; /** * The interest amount to be paid at end date (=_notional * _rate * _accrualFactor) */ private final double _interestAmount; /** * The initial amount. Usually is equal to the notional or 0 if the amount has been paid in the past. */ private final double _initialAmount; /** * The discounting curve name. */ private final String _discountingCurveName; /** * Constructor of a cash deposit. * @param currency The currency * @param startTime Time when the notional amount is borrowed (could be 0, i.e. now) * @param endTime Time from now (in years) when the loan matures (is repaid) * @param notional The notional of the loan * @param rate The loan rate. * @param accrualFactor The time (in years) between the start date and the end date in some day count convention. * @param yieldCurveName Name of yield curve used to price loan * @deprecated Use the constructor that does not take yield curve names. */ @Deprecated public Cash(final Currency currency, final double startTime, final double endTime, final double notional, final double rate, final double accrualFactor, final String yieldCurveName) { this(currency, startTime, endTime, notional, notional, rate, accrualFactor, yieldCurveName); } /** * Constructor of a cash deposit. * @param currency The currency * @param startTime Time when the notional amount is borrowed (could be 0, i.e. now) * @param endTime Time from now (in years) when the loan matures (is repaid) * @param notional The notional of the loan * @param rate The loan rate. * @param accrualFactor The time (in years) between the start date and the end date in some day count convention. */ public Cash(final Currency currency, final double startTime, final double endTime, final double notional, final double rate, final double accrualFactor) { this(currency, startTime, endTime, notional, notional, rate, accrualFactor); } /** * A cash loan * @param currency The currency * @param startTime Time when the notional amount is borrowed (could be 0, i.e. now) * @param endTime Time from now (in years) when the loan matures (is repaid) * @param notional The notional of the loan * @param initialAmount The initial amount. Usually is equal to the notional or 0 if the amount has been paid in the past. Should be of the same sign as notional. * @param rate The loan rate. * @param accrualFactor The time (in years) between the start date and the end date in some day count convention. * @param yieldCurveName Name of yield curve used to price loan * @deprecated Use the constructor that does not take yield curve names. */ @Deprecated public Cash(final Currency currency, final double startTime, final double endTime, final double notional, final double initialAmount, final double rate, final double accrualFactor, final String yieldCurveName) { ArgumentChecker.notNull(yieldCurveName, "yield curve name"); ArgumentChecker.notNull(currency, "currency"); ArgumentChecker.isTrue(startTime >= 0, "Start time should be positive or 0."); ArgumentChecker.isTrue(accrualFactor >= 0, "Accrual factor should be positive or zero"); //REVIEW: Should the accrual factor be restricted to >0? ArgumentChecker.isTrue(startTime <= endTime, "Start time must be less or equal to the end time"); //REVIEW: Should the time be restricted to startTime < endTime? ArgumentChecker.isTrue(notional * initialAmount >= 0.0, "Notional and initial amount should have the same sign"); _currency = currency; _endTime = endTime; _discountingCurveName = yieldCurveName; _startTime = startTime; _accrualFactor = accrualFactor; _rate = rate; _notional = notional; _interestAmount = _notional * _rate * _accrualFactor; _initialAmount = initialAmount; } /** * A cash loan * @param currency The currency * @param startTime Time when the notional amount is borrowed (could be 0, i.e. now) * @param endTime Time from now (in years) when the loan matures (is repaid) * @param notional The notional of the loan * @param initialAmount The initial amount. Usually is equal to the notional or 0 if the amount has been paid in the past. Should be of the same sign as notional. * @param rate The loan rate. * @param accrualFactor The time (in years) between the start date and the end date in some day count convention. */ public Cash(final Currency currency, final double startTime, final double endTime, final double notional, final double initialAmount, final double rate, final double accrualFactor) { ArgumentChecker.notNull(currency, "currency"); ArgumentChecker.isTrue(startTime >= 0, "Start time should be positive or 0."); ArgumentChecker.isTrue(accrualFactor >= 0, "Accrual factor should be positive"); ArgumentChecker.isTrue(startTime <= endTime, "Start time must be less or equal to the end time"); //REVIEW: Should the time be restricted to startTime < endTime? ArgumentChecker.isTrue(notional * initialAmount >= 0.0, "Notional and initial amount should have the same sign"); _currency = currency; _endTime = endTime; _startTime = startTime; _accrualFactor = accrualFactor; _rate = rate; _notional = notional; _interestAmount = _notional * _rate * _accrualFactor; _initialAmount = initialAmount; _discountingCurveName = null; } public Currency getCurrency() { return _currency; } /** * @return The yield curve name * @deprecated Curve names should no longer be set in {@link InstrumentDefinition}s */ @Deprecated public String getYieldCurveName() { if (_discountingCurveName == null) { throw new IllegalStateException("Discounting curve name was not set"); } return _discountingCurveName; } public double getStartTime() { return _startTime; } public double getEndTime() { return _endTime; } public double getAccrualFactor() { return _accrualFactor; } public double getRate() { return _rate; } public double getNotional() { return _notional; } /** * Gets the interest amount. * @return The amount. */ public double getInterestAmount() { return _interestAmount; } /** * Gets the initial amount. * @return The amount. */ public double getInitialAmount() { return _initialAmount; } @Override public <S, T> T accept(final InstrumentDerivativeVisitor<S, T> visitor, final S data) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCash(this, data); } @Override public <T> T accept(final InstrumentDerivativeVisitor<?, T> visitor) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCash(this); } @Override public String toString() { return "Cash " + _currency.toString() + "[" + _startTime + " - " + _endTime + "], r: " + _rate + ", notional: " + _notional + ", curve: " + _discountingCurveName; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + _currency.hashCode(); result = prime * result + (_discountingCurveName == null ? 0 : _discountingCurveName.hashCode()); long temp; temp = Double.doubleToLongBits(_endTime); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(_rate); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(_notional); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(_startTime); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(_accrualFactor); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Cash other = (Cash) obj; if (!ObjectUtils.equals(_currency, other._currency)) { return false; } if (!ObjectUtils.equals(_discountingCurveName, other._discountingCurveName)) { return false; } if (Double.doubleToLongBits(_endTime) != Double.doubleToLongBits(other._endTime)) { return false; } if (Double.doubleToLongBits(_rate) != Double.doubleToLongBits(other._rate)) { return false; } if (Double.doubleToLongBits(_notional) != Double.doubleToLongBits(other._notional)) { return false; } if (Double.doubleToLongBits(_startTime) != Double.doubleToLongBits(other._startTime)) { return false; } if (Double.doubleToLongBits(_accrualFactor) != Double.doubleToLongBits(other._accrualFactor)) { return false; } return true; } }