/**
* 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 org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.testng.annotations.Test;
import com.google.common.collect.Maps;
import com.opengamma.analytics.financial.util.AssertSensitivityObjects;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.tuple.DoublesPair;
/**
* Class to test the PresentValueSensitivity class.
*
*/
@Test(groups = TestGroup.UNIT)
public class InterestRateCurveSensitivityTest {
private static final List<DoublesPair> SENSITIVITY_DATA_1 = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, 10d), DoublesPair.of(2d, 20d), DoublesPair.of(3d, 30d), DoublesPair.of(4d, 40d)});
private static final List<DoublesPair> SENSITIVITY_DATA_2 = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, 40d), DoublesPair.of(2d, 30d), DoublesPair.of(3d, 20d), DoublesPair.of(4d, 10d)});
private static final List<DoublesPair> SENSITIVITY_DATA_3 = Arrays.asList(new DoublesPair[] {DoublesPair.of(11d, 40d), DoublesPair.of(12d, 30d), DoublesPair.of(13d, 20d), DoublesPair.of(14d, 10d)});
private static final String CURVE_NAME_1 = "A";
private static final String CURVE_NAME_2 = "B";
private static final String CURVE_NAME_3 = "C";
private static final Map<String, List<DoublesPair>> SENSITIVITY_11 = new HashMap<>();
private static final Map<String, List<DoublesPair>> SENSITIVITY_12 = new HashMap<>();
private static final Map<String, List<DoublesPair>> SENSITIVITY_22 = new HashMap<>();
private static final Map<String, List<DoublesPair>> SENSITIVITY_33 = new HashMap<>();
private static final double EPS = 1e-12;
static {
SENSITIVITY_11.put(CURVE_NAME_1, SENSITIVITY_DATA_1);
SENSITIVITY_22.put(CURVE_NAME_2, SENSITIVITY_DATA_2);
SENSITIVITY_12.put(CURVE_NAME_1, SENSITIVITY_DATA_2);
SENSITIVITY_33.put(CURVE_NAME_3, SENSITIVITY_DATA_3);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullSensitivity1() {
new InterestRateCurveSensitivity(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullSensitivity2() {
InterestRateCurveSensitivity.of(CURVE_NAME_1, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullCurveName() {
InterestRateCurveSensitivity.of(null, SENSITIVITY_DATA_1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullSensitivities() {
InterestRateCurveSensitivity.of("Name", null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPlusNullName() {
new InterestRateCurveSensitivity().plus(null, SENSITIVITY_DATA_1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPlusNullList() {
new InterestRateCurveSensitivity().plus(CURVE_NAME_1, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testPlusNullSensitivity() {
new InterestRateCurveSensitivity().plus(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testCleanNegativeAbsoluteTolerance() {
new InterestRateCurveSensitivity(SENSITIVITY_11).cleaned(EPS, -EPS);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testCleanNegativeRelativeTolerance() {
new InterestRateCurveSensitivity(SENSITIVITY_11).cleaned(-EPS, EPS);
}
// FIXME
// @Test(expectedExceptions = IllegalArgumentException.class)
// public void testCompareNull1() {
// InterestRateCurveSensitivity.compare(null, new InterestRateCurveSensitivity(), EPS);
// }
//
// @Test(expectedExceptions = IllegalArgumentException.class)
// public void testCompareNull2() {
// InterestRateCurveSensitivity.compare(new InterestRateCurveSensitivity(), null, EPS);
// }
//
// @Test(expectedExceptions = IllegalArgumentException.class)
// public void testCompareNegativeTolerance() {
// InterestRateCurveSensitivity.compare(new InterestRateCurveSensitivity(), new InterestRateCurveSensitivity(), -EPS);
// }
@Test
public void testObject() {
final Map<String, List<DoublesPair>> map = Maps.newHashMap(SENSITIVITY_11);
InterestRateCurveSensitivity sensitivities = new InterestRateCurveSensitivity(map);
map.put("DUMMY", SENSITIVITY_DATA_3);
assertFalse(sensitivities.getSensitivities().equals(map));
sensitivities = new InterestRateCurveSensitivity(SENSITIVITY_11);
assertEquals(SENSITIVITY_11.keySet(), sensitivities.getCurves());
assertEquals(SENSITIVITY_11, sensitivities.getSensitivities());
InterestRateCurveSensitivity other = new InterestRateCurveSensitivity(SENSITIVITY_11);
assertEquals(sensitivities.hashCode(), other.hashCode());
assertEquals(sensitivities, other);
other = InterestRateCurveSensitivity.of(CURVE_NAME_1, SENSITIVITY_DATA_1);
assertEquals(sensitivities, other);
assertFalse(SENSITIVITY_11 == new InterestRateCurveSensitivity(SENSITIVITY_11).getSensitivities());
assertFalse(sensitivities.equals(new InterestRateCurveSensitivity(SENSITIVITY_12)));
other = new InterestRateCurveSensitivity();
assertTrue(other.getCurves().isEmpty());
assertTrue(other.getSensitivities().isEmpty());
other = new InterestRateCurveSensitivity(SENSITIVITY_11);
assertEquals(sensitivities, other);
}
@Test
public void testPlusDifferentCurves() {
// Simple add
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, SENSITIVITY_DATA_1);
map.put(CURVE_NAME_2, SENSITIVITY_DATA_2);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
InterestRateCurveSensitivity actual = sensitivity1.plus(sensitivity2);
assertFalse(sensitivity1 == actual);
assertFalse(sensitivity2 == actual);
assertEquals(expected, actual);
actual = sensitivity1.plus(CURVE_NAME_2, SENSITIVITY_DATA_2);
assertEquals(expected, actual);
}
@Test
public void testPlusSameCurves() {
// Add on the same curve
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final List<DoublesPair> data = new ArrayList<>();
data.addAll(SENSITIVITY_DATA_1);
data.addAll(SENSITIVITY_DATA_2);
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, data);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
InterestRateCurveSensitivity actual = sensitivity1.plus(sensitivity2);
assertFalse(sensitivity1 == actual);
assertFalse(sensitivity2 == actual);
assertEquals(expected, actual);
actual = sensitivity1.plus(CURVE_NAME_1, SENSITIVITY_DATA_2);
assertEquals(expected, actual);
}
@Test
public void testPlusMultiCurve() {
// Add multi-curve
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final InterestRateCurveSensitivity sensitivity4 = new InterestRateCurveSensitivity(SENSITIVITY_33);
final List<DoublesPair> list = new ArrayList<>();
list.addAll(SENSITIVITY_DATA_1);
list.addAll(SENSITIVITY_DATA_2);
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, list);
map.put(CURVE_NAME_2, SENSITIVITY_DATA_2);
map.put(CURVE_NAME_3, SENSITIVITY_DATA_3);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
InterestRateCurveSensitivity actual = sensitivity1.plus(sensitivity2).plus(sensitivity3).plus(sensitivity4);
assertEquals(expected, actual);
actual = sensitivity1.plus(CURVE_NAME_1, SENSITIVITY_DATA_2).plus(CURVE_NAME_2, SENSITIVITY_DATA_2).plus(CURVE_NAME_3, SENSITIVITY_DATA_3);
assertEquals(expected, actual);
}
@Test
public void testMultiply() {
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final InterestRateCurveSensitivity sensitivity4 = new InterestRateCurveSensitivity(SENSITIVITY_33);
final double factor = Math.random() - 1;
final List<DoublesPair> list1 = new ArrayList<>();
final List<DoublesPair> list2 = new ArrayList<>();
final List<DoublesPair> list3 = new ArrayList<>();
for (final DoublesPair pair : SENSITIVITY_DATA_1) {
list1.add(DoublesPair.of(pair.first, pair.second * factor));
}
for (final DoublesPair pair : SENSITIVITY_DATA_2) {
final DoublesPair scaledPair = DoublesPair.of(pair.first, pair.second * factor);
list1.add(scaledPair);
list2.add(scaledPair);
}
for (final DoublesPair pair : SENSITIVITY_DATA_3) {
list3.add(DoublesPair.of(pair.first, pair.second * factor));
}
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, list1);
map.put(CURVE_NAME_2, list2);
map.put(CURVE_NAME_3, list3);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
final InterestRateCurveSensitivity actualUnscaled = sensitivity1.plus(sensitivity2).plus(sensitivity3).plus(sensitivity4);
InterestRateCurveSensitivity actual = actualUnscaled.multipliedBy(factor);
assertFalse(actualUnscaled == actual);
assertFalse(actualUnscaled.getSensitivities() == actual.getSensitivities());
assertEquals(expected, actual);
actual = sensitivity1.multipliedBy(factor).plus(sensitivity2.multipliedBy(factor)).plus(sensitivity3.multipliedBy(factor)).plus(sensitivity4.multipliedBy(factor));
assertEquals(expected, actual);
}
@Test
public void testCleanSameCurves() {
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final List<DoublesPair> list = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, 50d), DoublesPair.of(2d, 50d), DoublesPair.of(3d, 50d), DoublesPair.of(4d, 50d)});
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, list);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
final InterestRateCurveSensitivity actualUncleaned = sensitivity1.plus(sensitivity2);
final InterestRateCurveSensitivity actual = actualUncleaned.cleaned();
assertFalse(actualUncleaned == actual);
assertFalse(actualUncleaned.getSensitivities() == actual.getSensitivities());
assertEquals(expected, actual);
}
@Test
public void testCleanDifferentCurves() {
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final Map<String, List<DoublesPair>> map = new HashMap<>();
map.put(CURVE_NAME_1, SENSITIVITY_DATA_1);
map.put(CURVE_NAME_2, SENSITIVITY_DATA_2);
final InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(map);
final InterestRateCurveSensitivity actualUncleaned = sensitivity1.plus(sensitivity2);
final InterestRateCurveSensitivity actual = actualUncleaned.cleaned();
assertFalse(actualUncleaned == actual);
assertFalse(actualUncleaned.getSensitivities() == actual.getSensitivities());
assertEquals(expected, actual);
assertEquals(actualUncleaned, actual);
}
@Test
public void testCleanSameCurvesWithAbsoluteTolerance1() {
final double eps = 1e-3;
final double eps2 = 5e-4;
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final List<DoublesPair> fuzzyList = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, -10 - eps2), DoublesPair.of(2d, 30d), DoublesPair.of(3d, -30d + eps2), DoublesPair.of(4d, 10d)});
List<DoublesPair> expectedList = Arrays.asList(new DoublesPair[] {DoublesPair.of(2d, 50d), DoublesPair.of(4d, 50d)});
Map<String, List<DoublesPair>> expectedMap = new HashMap<>();
expectedMap.put(CURVE_NAME_1, expectedList);
final Map<String, List<DoublesPair>> fuzzyMap = new HashMap<>();
fuzzyMap.put(CURVE_NAME_1, fuzzyList);
final InterestRateCurveSensitivity fuzzySensitivity = new InterestRateCurveSensitivity(fuzzyMap);
InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(expectedMap);
final InterestRateCurveSensitivity actualUncleaned = sensitivity1.plus(fuzzySensitivity);
InterestRateCurveSensitivity actual = actualUncleaned.cleaned(eps / 10, eps);
assertFalse(actualUncleaned == actual);
assertFalse(actualUncleaned.getSensitivities() == actual.getSensitivities());
assertEquals(expected, actual);
expectedList = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, -eps2), DoublesPair.of(2d, 50d), DoublesPair.of(3d, eps2), DoublesPair.of(4d, 50d)});
expectedMap = new HashMap<>();
expectedMap.put(CURVE_NAME_1, expectedList);
expected = new InterestRateCurveSensitivity(expectedMap);
actual = actualUncleaned.cleaned(eps / 1000, eps / 100);
assertEquals(expected.getSensitivities().size(), actual.getSensitivities().size());
assertIRCSEquals(expected, actual);
}
@Test
public void testCleanSameCurvesWithRelativeTolerance1() {
final double eps = 1e-3;
final double eps2 = 5e-4;
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final List<DoublesPair> fuzzyList = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, -10d - 10 * eps2), DoublesPair.of(2d, 30d), DoublesPair.of(3d, -30d + 30 * eps2), DoublesPair.of(4d, 10d)});
List<DoublesPair> expectedList = Arrays.asList(new DoublesPair[] {DoublesPair.of(2d, 50d), DoublesPair.of(4d, 50d)});
Map<String, List<DoublesPair>> expectedMap = new HashMap<>();
expectedMap.put(CURVE_NAME_1, expectedList);
final Map<String, List<DoublesPair>> fuzzyMap = new HashMap<>();
fuzzyMap.put(CURVE_NAME_1, fuzzyList);
final InterestRateCurveSensitivity fuzzySensitivity = new InterestRateCurveSensitivity(fuzzyMap);
InterestRateCurveSensitivity expected = new InterestRateCurveSensitivity(expectedMap);
final InterestRateCurveSensitivity actualUncleaned = sensitivity1.plus(fuzzySensitivity);
InterestRateCurveSensitivity actual = actualUncleaned.cleaned(eps, eps / 10);
assertFalse(actualUncleaned == actual);
assertFalse(actualUncleaned.getSensitivities() == actual.getSensitivities());
assertEquals(expected, actual);
expectedList = Arrays.asList(new DoublesPair[] {DoublesPair.of(1d, -10d * eps2), DoublesPair.of(2d, 50d), DoublesPair.of(3d, 30d * eps2), DoublesPair.of(4d, 50d)});
expectedMap = new HashMap<>();
expectedMap.put(CURVE_NAME_1, expectedList);
expected = new InterestRateCurveSensitivity(expectedMap);
actual = actualUncleaned.cleaned(eps / 100, eps / 10);
assertEquals(expected.getSensitivities().size(), actual.getSensitivities().size());
assertIRCSEquals(expected, actual);
}
@Test
public void testTotalSensitivityByCurve() {
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final InterestRateCurveSensitivity sensitivity4 = new InterestRateCurveSensitivity(SENSITIVITY_33);
final Map<String, Double> actual = sensitivity1.plus(sensitivity2).plus(sensitivity3).plus(sensitivity4).totalSensitivityByCurve();
final Map<String, Double> expected = new HashMap<>();
expected.put(CURVE_NAME_1, 200.);
expected.put(CURVE_NAME_2, 100.);
expected.put(CURVE_NAME_3, 100.);
assertEquals(expected, actual);
}
@Test
public void testTotalSensitivity() {
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(SENSITIVITY_22);
final InterestRateCurveSensitivity sensitivity4 = new InterestRateCurveSensitivity(SENSITIVITY_33);
final double actual = sensitivity1.plus(sensitivity2).plus(sensitivity3).plus(sensitivity4).totalSensitivity();
final double expected = 400;
assertEquals(expected, actual);
}
@Test
public void testCompareDifferentTimes() {
AssertSensitivityObjects.assertEquals("", new InterestRateCurveSensitivity(), new InterestRateCurveSensitivity(), EPS);
final TreeMap<String, List<DoublesPair>> sortedMap = new TreeMap<>(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(sortedMap);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
AssertSensitivityObjects.assertDoesNotEqual("", sensitivity1, sensitivity2, EPS);
final Map<String, List<DoublesPair>> map = Maps.newTreeMap();
final double eps = 1e-4;
for (final Map.Entry<String, List<DoublesPair>> entry : sortedMap.entrySet()) {
final List<DoublesPair> list = new ArrayList<>();
for (final DoublesPair pair : entry.getValue()) {
list.add(DoublesPair.of(pair.first + 0.01 * eps, pair.second));
}
map.put(entry.getKey(), list);
}
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(map);
AssertSensitivityObjects.assertEquals("", sensitivity1, sensitivity3, eps);
AssertSensitivityObjects.assertDoesNotEqual("", sensitivity1, sensitivity3, EPS);
}
@Test
public void testCompareDifferentValues() {
AssertSensitivityObjects.assertEquals("", new InterestRateCurveSensitivity(), new InterestRateCurveSensitivity(), EPS);
final TreeMap<String, List<DoublesPair>> sortedMap = new TreeMap<>(SENSITIVITY_11);
final InterestRateCurveSensitivity sensitivity1 = new InterestRateCurveSensitivity(sortedMap);
final InterestRateCurveSensitivity sensitivity2 = new InterestRateCurveSensitivity(SENSITIVITY_12);
AssertSensitivityObjects.assertDoesNotEqual("", sensitivity1, sensitivity2, EPS);
final Map<String, List<DoublesPair>> map = Maps.newTreeMap();
final double eps = 1e-4;
for (final Map.Entry<String, List<DoublesPair>> entry : sortedMap.entrySet()) {
final List<DoublesPair> list = new ArrayList<>();
for (final DoublesPair pair : entry.getValue()) {
list.add(DoublesPair.of(pair.first, pair.second + 0.01 * eps));
}
map.put(entry.getKey(), list);
}
final InterestRateCurveSensitivity sensitivity3 = new InterestRateCurveSensitivity(map);
AssertSensitivityObjects.assertEquals("", sensitivity1, sensitivity3, eps);
AssertSensitivityObjects.assertDoesNotEqual("", sensitivity1, sensitivity3, EPS);
}
private void assertIRCSEquals(final InterestRateCurveSensitivity expected, final InterestRateCurveSensitivity actual) {
final Iterator<Map.Entry<String, List<DoublesPair>>> expectedIterator = new TreeMap<>(expected.getSensitivities()).entrySet().iterator();
final Iterator<Map.Entry<String, List<DoublesPair>>> actualIterator = new TreeMap<>(actual.getSensitivities()).entrySet().iterator();
do {
final Map.Entry<String, List<DoublesPair>> expectedEntry = expectedIterator.next();
final Map.Entry<String, List<DoublesPair>> actualEntry = actualIterator.next();
assertEquals(expectedEntry.getKey(), actualEntry.getKey());
assertEquals(expectedEntry.getValue().size(), actualEntry.getValue().size());
for (int i = 0; i < expectedEntry.getValue().size(); i++) {
final DoublesPair expectedPair = expectedEntry.getValue().get(i);
final DoublesPair actualPair = actualEntry.getValue().get(i);
assertEquals(expectedPair.first, actualPair.first, EPS);
assertEquals(expectedPair.second, actualPair.second, EPS);
}
} while (expectedIterator.hasNext() && actualIterator.hasNext());
}
}