/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.market.curve;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365F;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.coverBeanEquals;
import static com.opengamma.strata.collect.TestHelper.coverImmutableBean;
import static com.opengamma.strata.collect.TestHelper.date;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.ValueType;
import com.opengamma.strata.market.curve.interpolator.BoundCurveInterpolator;
import com.opengamma.strata.market.curve.interpolator.CurveExtrapolator;
import com.opengamma.strata.market.curve.interpolator.CurveExtrapolators;
import com.opengamma.strata.market.curve.interpolator.CurveInterpolator;
import com.opengamma.strata.market.curve.interpolator.CurveInterpolators;
import com.opengamma.strata.market.param.CurrencyParameterSensitivity;
import com.opengamma.strata.market.param.LabelDateParameterMetadata;
import com.opengamma.strata.market.param.ParameterMetadata;
import com.opengamma.strata.market.param.UnitParameterSensitivity;
/**
* Test {@link InterpolatedNodalCurve}.
*/
@Test
public class InterpolatedNodalCurveTest {
private static final int SIZE = 3;
private static final String TNR_1Y = "1Y";
private static final String NAME = "TestCurve";
private static final CurveName CURVE_NAME = CurveName.of(NAME);
private static final CurveMetadata METADATA = Curves.zeroRates(CURVE_NAME, ACT_365F);
private static final CurveMetadata METADATA_ENTRIES =
Curves.zeroRates(CURVE_NAME, ACT_365F, ParameterMetadata.listOfEmpty(SIZE));
private static final CurveMetadata METADATA_ENTRIES2 =
Curves.zeroRates(CURVE_NAME, ACT_365F, ParameterMetadata.listOfEmpty(SIZE + 2));
private static final CurveMetadata METADATA_NOPARAM = Curves.zeroRates(CURVE_NAME, ACT_365F);
private static final DoubleArray XVALUES = DoubleArray.of(1d, 2d, 3d);
private static final DoubleArray XVALUES2 = DoubleArray.of(0d, 2d, 3d);
private static final DoubleArray YVALUES = DoubleArray.of(5d, 7d, 8d);
private static final DoubleArray YVALUES_BUMPED = DoubleArray.of(3d, 5d, 6d);
private static final CurveInterpolator INTERPOLATOR = CurveInterpolators.LOG_LINEAR;
private static final CurveExtrapolator FLAT_EXTRAPOLATOR = CurveExtrapolators.FLAT;
private static final CurveExtrapolator LINEAR_EXTRAPOLATOR = CurveExtrapolators.LINEAR;
//-------------------------------------------------------------------------
public void test_of_CurveMetadata() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getParameter(0)).isEqualTo(YVALUES.get(0));
assertThat(test.getParameter(1)).isEqualTo(YVALUES.get(1));
assertThat(test.getParameterMetadata(0)).isSameAs(METADATA_ENTRIES.getParameterMetadata().get().get(0));
assertThat(test.getParameterMetadata(1)).isSameAs(METADATA_ENTRIES.getParameterMetadata().get().get(1));
assertThat(test.withParameter(0, 2d)).isEqualTo(
InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES.with(0, 2d), INTERPOLATOR));
assertThat(test.withPerturbation((i, v, m) -> v - 2d)).isEqualTo(
InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES_BUMPED, INTERPOLATOR));
assertThat(test.getExtrapolatorLeft().getName()).isEqualTo(FLAT_EXTRAPOLATOR.getName());
assertThat(test.getInterpolator().getName()).isEqualTo(INTERPOLATOR.getName());
assertThat(test.getExtrapolatorRight().getName()).isEqualTo(FLAT_EXTRAPOLATOR.getName());
assertThat(test.getMetadata()).isEqualTo(METADATA_ENTRIES);
assertThat(test.getXValues()).isEqualTo(XVALUES);
assertThat(test.getYValues()).isEqualTo(YVALUES);
}
public void test_of_extrapolators() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(
METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR, LINEAR_EXTRAPOLATOR, LINEAR_EXTRAPOLATOR);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getExtrapolatorLeft().getName()).isEqualTo(LINEAR_EXTRAPOLATOR.getName());
assertThat(test.getInterpolator().getName()).isEqualTo(INTERPOLATOR.getName());
assertThat(test.getExtrapolatorRight().getName()).isEqualTo(LINEAR_EXTRAPOLATOR.getName());
}
public void test_of_noCurveMetadata() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA_NOPARAM, XVALUES, YVALUES, INTERPOLATOR);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getParameter(0)).isEqualTo(YVALUES.get(0));
assertThat(test.getParameter(1)).isEqualTo(YVALUES.get(1));
assertThat(test.getParameterMetadata(0)).isEqualTo(SimpleCurveParameterMetadata.of(ValueType.YEAR_FRACTION, XVALUES.get(0)));
assertThat(test.getParameterMetadata(1)).isEqualTo(SimpleCurveParameterMetadata.of(ValueType.YEAR_FRACTION, XVALUES.get(1)));
}
public void test_of_invalid() {
// not enough nodes
assertThrowsIllegalArg(() -> InterpolatedNodalCurve.of(
METADATA, DoubleArray.of(1d), DoubleArray.of(1d), INTERPOLATOR));
// x node size != y node size
assertThrowsIllegalArg(() -> InterpolatedNodalCurve.of(
METADATA, XVALUES, DoubleArray.of(1d, 3d), INTERPOLATOR));
// parameter metadata size != node size
assertThrowsIllegalArg(() -> InterpolatedNodalCurve.of(
METADATA_ENTRIES, DoubleArray.of(1d, 3d), DoubleArray.of(1d, 3d), INTERPOLATOR));
// x not in order
assertThrowsIllegalArg(() -> InterpolatedNodalCurve.of(
METADATA, DoubleArray.of(2d, 1d), DoubleArray.of(2d, 3d), INTERPOLATOR));
}
//-------------------------------------------------------------------------
public void test_lookup() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
BoundCurveInterpolator interp = INTERPOLATOR.bind(XVALUES, YVALUES, FLAT_EXTRAPOLATOR, FLAT_EXTRAPOLATOR);
assertThat(test.yValue(XVALUES.get(0))).isEqualTo(YVALUES.get(0));
assertThat(test.yValue(XVALUES.get(1))).isEqualTo(YVALUES.get(1));
assertThat(test.yValue(XVALUES.get(2))).isEqualTo(YVALUES.get(2));
assertThat(test.yValue(10d)).isEqualTo(interp.interpolate(10d));
assertThat(test.yValueParameterSensitivity(10d).getMarketDataName()).isEqualTo(CURVE_NAME);
assertThat(test.yValueParameterSensitivity(10d).getSensitivity()).isEqualTo(interp.parameterSensitivity(10d));
assertThat(test.firstDerivative(10d)).isEqualTo(interp.firstDerivative(10d));
}
//-------------------------------------------------------------------------
public void test_withMetadata() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
InterpolatedNodalCurve test = base.withMetadata(METADATA_ENTRIES);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getMetadata()).isEqualTo(METADATA_ENTRIES);
assertThat(test.getXValues()).isEqualTo(XVALUES);
assertThat(test.getYValues()).isEqualTo(YVALUES);
}
public void test_withMetadata_badSize() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
assertThrowsIllegalArg(() -> base.withMetadata(METADATA_ENTRIES2));
}
//-------------------------------------------------------------------------
public void test_withValues() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
InterpolatedNodalCurve test = base.withYValues(YVALUES_BUMPED);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getMetadata()).isEqualTo(METADATA);
assertThat(test.getXValues()).isEqualTo(XVALUES);
assertThat(test.getYValues()).isEqualTo(YVALUES_BUMPED);
}
public void test_withValues_badSize() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
assertThrowsIllegalArg(() -> base.withYValues(DoubleArray.EMPTY));
assertThrowsIllegalArg(() -> base.withYValues(DoubleArray.of(4d, 6d)));
}
//-------------------------------------------------------------------------
public void test_withValuesXy() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
InterpolatedNodalCurve test = base.withValues(XVALUES2, YVALUES_BUMPED);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getMetadata()).isEqualTo(METADATA);
assertThat(test.getXValues()).isEqualTo(XVALUES2);
assertThat(test.getYValues()).isEqualTo(YVALUES_BUMPED);
}
public void test_withValuesXy_badSize() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
assertThrowsIllegalArg(() -> base.withValues(DoubleArray.EMPTY, DoubleArray.EMPTY));
assertThrowsIllegalArg(() -> base.withValues(DoubleArray.of(1d, 3d, 5d), DoubleArray.of(4d, 6d)));
}
//-------------------------------------------------------------------------
public void test_withNode_atStart_withMetadata() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR);
LabelDateParameterMetadata item = LabelDateParameterMetadata.of(date(2015, 6, 30), TNR_1Y);
InterpolatedNodalCurve test = base.withNode(0.5d, 4d, item);
List<ParameterMetadata> list = new ArrayList<>();
list.add(item);
list.addAll(ParameterMetadata.listOfEmpty(SIZE));
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE + 1);
assertThat(test.getMetadata()).isEqualTo(METADATA_ENTRIES.withParameterMetadata(list));
assertThat(test.getXValues()).isEqualTo(DoubleArray.of(0.5d, 1d, 2d, 3d));
assertThat(test.getYValues()).isEqualTo(DoubleArray.of(4d, 5d, 7d, 8d));
}
public void test_withNode_inMiddle_withMetadata() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR);
LabelDateParameterMetadata item = LabelDateParameterMetadata.of(date(2015, 6, 30), TNR_1Y);
InterpolatedNodalCurve test = base.withNode(2.5d, 4d, item);
List<ParameterMetadata> list = new ArrayList<>(METADATA_ENTRIES.getParameterMetadata().get());
list.add(2, item);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE + 1);
assertThat(test.getMetadata()).isEqualTo(METADATA_ENTRIES.withParameterMetadata(list));
assertThat(test.getXValues()).isEqualTo(DoubleArray.of(1d, 2d, 2.5d, 3d));
assertThat(test.getYValues()).isEqualTo(DoubleArray.of(5d, 7d, 4d, 8d));
}
public void test_withNode_atEnd_withoutMetadata() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
LabelDateParameterMetadata item = LabelDateParameterMetadata.of(date(2015, 6, 30), TNR_1Y);
InterpolatedNodalCurve test = base.withNode(0.5d, 4d, item);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE + 1);
assertThat(test.getMetadata()).isEqualTo(METADATA);
assertThat(test.getXValues()).isEqualTo(DoubleArray.of(0.5d, 1d, 2d, 3d));
assertThat(test.getYValues()).isEqualTo(DoubleArray.of(4d, 5d, 7d, 8d));
}
public void test_withNode_replace_withMetadata() {
InterpolatedNodalCurve base = InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR);
LabelDateParameterMetadata item = LabelDateParameterMetadata.of(date(2015, 6, 30), TNR_1Y);
InterpolatedNodalCurve test = base.withNode(2d, 4d, item);
List<ParameterMetadata> list = new ArrayList<>(METADATA_ENTRIES.getParameterMetadata().get());
list.set(1, item);
assertThat(test.getName()).isEqualTo(CURVE_NAME);
assertThat(test.getParameterCount()).isEqualTo(SIZE);
assertThat(test.getMetadata()).isEqualTo(METADATA.withParameterMetadata(list));
assertThat(test.getXValues()).isEqualTo(DoubleArray.of(1d, 2d, 3d));
assertThat(test.getYValues()).isEqualTo(DoubleArray.of(5d, 4d, 8d));
}
//-------------------------------------------------------------------------
public void test_createParameterSensitivity() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA_ENTRIES, XVALUES, YVALUES, INTERPOLATOR);
assertThat(test.createParameterSensitivity(DoubleArray.of(2d, 3d, 4d))).isEqualTo(
UnitParameterSensitivity.of(CURVE_NAME, DoubleArray.of(2d, 3d, 4d)));
assertThat(test.createParameterSensitivity(Currency.GBP, DoubleArray.of(2d, 3d, 4d))).isEqualTo(
CurrencyParameterSensitivity.of(CURVE_NAME, Currency.GBP, DoubleArray.of(2d, 3d, 4d)));
}
//-------------------------------------------------------------------------
public void coverage() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
coverImmutableBean(test);
InterpolatedNodalCurve test2 = InterpolatedNodalCurve.builder()
.metadata(METADATA_ENTRIES)
.xValues(XVALUES2)
.yValues(YVALUES_BUMPED)
.extrapolatorLeft(CurveExtrapolators.LOG_LINEAR)
.interpolator(CurveInterpolators.DOUBLE_QUADRATIC)
.extrapolatorRight(CurveExtrapolators.LOG_LINEAR)
.build();
coverBeanEquals(test, test2);
}
public void test_serialization() {
InterpolatedNodalCurve test = InterpolatedNodalCurve.of(METADATA, XVALUES, YVALUES, INTERPOLATOR);
assertSerialization(test);
}
}