/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.provider.sensitivity.multicurve; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.ObjectUtils; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.tuple.DoublesPair; /** * Class describing a present value curve sensitivity for multi-curves framework. */ public class MulticurveSensitivity implements Serializable { /** * The map containing the sensitivity to the yield (continuously compounded) (for discounting and issuer specific curves). * The map linked the curve (String) to a list of pairs (cash flow time, sensitivity value). */ private final Map<String, List<DoublesPair>> _sensitivityYieldDiscounting; /** * The map containing the sensitivity to forward curve. The sensitivity will depend on the way the curve is described (discount factor curve, forward rate, ...) * The map linked the curve (String) to a list of pairs (cash flow time, sensitivity value). */ private final Map<String, List<ForwardSensitivity>> _sensitivityForward; // TODO: Replace the curve names by some curve ID, maybe some UniqueIdentifiable objects /** * Default constructor, creating an empty HashMap for the sensitivity. */ public MulticurveSensitivity() { _sensitivityYieldDiscounting = new HashMap<>(); _sensitivityForward = new HashMap<>(); } /** * Constructor from a yield discounting map and a forward map. The maps are used directly. * @param sensitivityYieldDiscounting The map. * @param sensitivityForward The map. */ private MulticurveSensitivity(final Map<String, List<DoublesPair>> sensitivityYieldDiscounting, final Map<String, List<ForwardSensitivity>> sensitivityForward) { _sensitivityYieldDiscounting = sensitivityYieldDiscounting; _sensitivityForward = sensitivityForward; } /** * Constructor from a yield discounting map of sensitivity. The maps are used directly. * @param sensitivityYieldDiscounting The map. * @param sensitivityForward The map. * @return The sensitivity. */ public static MulticurveSensitivity of(final Map<String, List<DoublesPair>> sensitivityYieldDiscounting, final Map<String, List<ForwardSensitivity>> sensitivityForward) { ArgumentChecker.notNull(sensitivityYieldDiscounting, "Sensitivity yield curve"); ArgumentChecker.notNull(sensitivityForward, "Sensitivity forward"); return new MulticurveSensitivity(sensitivityYieldDiscounting, sensitivityForward); } /** * Constructor from a yield discounting map of sensitivity. The map is used directly. * @param sensitivityYieldDiscounting The map. * @return The sensitivity. */ public static MulticurveSensitivity ofYieldDiscounting(final Map<String, List<DoublesPair>> sensitivityYieldDiscounting) { ArgumentChecker.notNull(sensitivityYieldDiscounting, "Sensitivity yield curve"); return new MulticurveSensitivity(sensitivityYieldDiscounting, new HashMap<String, List<ForwardSensitivity>>()); } /** * Constructor from a yield discounting map and a forward map. The map is used directly. * @param sensitivityForward The map. * @return The sensitivity. */ public static MulticurveSensitivity ofForward(final Map<String, List<ForwardSensitivity>> sensitivityForward) { ArgumentChecker.notNull(sensitivityForward, "Sensitivity forward"); return new MulticurveSensitivity(new HashMap<String, List<DoublesPair>>(), sensitivityForward); } public static MulticurveSensitivity ofForward(final String curveName, final ForwardSensitivity pointSensitivity) { final List<ForwardSensitivity> listForward = new ArrayList<>(); listForward.add(pointSensitivity); final HashMap<String, List<ForwardSensitivity>> mapFwd = new HashMap<>(); mapFwd.put(curveName, listForward); return MulticurveSensitivity.ofForward(mapFwd); } /** * Gets the discounting curve sensitivities. * @return The sensitivity map */ public Map<String, List<DoublesPair>> getYieldDiscountingSensitivities() { return _sensitivityYieldDiscounting; } /** * Gets the forward curve sensitivity map. * @return The sensitivity map */ public Map<String, List<ForwardSensitivity>> getForwardSensitivities() { return _sensitivityForward; } /** * Create a copy of the sensitivity and add a given sensitivity to it. * @param other The sensitivity to add. * @return The total sensitivity. */ public MulticurveSensitivity plus(final MulticurveSensitivity other) { ArgumentChecker.notNull(other, "sensitivity"); final Map<String, List<DoublesPair>> resultDsc = MulticurveSensitivityUtils.plus(_sensitivityYieldDiscounting, other._sensitivityYieldDiscounting); final Map<String, List<ForwardSensitivity>> resultFwd = MulticurveSensitivityUtils.plusFwd(_sensitivityForward, other._sensitivityForward); return new MulticurveSensitivity(resultDsc, resultFwd); } /** * Create a new sensitivity object containing the original sensitivity multiplied by a common factor. * @param factor The multiplicative factor. * @return The multiplied sensitivity. */ public MulticurveSensitivity multipliedBy(final double factor) { final Map<String, List<DoublesPair>> resultDsc = MulticurveSensitivityUtils.multipliedBy(_sensitivityYieldDiscounting, factor); final Map<String, List<ForwardSensitivity>> resultFwd = MulticurveSensitivityUtils.multipliedByFwd(_sensitivityForward, factor); return new MulticurveSensitivity(resultDsc, resultFwd); } /** * Create a new sensitivity object by a product of two sensitivities * @param other The other sensitivity * @return The new sensitivity */ public MulticurveSensitivity productOf(final MulticurveSensitivity other) { final Map<String, List<DoublesPair>> resultDsc = MulticurveSensitivityUtils.productOf(_sensitivityYieldDiscounting, other._sensitivityYieldDiscounting); final Map<String, List<ForwardSensitivity>> resultFwd = MulticurveSensitivityUtils.productOfFwd(_sensitivityForward, other._sensitivityForward); return new MulticurveSensitivity(resultDsc, resultFwd); } /** * Return a new sensitivity by sorting the times and adding the values at duplicated times. * @return The cleaned sensitivity. */ public MulticurveSensitivity cleaned() { final Map<String, List<DoublesPair>> resultDsc = MulticurveSensitivityUtils.cleaned(_sensitivityYieldDiscounting); final Map<String, List<ForwardSensitivity>> resultFwd = MulticurveSensitivityUtils.cleanedFwd(_sensitivityForward); return new MulticurveSensitivity(resultDsc, resultFwd); } /** * Return a new sensitivity by sorting the times and adding the values at duplicated times. The total value below the tolerance threshold are removed. * @param tolerance The tolerance. * @return The cleaned sensitivity. */ public MulticurveSensitivity cleaned(final double tolerance) { final Map<String, List<DoublesPair>> resultDsc = MulticurveSensitivityUtils.cleaned(_sensitivityYieldDiscounting, tolerance); final Map<String, List<ForwardSensitivity>> resultFwd = MulticurveSensitivityUtils.cleanedFwd(_sensitivityForward, tolerance); return new MulticurveSensitivity(resultDsc, resultFwd); } @Override public String toString() { return _sensitivityYieldDiscounting.toString() + "\n" + _sensitivityForward.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + _sensitivityForward.hashCode(); result = prime * result + _sensitivityYieldDiscounting.hashCode(); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!(obj instanceof MulticurveSensitivity)) { return false; } final MulticurveSensitivity other = (MulticurveSensitivity) obj; if (!ObjectUtils.equals(_sensitivityForward, other._sensitivityForward)) { return false; } if (!ObjectUtils.equals(_sensitivityYieldDiscounting, other._sensitivityYieldDiscounting)) { return false; } return true; } }