/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.cash.method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.opengamma.analytics.financial.interestrate.ContinuousInterestRate;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InterestRate;
import com.opengamma.analytics.financial.interestrate.InterestRateCurveSensitivity;
import com.opengamma.analytics.financial.interestrate.YieldCurveBundle;
import com.opengamma.analytics.financial.interestrate.cash.derivative.DepositZero;
import com.opengamma.analytics.financial.interestrate.method.PricingMethod;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.CurrencyAmount;
import com.opengamma.util.tuple.DoublesPair;
/**
* The methods associated to the pricing of deposit by discounting.
* @deprecated {@link YieldCurveBundle} is deprecated
*/
@Deprecated
public final class DepositZeroDiscountingMethod implements PricingMethod {
/**
* The method unique instance.
*/
private static final DepositZeroDiscountingMethod INSTANCE = new DepositZeroDiscountingMethod();
/**
* Return the unique instance of the class.
* @return The instance.
*/
public static DepositZeroDiscountingMethod getInstance() {
return INSTANCE;
}
/**
* Private constructor.
*/
private DepositZeroDiscountingMethod() {
}
/**
* Compute the present value by discounting the final cash flow (nominal + interest) and the initial payment (initial amount).
* @param deposit The deposit.
* @param curves The curves.
* @return The present value.
*/
public CurrencyAmount presentValue(final DepositZero deposit, final YieldCurveBundle curves) {
ArgumentChecker.notNull(deposit, "deposit");
ArgumentChecker.notNull(curves, "curves");
final double dfStart = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getStartTime());
final double dfEnd = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getEndTime());
final double pv = (deposit.getNotional() + deposit.getInterestAmount()) * dfEnd - deposit.getInitialAmount() * dfStart;
return CurrencyAmount.of(deposit.getCurrency(), pv);
}
@Override
public CurrencyAmount presentValue(final InstrumentDerivative instrument, final YieldCurveBundle curves) {
ArgumentChecker.isTrue(instrument instanceof DepositZero, "Cash");
return presentValue((DepositZero) instrument, curves);
}
/**
* Compute the present value curve sensitivity by discounting the final cash flow (nominal + interest) and the initial payment (initial amount).
* @param deposit The deposit.
* @param curves The curves.
* @return The present value.
*/
public InterestRateCurveSensitivity presentValueCurveSensitivity(final DepositZero deposit, final YieldCurveBundle curves) {
ArgumentChecker.notNull(deposit, "deposit");
ArgumentChecker.notNull(curves, "curves");
final double dfStart = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getStartTime());
final double dfEnd = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getEndTime());
// Backward sweep
final double pvBar = 1.0;
final double dfEndBar = deposit.getNotional() + deposit.getInterestAmount() * pvBar;
final double dfStartBar = -deposit.getInitialAmount() * pvBar;
final Map<String, List<DoublesPair>> resultMapDsc = new HashMap<>();
final List<DoublesPair> listDiscounting = new ArrayList<>();
listDiscounting.add(DoublesPair.of(deposit.getStartTime(), -deposit.getStartTime() * dfStart * dfStartBar));
listDiscounting.add(DoublesPair.of(deposit.getEndTime(), -deposit.getEndTime() * dfEnd * dfEndBar));
resultMapDsc.put(deposit.getDiscountingCurveName(), listDiscounting);
return new InterestRateCurveSensitivity(resultMapDsc);
}
/**
* Computes the deposit fair rate given the start and end time and the accrual factor.
* When deposit has already start the number may not be meaning full as the remaining period is not in line with the accrual factor.
* @param deposit The deposit.
* @param curves The curves.
* @return The rate.
*/
public double parRate(final DepositZero deposit, final YieldCurveBundle curves) {
final YieldAndDiscountCurve dsc = curves.getCurve(deposit.getDiscountingCurveName());
final double startTime = deposit.getStartTime();
final double endTime = deposit.getEndTime();
final double rcc = Math.log(dsc.getDiscountFactor(startTime) / dsc.getDiscountFactor(endTime)) / deposit.getPaymentAccrualFactor();
final InterestRate rate = deposit.getRate().fromContinuous(new ContinuousInterestRate(rcc));
return rate.getRate();
}
/**
* Computes the deposit fair rate curve sensitivity.
* When deposit has already start the number may not be meaning full as the remaining period is not in line with the accrual factor.
* @param deposit The deposit.
* @param curves The curves.
* @return The rate sensitivity.
*/
public InterestRateCurveSensitivity parRateCurveSensitivity(final DepositZero deposit, final YieldCurveBundle curves) {
final YieldAndDiscountCurve dsc = curves.getCurve(deposit.getDiscountingCurveName());
final double dfStartTime = dsc.getDiscountFactor(deposit.getStartTime());
final double dfEndTime = dsc.getDiscountFactor(deposit.getEndTime());
final double rcc = Math.log(dfStartTime / dfEndTime) / deposit.getPaymentAccrualFactor();
final double rateBar = 1.0;
final double rccBar = deposit.getRate().fromContinuousDerivative(new ContinuousInterestRate(rcc)) * rateBar;
final double dfEndTimeBar = -1.0 / dfEndTime / deposit.getPaymentAccrualFactor() * rccBar;
final double dfStartTimeBar = 1.0 / dfStartTime / deposit.getPaymentAccrualFactor() * rccBar;
final Map<String, List<DoublesPair>> resultMapDsc = new HashMap<>();
final List<DoublesPair> listDiscounting = new ArrayList<>();
listDiscounting.add(DoublesPair.of(deposit.getStartTime(), -deposit.getStartTime() * dfStartTime * dfStartTimeBar));
listDiscounting.add(DoublesPair.of(deposit.getEndTime(), -deposit.getEndTime() * dfEndTime * dfEndTimeBar));
resultMapDsc.put(deposit.getDiscountingCurveName(), listDiscounting);
return new InterestRateCurveSensitivity(resultMapDsc);
}
/**
* Computes the spread to be added to the deposit rate to have a zero present value.
* When deposit has already start the number may not be meaning full as the remaining period is not in line with the accrual factor.
* @param deposit The deposit.
* @param curves The curves.
* @return The spread.
*/
public double parSpread(final DepositZero deposit, final YieldCurveBundle curves) {
ArgumentChecker.notNull(deposit, "deposit");
ArgumentChecker.notNull(curves, "curves");
final double dfStart = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getStartTime());
final double dfEnd = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getEndTime());
final double ccrs = Math.log(deposit.getInitialAmount() * dfStart / (deposit.getNotional() * dfEnd)) / deposit.getPaymentAccrualFactor();
final InterestRate rs = deposit.getRate().fromContinuous(new ContinuousInterestRate(ccrs));
return rs.getRate() - deposit.getRate().getRate();
}
/**
* Computes the par spread curve sensitivity.
* @param deposit The deposit.
* @param curves The curves.
* @return The spread curve sensitivity.
*/
public InterestRateCurveSensitivity parSpreadCurveSensitivity(final DepositZero deposit, final YieldCurveBundle curves) {
ArgumentChecker.notNull(deposit, "deposit");
ArgumentChecker.notNull(curves, "curves");
final double dfStart = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getStartTime());
final double dfEnd = curves.getCurve(deposit.getDiscountingCurveName()).getDiscountFactor(deposit.getEndTime());
final double ccrs = Math.log(deposit.getInitialAmount() * dfStart / (deposit.getNotional() * dfEnd)) / deposit.getPaymentAccrualFactor();
// Backward sweep
final double parSpreadBar = 1.0;
final double rsBar = parSpreadBar;
final double ccrsBar = deposit.getRate().fromContinuousDerivative(new ContinuousInterestRate(ccrs)) * rsBar;
final double dfEndBar = -1 / (dfEnd * deposit.getPaymentAccrualFactor()) * ccrsBar;
final double dfStartBar = 1 / (dfEnd * deposit.getPaymentAccrualFactor()) * ccrsBar;
final Map<String, List<DoublesPair>> resultMapDsc = new HashMap<>();
final List<DoublesPair> listDiscounting = new ArrayList<>();
listDiscounting.add(DoublesPair.of(deposit.getStartTime(), -deposit.getStartTime() * dfStart * dfStartBar));
listDiscounting.add(DoublesPair.of(deposit.getEndTime(), -deposit.getEndTime() * dfEnd * dfEndBar));
resultMapDsc.put(deposit.getDiscountingCurveName(), listDiscounting);
return new InterestRateCurveSensitivity(resultMapDsc);
}
}