/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame.marketdata.scenarios;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.financial.analytics.ircurve.strips.CurveNodeWithIdentifier;
import com.opengamma.id.ExternalId;
import com.opengamma.sesame.CurveNodeId;
import com.opengamma.sesame.TenorCurveNodeId;
import com.opengamma.util.time.Tenor;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.opengamma.core.marketdatasnapshot.SnapshotDataBundle;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.sesame.function.scenarios.curvedata.CurveTestUtils;
import com.opengamma.util.test.TestGroup;
import static com.opengamma.sesame.function.scenarios.curvedata.CurveTestUtils.nodeWithId;
import static com.opengamma.sesame.function.scenarios.curvedata.CurveTestUtils.swapNode;
@Test(groups = TestGroup.UNIT)
public class MulticurveInputPointShiftTest {
@Test
public void noShift() {
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveTestUtils.checkValues(inputs.getNodeData(), 0.1, 0.2, 0.7, 0.4);
}
@Test(expectedExceptions = {OpenGammaRuntimeException.class})
public void usingFuturesAsUnderlyingsNotSupportedAtTheMoment() {
// shift 6M by 0 bp
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), 0.00
);
MulticurveInputPointShift shift = MulticurveInputPointShift.absolute(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(CurveTestUtils.NODES), dataBundle());
// this will throw because the curve contains futures as underlyings. not yet supported.
shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
}
@Test
public void shiftOfZeroBpAbsoluteDoesNotChangeCurve() {
// shift 6M by 0 bp
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), 0.00
);
MulticurveInputPointShift shift = MulticurveInputPointShift.absolute(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.2, 0.7, 0.4);
}
@Test
public void shiftUpOfTenBpAbsolute() {
// shift 6M up 10 bp
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), 0.0010
);
MulticurveInputPointShift shift = MulticurveInputPointShift.absolute(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.201, 0.7, 0.4);
}
@Test
public void shiftDownOfTenBpAbsolute() {
// shift 6M down 10 bp
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), -0.0010
);
MulticurveInputPointShift shift = MulticurveInputPointShift.absolute(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.199, 0.7, 0.4);
}
@Test
public void steepenCurveAbsolute() {
// shift 6M down 10 bp, shift 1Y up 10 bp
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), -0.0010,
TenorCurveNodeId.of(Tenor.ONE_YEAR), 0.0010
);
MulticurveInputPointShift shift = MulticurveInputPointShift.absolute(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.199, 0.7, 0.401);
}
@Test
public void shiftOfZeroPctRelativeDoesNotChangeCurve() {
// shift 6M by 0%
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), 0.00
);
MulticurveInputPointShift shift = MulticurveInputPointShift.relative(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.2, 0.7, 0.4);
}
@Test
public void shiftUpTenPctRelative() {
// shift 6M up 10%
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), 0.1
);
MulticurveInputPointShift shift = MulticurveInputPointShift.relative(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.22, 0.7, 0.4);
}
@Test
public void shiftDownTenPctRelative() {
// shift 6M up 10%
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), -0.1
);
MulticurveInputPointShift shift = MulticurveInputPointShift.relative(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.18, 0.7, 0.4);
}
@Test
public void steepenCurveRelative() {
// shift 6M down 10%, shift 1Y up 10%
Map<CurveNodeId, Double> shifts = ImmutableMap.of(
(CurveNodeId) TenorCurveNodeId.of(Tenor.SIX_MONTHS), -0.1,
TenorCurveNodeId.of(Tenor.ONE_YEAR), 0.1
);
MulticurveInputPointShift shift = MulticurveInputPointShift.relative(shifts);
CurveInputs inputs = new CurveInputs(ImmutableSet.copyOf(nodes()), dataBundle());
CurveInputs shiftedInputs = shift.apply(inputs, StandardMatchDetails.multicurve("not used"));
CurveTestUtils.checkValues(shiftedInputs.getNodeData(), 0.1, 0.18, 0.7, 0.44);
}
private static Set<CurveNodeWithIdentifier> nodes() {
return Sets.newHashSet(
nodeWithId(CurveTestUtils.ID1, swapNode(Tenor.ofMonths(0), Tenor.ofMonths(3))),
nodeWithId(CurveTestUtils.ID2, swapNode(Tenor.ofMonths(3), Tenor.ofMonths(3))),
nodeWithId(CurveTestUtils.ID3, swapNode(Tenor.ofMonths(6), Tenor.ofMonths(3))),
nodeWithId(CurveTestUtils.ID4, swapNode(Tenor.ofYears(0), Tenor.ofYears(1)))
);
}
private static SnapshotDataBundle dataBundle() {
SnapshotDataBundle dataBundle = new SnapshotDataBundle();
for (Map.Entry<ExternalIdBundle, Double> entry : CurveTestUtils.VALUE_MAP.entrySet()) {
dataBundle.setDataPoint(entry.getKey(), entry.getValue());
}
return dataBundle;
}
}