/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate;
import static com.opengamma.analytics.financial.interestrate.InterestRateCurveSensitivityUtils.addSensitivity;
import static com.opengamma.analytics.financial.interestrate.InterestRateCurveSensitivityUtils.multiplySensitivity;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.DoublesPair;
/**
* Class containing data describing the sensitivity of some analytic value (present value, par rate, etc.) to a family of yield curves.
*/
public class InterestRateCurveSensitivity {
/**
* The map containing the sensitivity. The map links the curve name to a list of pairs of cash flow time and sensitivity value.
*/
private final Map<String, List<DoublesPair>> _sensitivity;
/**
* Default constructor, creating an empty HashMap for the sensitivity.
*/
public InterestRateCurveSensitivity() {
_sensitivity = new HashMap<>();
}
/**
* Constructor from a map of sensitivity. The map links the curve name to a list of pairs of cash flow time and sensitivity value.
* @param sensitivity The map, not null
*/
public InterestRateCurveSensitivity(final Map<String, List<DoublesPair>> sensitivity) {
ArgumentChecker.notNull(sensitivity, "sensitivity");
_sensitivity = new HashMap<>(sensitivity);
}
/**
* Builder from a curve name and a list of sensitivities.
* @param name The name, not null
* @param sensitivityCurve The sensitivity as a list, not null
* @return The interest rate curve sensitivity.
*/
public static InterestRateCurveSensitivity of(final String name, final List<DoublesPair> sensitivityCurve) {
ArgumentChecker.notNull(name, "Curve name");
ArgumentChecker.notNull(sensitivityCurve, "sensitivity");
final HashMap<String, List<DoublesPair>> ircs = new HashMap<>();
ircs.put(name, sensitivityCurve);
return new InterestRateCurveSensitivity(ircs);
}
/**
* Gets the sensitivity map.
* @return The sensitivity map
*/
public Map<String, List<DoublesPair>> getSensitivities() {
return _sensitivity;
}
/**
* Returns the set of curve names in the interest rate sensitivities.
* @return The set of curve names.
*/
public Set<String> getCurves() {
return _sensitivity.keySet();
}
/**
* Create a copy of the sensitivity and add a given sensitivity to it.
* @param other The sensitivity to add.
* @return The total sensitivity.
*/
public InterestRateCurveSensitivity plus(final InterestRateCurveSensitivity other) {
ArgumentChecker.notNull(other, "Curve sensitivity");
return new InterestRateCurveSensitivity(addSensitivity(_sensitivity, other._sensitivity));
}
/**
* Create a copy of the sensitivity and add a list representing the sensitivity to a specific curve.=.
* @param curveName The name of the curve the sensitivity of which is added. Not null.
* @param list The sensitivity as a list. Not null.
* @return The total sensitivity.
*/
public InterestRateCurveSensitivity plus(final String curveName, final List<DoublesPair> list) {
ArgumentChecker.notNull(curveName, "Curve name");
ArgumentChecker.notNull(list, "Sensitivity as list");
return new InterestRateCurveSensitivity(addSensitivity(_sensitivity, curveName, list));
}
/**
* Create a new sensitivity object containing the original sensitivity multiplied by a common factor.
* @param factor The multiplicative factor.
* @return The multiplied sensitivity.
*/
public InterestRateCurveSensitivity multipliedBy(final double factor) {
return new InterestRateCurveSensitivity(multiplySensitivity(_sensitivity, factor));
}
//REVIEW emcleod 23/10/2012 These next two methods look like an argument for splitting this class into two, with
// the first acting more like a list (i.e. not allowing duplicate times) and the type that has been cleaned looking
// more like a set. Probably worth splitting the two.
/**
* Return a new sensitivity cleaned by sorting the times and adding the values at the duplicate times.
* @return The cleaned sensitivity.
*/
public InterestRateCurveSensitivity cleaned() {
return new InterestRateCurveSensitivity(InterestRateCurveSensitivityUtils.clean(_sensitivity, 0, 0));
}
/**
* Return a new sensitivity cleaned by sorting the times and adding the values at the duplicate times.
* @param relTol Relative tolerance. If the net divided by gross sensitivity is less than this it is ignored/removed
* @param absTol Absolute tolerance. If the net sensitivity is less than this it is ignored/removed
* @return The cleaned sensitivity.
*/
public InterestRateCurveSensitivity cleaned(final double relTol, final double absTol) {
return new InterestRateCurveSensitivity(InterestRateCurveSensitivityUtils.clean(_sensitivity, relTol, absTol));
}
/**
* Returns a map<String, Double> with the total sensitivity with respect to each curve.
* @return The map.
*/
public Map<String, Double> totalSensitivityByCurve() {
final HashMap<String, Double> s = new HashMap<>();
for (final Map.Entry<String, List<DoublesPair>> entry : _sensitivity.entrySet()) {
double total = 0.0;
for (final DoublesPair p : entry.getValue()) {
total += p.second;
}
s.put(entry.getKey(), total);
}
return s;
}
/**
* Returns the total sensitivity to all curves.
* @return The sensitivity.
*/
public double totalSensitivity() {
double total = 0.0;
for (final List<DoublesPair> pairs : _sensitivity.values()) {
for (final DoublesPair p : pairs) {
total += p.second;
}
}
return total;
}
@Override
public String toString() {
return _sensitivity.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _sensitivity.hashCode();
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof InterestRateCurveSensitivity)) {
return false;
}
final InterestRateCurveSensitivity other = (InterestRateCurveSensitivity) obj;
if (!ObjectUtils.equals(_sensitivity, other._sensitivity)) {
return false;
}
return true;
}
}