/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.cash.provider; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.opengamma.analytics.financial.interestrate.cash.derivative.DepositIbor; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.ForwardSensitivity; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MulticurveSensitivity; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyMulticurveSensitivity; import com.opengamma.analytics.financial.provider.sensitivity.multicurve.SimplyCompoundedForwardSensitivity; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.tuple.DoublesPair; /** * The methods associated to the pricing of Ibor fixing. */ public final class DepositIborDiscountingMethod { /** * The method unique instance. */ private static final DepositIborDiscountingMethod INSTANCE = new DepositIborDiscountingMethod(); /** * Return the unique instance of the class. * @return The instance. */ public static DepositIborDiscountingMethod getInstance() { return INSTANCE; } /** * Private constructor. */ private DepositIborDiscountingMethod() { } /** * Compute the present value by discounting of a "Ibor deposit", i.e. a fictitious deposit representing the Ibor fixing. * @param deposit The deposit. * @param multicurves The multi-curves provider. * @return The present value. */ public MultipleCurrencyAmount presentValue(final DepositIbor deposit, final MulticurveProviderInterface multicurves) { ArgumentChecker.notNull(deposit, "Deposit"); ArgumentChecker.notNull(multicurves, "Multicurves"); final double dfEnd = multicurves.getDiscountFactor(deposit.getCurrency(), deposit.getEndTime()); final double pv = deposit.getAccrualFactor() * (deposit.getRate() - multicurves.getSimplyCompoundForwardRate(deposit.getIndex(), deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor())) * dfEnd; return MultipleCurrencyAmount.of(deposit.getCurrency(), pv); } /** * Compute the present value curve sensitivity by discounting. * @param deposit The deposit. * @param multicurves The multi-curves provider. * @return The present value. */ public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final DepositIbor deposit, final MulticurveProviderInterface multicurves) { ArgumentChecker.notNull(deposit, "Deposit"); ArgumentChecker.notNull(multicurves, "Multicurves"); final double dfEnd = multicurves.getDiscountFactor(deposit.getCurrency(), deposit.getEndTime()); final double forward = multicurves.getSimplyCompoundForwardRate(deposit.getIndex(), deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor()); // Backward sweep final double forwardBar = deposit.getAccrualFactor() * dfEnd; final double dfEndBar = deposit.getAccrualFactor() * (deposit.getRate() - forward); final Map<String, List<ForwardSensitivity>> mapFwd = new HashMap<>(); final List<ForwardSensitivity> listForward = new ArrayList<>(); listForward.add(new SimplyCompoundedForwardSensitivity(deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor(), forwardBar)); mapFwd.put(multicurves.getName(deposit.getIndex()), listForward); final Map<String, List<DoublesPair>> mapDsc = new HashMap<>(); final List<DoublesPair> listDiscounting = new ArrayList<>(); listDiscounting.add(DoublesPair.of(deposit.getEndTime(), -deposit.getEndTime() * dfEnd * dfEndBar)); mapDsc.put(multicurves.getName(deposit.getCurrency()), listDiscounting); MultipleCurrencyMulticurveSensitivity result = new MultipleCurrencyMulticurveSensitivity(); result = result.plus(deposit.getCurrency(), MulticurveSensitivity.of(mapDsc, mapFwd)); return result; } /** * Computes the Ibor fixing deposit representation par rate. * When deposit has already start the number may not be meaning full as only the final payment remains (no initial payment). * @param deposit The deposit. * @param multicurve The curves. * @return The spread. */ public double parRate(final DepositIbor deposit, final MulticurveProviderInterface multicurve) { return multicurve.getSimplyCompoundForwardRate(deposit.getIndex(), deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor()); } /** * Computes the spread to be added to the Ibor rate to have a zero present value. * When deposit has already start the number may not be meaning full as only the final payment remains (no initial payment). * @param deposit The deposit. * @param multicurve The curves. * @return The spread. */ public double parSpread(final DepositIbor deposit, final MulticurveProviderInterface multicurve) { return multicurve.getSimplyCompoundForwardRate(deposit.getIndex(), deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor()) - deposit.getRate(); } /** * Computes the par spread curve sensitivity. * When deposit has already start the number may not be meaning full as only the final payment remains (no initial payment). * @param deposit The deposit. * @param multicurve The curves. * @return The spread curve sensitivity. */ public MulticurveSensitivity parSpreadCurveSensitivity(final DepositIbor deposit, final MulticurveProviderInterface multicurve) { ArgumentChecker.notNull(deposit, "Deposit"); ArgumentChecker.notNull(multicurve, "Multicurves"); final Map<String, List<ForwardSensitivity>> mapFwd = new HashMap<>(); final List<ForwardSensitivity> listForward = new ArrayList<>(); listForward.add(new SimplyCompoundedForwardSensitivity(deposit.getStartTime(), deposit.getEndTime(), deposit.getAccrualFactor(), 1.0)); mapFwd.put(multicurve.getName(deposit.getIndex()), listForward); return MulticurveSensitivity.ofForward(mapFwd); } }