/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.model.interestrate.curve;
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.List;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.opengamma.analytics.ShiftType;
import com.opengamma.analytics.math.curve.AddCurveSpreadFunction;
import com.opengamma.analytics.math.curve.ConstantDoublesCurve;
import com.opengamma.analytics.math.curve.DoublesCurve;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.curve.MultiplyCurveSpreadFunction;
import com.opengamma.analytics.math.curve.SpreadDoublesCurve;
import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.analytics.math.interpolation.Interpolator1DFactory;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.tuple.DoublesPair;
/**
* Tests the functionality in {@link YieldCurveUtils}
*/
@Test(groups = TestGroup.UNIT)
public class YieldCurveUtilsTest {
/** Adds yield curves */
private static final AddCurveSpreadFunction ADD_CURVE_FUNCTION = new AddCurveSpreadFunction();
/** Multiplies yield curves */
private static final MultiplyCurveSpreadFunction MULTIPLY_CURVE_FUNCTION = new MultiplyCurveSpreadFunction();
/** The interpolator for the original curve */
private static final Interpolator1D INTERPOLATOR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.DOUBLE_QUADRATIC,
Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.LINEAR_EXTRAPOLATOR);
/** The step interpolator used for bucketed shifts */
private static final Interpolator1D STEP_INTERPOLATOR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.STEP,
Interpolator1DFactory.FLAT_EXTRAPOLATOR);
/** Time points of the original curve */
private static final double[] T = new double[] {1, 2, 3, 4, 5, 6, 7};
/** Yield points of the original curve */
private static final double[] Y = new double[] {0.01, 0.015, 0.017, 0.02, 0.025, 0.035, 0.05};
/** The original interpolated curve */
private static final DoublesCurve INTERPOLATED_CURVE = InterpolatedDoublesCurve.fromSorted(T, Y, INTERPOLATOR);
/** Name of the original curve */
private static final String ORIGINAL_NAME = "ORIGINAL";
/** The original yield curve */
private static final YieldCurve ORIGINAL_CURVE = new YieldCurve(ORIGINAL_NAME, INTERPOLATED_CURVE);
/**
* Tests a null yield curve for parallel shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullCurve1() {
YieldCurveUtils.withParallelShift(null, 100, ShiftType.ABSOLUTE);
}
/**
* Tests a null shift type for parallel shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullShiftType1() {
YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, 100, null);
}
/**
* Tests a null yield curve for bucketed shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullCurve2() {
YieldCurveUtils.withBucketedShifts(null, new ArrayList<DoublesPair>(), new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests a null list of buckets
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullBuckets() {
YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, null, new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests a null list of bucketed shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullShifts1() {
YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, new ArrayList<DoublesPair>(), null, ShiftType.ABSOLUTE);
}
/**
* Tests a null shift type for bucketed shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullShiftType2() {
YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, new ArrayList<DoublesPair>(), new ArrayList<Double>(), null);
}
/**
* Tests the case where there is not an equal number of shifts and buckets
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testDifferentLengthShifts1() {
YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, Arrays.asList(DoublesPair.of(1., 2.)), new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests a null yield curve for point shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullCurve3() {
YieldCurveUtils.withPointShifts(null, new ArrayList<Double>(), new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests a null list of points
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullPoints() {
YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, null, new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests a null list of points shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullShifts2() {
YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, new ArrayList<Double>(), null, ShiftType.ABSOLUTE);
}
/**
* Tests a null shift type for point shifts
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullShiftType3() {
YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, new ArrayList<Double>(), new ArrayList<Double>(), null);
}
/**
* Tests the case where there is not an equal number of shifts and points
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testDifferentLengthShifts2() {
YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, Arrays.asList(3., 5.), new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests that only interpolated curves are handled.
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testConstantCurvePointsShift() {
YieldCurveUtils.withPointShifts(new YieldCurve("NAME", ConstantDoublesCurve.from(0.)), new ArrayList<Double>(), new ArrayList<Double>(), ShiftType.ABSOLUTE);
}
/**
* Tests that doing a parallel absolute shift of zero returns a different yield curve with the
* same shape.
*/
@Test
public void testZeroAbsoluteParallelShift() {
final YieldCurve shiftedCurve = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, 0, ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithParallelShift", shiftedCurve.getName());
assertFalse(shiftedCurve.getCurve().equals(ORIGINAL_CURVE.getCurve()));
assertTrue(shiftedCurve.getCurve() instanceof SpreadDoublesCurve);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that doing a parallel relative shift of zero returns a different yield curve with the same
* shape.
*/
@Test
public void testZeroRelativeParallelShift() {
final YieldCurve shiftedCurve = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, 0, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithParallelShift", shiftedCurve.getName());
assertFalse(shiftedCurve.getCurve().equals(ORIGINAL_CURVE.getCurve()));
assertTrue(shiftedCurve.getCurve() instanceof SpreadDoublesCurve);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests absolute parallel shifts. A round trip (+ve shift -> -ve shift) should return the same
* curve as the original.
*/
@Test
public void testAbsoluteParallelShift() {
final double shift = 0.03;
YieldCurve shiftedCurve = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, shift, ShiftType.ABSOLUTE);
final double[] y = new double[T.length];
for (int i = 0; i < y.length; i++) {
y[i] = Y[i] + shift;
}
final DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(T, y, INTERPOLATOR);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withParallelShift(shiftedCurve, -shift, ShiftType.ABSOLUTE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests relative parallel shifts. A round trip (shift -> -shift / (1 + shift)) should return the same
* curve as the original.
*/
@Test
public void testRelativeParallelShift() {
final double shift = 0.03;
YieldCurve shiftedCurve = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, shift, ShiftType.RELATIVE);
final double[] y = new double[T.length];
for (int i = 0; i < y.length; i++) {
y[i] = Y[i] * (1 + shift);
}
final DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(T, y, INTERPOLATOR);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withParallelShift(shiftedCurve, -shift / (1 + shift), ShiftType.RELATIVE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests that performing absolute shifts with an empty list of buckets returns a different yield curve with the same
* shape.
*/
@Test
public void testEmptyBucketedAbsoluteShifts() {
final List<DoublesPair> buckets = new ArrayList<>();
final List<Double> shifts = new ArrayList<>();
final YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(
ORIGINAL_CURVE,
buckets,
shifts,
ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithBucketedShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that performing relative shifts with an empty list of buckets returns a different yield curve with the same
* shape.
*/
@Test
public void testEmptyBucketedRelativeShifts() {
final List<DoublesPair> buckets = new ArrayList<>();
final List<Double> shifts = new ArrayList<>();
final YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithBucketedShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that performing absolute bucketed shifts of zero returns a different yield curve with the same shape.
*/
@Test
public void testZeroBucketedAbsoluteShifts() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 2.), DoublesPair.of(2., 3.), DoublesPair.of(3., 4.));
final List<Double> shifts = Arrays.asList(0., 0., 0.);
final YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.ABSOLUTE);
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that performing relative bucketed shifts of zero returns a different yield curve with the same shape.
*/
@Test
public void testZeroBucketedRelativeShifts() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 2.), DoublesPair.of(2., 3.), DoublesPair.of(3., 4.));
final List<Double> shifts = Arrays.asList(0., 0., 0.);
final YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.RELATIVE);
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that a single absolute shift over the entire relevant curve range is equivalent to a parallel shift.
*/
@Test
public void testSingleBucketedAbsoluteShift() {
final double startTime = -2;
final double endTime = 20;
final double shift = 0.02;
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(startTime, endTime));
final List<Double> shifts = Arrays.asList(shift);
final List<Double> inverseShifts = Arrays.asList(-shift);
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.ABSOLUTE);
assertCurveEquals(YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, shift, ShiftType.ABSOLUTE).getCurve(), shiftedCurve.getCurve(), startTime, endTime, 0.0001, 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.ABSOLUTE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests that a single relative shift over the entire relevant curve range is equivalent to a parallel shift.
*/
@Test
public void testSingleBucketedRelativeShift() {
final double startTime = -2;
final double endTime = 20;
final double shift = 0.02;
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(startTime, endTime));
final List<Double> shifts = Arrays.asList(shift);
final List<Double> inverseShifts = Arrays.asList(-shift / (1 + shift));
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.RELATIVE);
assertCurveEquals(YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, shift, ShiftType.RELATIVE).getCurve(), shiftedCurve.getCurve(), startTime, endTime, 0.0001, 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.RELATIVE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests a series of contiguous absolute bucketed shifts.
*/
@Test
public void testBucketedAbsoluteShifts1() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 5.), DoublesPair.of(5., 7.5), DoublesPair.of(7.5, 10));
final List<Double> shifts = Arrays.asList(3., 4., 5.);
final List<Double> inverseShifts = Arrays.asList(-3., -4., -5.);
final DoublesCurve expectedSpreadCurve = InterpolatedDoublesCurve.from(
new double[]{0, 1, 5, 7.5, 10},
new double[]{0, 3., 4., 5., 0.},
STEP_INTERPOLATOR);
final DoublesCurve expectedCurve = SpreadDoublesCurve.from(
ADD_CURVE_FUNCTION,
ORIGINAL_CURVE.getCurve(),
expectedSpreadCurve);
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.ABSOLUTE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.ABSOLUTE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests a series of contiguous relative bucketed shifts.
*/
@Test
public void testBucketedRelativeShifts1() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 5.), DoublesPair.of(5., 7.5), DoublesPair.of(7.5, 10));
final List<Double> shifts = Arrays.asList(3., 4., 5.);
final List<Double> inverseShifts = Arrays.asList(-0.75, -0.8, -5. / 6);
final DoublesCurve expectedSpreadCurve = InterpolatedDoublesCurve.from(new double[] {0, 1, 5, 7.5, 10}, new double[] {1, 4., 5., 6., 1.}, STEP_INTERPOLATOR);
final DoublesCurve expectedCurve = SpreadDoublesCurve.from(MULTIPLY_CURVE_FUNCTION, ORIGINAL_CURVE.getCurve(), expectedSpreadCurve);
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.RELATIVE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.RELATIVE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests a series of non-contiguous absolute bucketed shifts.
*/
@Test
public void testBucketedAbsoluteShifts2() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 2.), DoublesPair.of(2.5, 3.5), DoublesPair.of(5., 7.5), DoublesPair.of(7.5, 10));
final List<Double> shifts = Arrays.asList(3., 4., 5., 6.);
final List<Double> inverseShifts = Arrays.asList(-3., -4., -5., -6.);
final DoublesCurve expectedSpreadCurve = InterpolatedDoublesCurve.from(new double[] {0, 1, 2, 2.5, 3.5, 5, 7.5, 10}, new double[] {0, 3., 0, 4., 0., 5., 6., 0.}, STEP_INTERPOLATOR);
final DoublesCurve expectedCurve = SpreadDoublesCurve.from(ADD_CURVE_FUNCTION, ORIGINAL_CURVE.getCurve(), expectedSpreadCurve);
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.ABSOLUTE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.ABSOLUTE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests a series of non-contiguous relative bucketed shifts.
*/
@Test
public void testBucketedRelativeShifts2() {
final List<DoublesPair> buckets = Arrays.asList(DoublesPair.of(1., 2.), DoublesPair.of(2.5, 3.5), DoublesPair.of(5., 7.5), DoublesPair.of(7.5, 10));
final List<Double> shifts = Arrays.asList(3., 4., 5., 6.);
final List<Double> inverseShifts = Arrays.asList(-0.75, -0.8, -5. / 6, -6. / 7);
final DoublesCurve expectedSpreadCurve = InterpolatedDoublesCurve.from(new double[] {0, 1, 2, 2.5, 3.5, 5, 7.5, 10}, new double[] {1, 4., 1, 5., 1., 6., 7., 1.}, STEP_INTERPOLATOR);
final DoublesCurve expectedCurve = SpreadDoublesCurve.from(MULTIPLY_CURVE_FUNCTION, ORIGINAL_CURVE.getCurve(), expectedSpreadCurve);
YieldCurve shiftedCurve = YieldCurveUtils.withBucketedShifts(ORIGINAL_CURVE, buckets, shifts, ShiftType.RELATIVE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withBucketedShifts(shiftedCurve, buckets, inverseShifts, ShiftType.RELATIVE);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests that empty point shifts returns a different curve with the same shape.
*/
@Test
public void testEmptyPointAbsoluteShifts() {
final List<Double> points = new ArrayList<>();
final List<Double> shifts = new ArrayList<>();
final YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that empty point shifts returns a different curve with the same shape.
*/
@Test
public void testEmptyPointRelativeShifts() {
final List<Double> points = new ArrayList<>();
final List<Double> shifts = new ArrayList<>();
final YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-15);
}
/**
* Tests that a series of zero absolute point shifts returns a different curve with the same shape.
*/
@Test
public void testPointZeroAbsoluteShifts() {
List<Double> points = Arrays.asList(1., 2., 3., 4.);
final List<Double> shifts = Arrays.asList(0., 0., 0., 0.);
YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
points = Arrays.asList(1.1, 2.1, 3.1, 4.1);
final double[] newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
final double[] newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1), 0.015, INTERPOLATED_CURVE.getYValue(2.1), 0.017, INTERPOLATED_CURVE.getYValue(3.1), 0.02, INTERPOLATED_CURVE.getYValue(4.1), 0.025, 0.035, 0.05};
final DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests that a series of zero relative point shifts returns a different curve with the same shape.
*/
@Test
public void testPointZeroRelativeShifts() {
List<Double> points = Arrays.asList(1., 2., 3., 4.);
final List<Double> shifts = Arrays.asList(0., 0., 0., 0.);
YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertFalse(ORIGINAL_CURVE.equals(shiftedCurve));
assertCurveEquals(ORIGINAL_CURVE.getCurve(), shiftedCurve.getCurve(), 1e-9);
points = Arrays.asList(1.1, 2.1, 3.1, 4.1);
final double[] newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
final double[] newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1), 0.015, INTERPOLATED_CURVE.getYValue(2.1), 0.017, INTERPOLATED_CURVE.getYValue(3.1), 0.02, INTERPOLATED_CURVE.getYValue(4.1), 0.025, 0.035, 0.05};
final DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
}
/**
* Tests a series of absolute point shifts.
*/
@Test
public void testPointAbsoluteShifts() {
List<Double> points = Arrays.asList(1., 2., 3., 4.);
final List<Double> shifts = Arrays.asList(2., 3., 4., 5.);
final double[] y = new double[Y.length];
System.arraycopy(Y, 0, y, 0, Y.length);
y[0] += 2;
y[1] += 3;
y[2] += 4;
y[3] += 5;
YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(T, y, INTERPOLATOR);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
final List<Double> inverseShifts = Arrays.asList(-2., -3., -4., -5.);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), YieldCurveUtils.withPointShifts(shiftedCurve, points, inverseShifts, ShiftType.ABSOLUTE).getCurve(), 1e-9);
points = Arrays.asList(1.1, 2.1, 3.1, 4.1);
double[] newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
double[] newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1) + 2, 0.015, INTERPOLATED_CURVE.getYValue(2.1) + 3, 0.017, INTERPOLATED_CURVE.getYValue(3.1) + 4, 0.02, INTERPOLATED_CURVE.getYValue(4.1) + 5, 0.025, 0.035, 0.05};
expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.ABSOLUTE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1), 0.015, INTERPOLATED_CURVE.getYValue(2.1), 0.017, INTERPOLATED_CURVE.getYValue(3.1), 0.02, INTERPOLATED_CURVE.getYValue(4.1), 0.025, 0.035, 0.05};
expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
assertCurveEquals(expectedCurve, YieldCurveUtils.withPointShifts(shiftedCurve, points, inverseShifts, ShiftType.ABSOLUTE).getCurve(), 1e-9);
}
/**
* Tests a series of relative point shifts.
*/
@Test
public void testPointRelativeShifts() {
List<Double> points = Arrays.asList(1., 2., 3., 4.);
final List<Double> shifts = Arrays.asList(2., 3., 4., 5.);
final double[] y = new double[Y.length];
System.arraycopy(Y, 0, y, 0, Y.length);
y[0] *= 3;
y[1] *= 4;
y[2] *= 5;
y[3] *= 6;
YieldCurve shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
DoublesCurve expectedCurve = InterpolatedDoublesCurve.from(T, y, INTERPOLATOR);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
assertEquals("ORIGINAL_WithPointShifts", shiftedCurve.getName());
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
final List<Double> inverseShifts = Arrays.asList(-2. / 3, -0.75, -0.8, -5 / 6.);
assertCurveEquals(ORIGINAL_CURVE.getCurve(), YieldCurveUtils.withPointShifts(shiftedCurve, points, inverseShifts, ShiftType.RELATIVE).getCurve(), 1e-9);
points = Arrays.asList(1.1, 2.1, 3.1, 4.1);
double[] newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
double[] newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1) * 3, 0.015, INTERPOLATED_CURVE.getYValue(2.1) * 4, 0.017, INTERPOLATED_CURVE.getYValue(3.1) * 5, 0.02, INTERPOLATED_CURVE.getYValue(4.1) * 6, 0.025, 0.035, 0.05};
expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
shiftedCurve = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE);
assertCurveEquals(expectedCurve, shiftedCurve.getCurve(), 1e-9);
newT = new double[] {1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 6, 7};
newY = new double[] {0.01, INTERPOLATED_CURVE.getYValue(1.1), 0.015, INTERPOLATED_CURVE.getYValue(2.1), 0.017, INTERPOLATED_CURVE.getYValue(3.1), 0.02, INTERPOLATED_CURVE.getYValue(4.1), 0.025, 0.035, 0.05};
expectedCurve = InterpolatedDoublesCurve.from(newT, newY, INTERPOLATOR);
assertCurveEquals(expectedCurve, YieldCurveUtils.withPointShifts(shiftedCurve, points, inverseShifts, ShiftType.RELATIVE).getCurve(), 1e-9);
}
/**
* Tests the curve name suffix can be specified when shifting a curve.
*/
@Test
public void testCurveNameSuffix() {
List<Double> points = ImmutableList.of();
final List<Double> shifts = ImmutableList.of();
YieldCurve shiftedCurve1 = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE, "");
assertEquals(ORIGINAL_NAME, shiftedCurve1.getName());
String suffix = "suffix";
YieldCurve shiftedCurve2 = YieldCurveUtils.withPointShifts(ORIGINAL_CURVE, points, shifts, ShiftType.RELATIVE, suffix);
assertEquals(ORIGINAL_NAME + suffix, shiftedCurve2.getName());
YieldCurve shiftedCurve3 = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, 0d, ShiftType.RELATIVE, "");
assertEquals(ORIGINAL_NAME, shiftedCurve3.getName());
YieldCurve shiftedCurve4 = YieldCurveUtils.withParallelShift(ORIGINAL_CURVE, 0d, ShiftType.RELATIVE, suffix);
assertEquals(ORIGINAL_NAME + suffix, shiftedCurve4.getName());
YieldCurve shiftedCurve5 =
YieldCurveUtils.withBucketedShifts(
ORIGINAL_CURVE,
ImmutableList.<DoublesPair>of(),
ImmutableList.<Double>of(),
ShiftType.RELATIVE,
"");
assertEquals(ORIGINAL_NAME, shiftedCurve5.getName());
YieldCurve shiftedCurve6 =
YieldCurveUtils.withBucketedShifts(
ORIGINAL_CURVE,
ImmutableList.<DoublesPair>of(),
ImmutableList.<Double>of(),
ShiftType.RELATIVE,
suffix);
assertEquals(ORIGINAL_NAME + suffix, shiftedCurve6.getName());
}
/**
* Tests that two curves are equal to within an absolute tolerance by sampling.
* @param expected The expected curve
* @param actual The actual curve
* @param eps The absolute result tolerance
*/
private static void assertCurveEquals(final DoublesCurve expected, final DoublesCurve actual, final double eps) {
for (double t = -1; t <= 10; t += 0.001) {
assertEquals("t = " + t, expected.getYValue(t), actual.getYValue(t), eps);
}
}
/**
* Tests that two curves are equal to within an absolute tolerance by sampling.
* @param expected The expected curve
* @param actual The actual curve
* @param startTime The time at which to start comparing the curves
* @param endTime The time at which to end comparing the curves
* @param delta The time step
* @param eps The absolute result tolerance
*/
private static void assertCurveEquals(final DoublesCurve expected, final DoublesCurve actual, final double startTime,
final double endTime, final double delta, final double eps) {
for (double t = -1; t <= 10; t += 0.001) {
assertEquals("t = " + t, expected.getYValue(t), actual.getYValue(t), eps);
}
}
}