/**
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.market.param;
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 org.testng.Assert.assertEquals;
import java.util.List;
import java.util.Optional;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.FxMatrix;
import com.opengamma.strata.basics.currency.FxRate;
import com.opengamma.strata.collect.array.DoubleMatrix;
import com.opengamma.strata.collect.tuple.Pair;
import com.opengamma.strata.data.MarketDataName;
import com.opengamma.strata.market.curve.CurveName;
/**
* Test {@link CrossGammaParameterSensitivities}.
*/
@Test
public class CrossGammaParameterSensitivitiesTest {
private static final double FACTOR1 = 3.14;
private static final DoubleMatrix MATRIX_USD1 = DoubleMatrix.of(2, 2, 100, 200, 300, 123);
private static final DoubleMatrix MATRIX_USD2 = DoubleMatrix.of(2, 2, 1000, 250, 321, 123);
private static final DoubleMatrix MATRIX_USD2_IN_EUR = DoubleMatrix.of(2, 2, 1000 / 1.6, 250 / 1.6, 321 / 1.6, 123 / 1.6);
private static final DoubleMatrix MATRIX_USD12 = DoubleMatrix.of(2, 4, 100, 200, 1000, 250, 300, 123, 321, 123);
private static final DoubleMatrix MATRIX_USD21 = DoubleMatrix.of(2, 4, 1000, 250, -500, -400, 321, 123, -200, -300);
private static final DoubleMatrix MATRIX_ZERO = DoubleMatrix.of(2, 2, 0, 0, 0, 0);
private static final DoubleMatrix TOTAL_USD = DoubleMatrix.of(2, 2, 1100, 450, 621, 246);
private static final DoubleMatrix MATRIX_EUR1 = DoubleMatrix.of(2, 2, 1000, 250, 321, 123);
private static final DoubleMatrix MATRIX_EUR1_IN_USD =
DoubleMatrix.of(2, 2, 1000 * 1.6, 250 * 1.6, 321 * 1.6, 123 * 1.6);
private static final Currency USD = Currency.USD;
private static final Currency EUR = Currency.EUR;
private static final FxRate FX_RATE = FxRate.of(EUR, USD, 1.6d);
private static final MarketDataName<?> NAME0 = CurveName.of("NAME-0");
private static final MarketDataName<?> NAME1 = CurveName.of("NAME-1");
private static final MarketDataName<?> NAME2 = CurveName.of("NAME-2");
private static final MarketDataName<?> NAME3 = CurveName.of("NAME-3");
private static final List<ParameterMetadata> METADATA0 = ParameterMetadata.listOfEmpty(2);
private static final List<ParameterMetadata> METADATA1 = ParameterMetadata.listOfEmpty(2);
private static final List<ParameterMetadata> METADATA2 = ParameterMetadata.listOfEmpty(2);
private static final List<ParameterMetadata> METADATA3 = ParameterMetadata.listOfEmpty(2);
private static final CrossGammaParameterSensitivity ENTRY_USD =
CrossGammaParameterSensitivity.of(NAME1, METADATA1, USD, MATRIX_USD1);
private static final CrossGammaParameterSensitivity ENTRY_USD2 =
CrossGammaParameterSensitivity.of(NAME1, METADATA1, USD, MATRIX_USD2);
private static final CrossGammaParameterSensitivity ENTRY_USD_TOTAL =
CrossGammaParameterSensitivity.of(NAME1, METADATA1, USD, TOTAL_USD);
private static final CrossGammaParameterSensitivity ENTRY_USD2_IN_EUR =
CrossGammaParameterSensitivity.of(NAME1, METADATA1, EUR, MATRIX_USD2_IN_EUR);
private static final CrossGammaParameterSensitivity ENTRY_EUR =
CrossGammaParameterSensitivity.of(NAME2, METADATA2, EUR, MATRIX_EUR1);
private static final CrossGammaParameterSensitivity ENTRY_EUR_IN_USD =
CrossGammaParameterSensitivity.of(NAME2, METADATA2, USD, MATRIX_EUR1_IN_USD);
private static final CrossGammaParameterSensitivity ENTRY_ZERO0 =
CrossGammaParameterSensitivity.of(NAME0, METADATA0, USD, MATRIX_ZERO);
private static final CrossGammaParameterSensitivity ENTRY_ZERO3 =
CrossGammaParameterSensitivity.of(NAME3, METADATA3, USD, MATRIX_ZERO);
private static final CrossGammaParameterSensitivity ENTRY_USD12 = CrossGammaParameterSensitivity.of(
NAME1, METADATA1, ImmutableList.of(Pair.of(NAME1, METADATA1), Pair.of(NAME2, METADATA2)), USD, MATRIX_USD12);
private static final CrossGammaParameterSensitivity ENTRY_USD21 = CrossGammaParameterSensitivity.of(
NAME2, METADATA2, ImmutableList.of(Pair.of(NAME1, METADATA1), Pair.of(NAME2, METADATA2)), USD, MATRIX_USD21);
private static final CrossGammaParameterSensitivities SENSI_1 = CrossGammaParameterSensitivities.of(ENTRY_USD);
private static final CrossGammaParameterSensitivities SENSI_2 =
CrossGammaParameterSensitivities.of(ImmutableList.of(ENTRY_USD2, ENTRY_EUR));
private static final CrossGammaParameterSensitivities SENSI_3 =
CrossGammaParameterSensitivities.of(ImmutableList.of(ENTRY_USD12, ENTRY_USD21));
private static final double TOLERENCE_CMP = 1.0E-8;
//-------------------------------------------------------------------------
public void test_empty() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.empty();
assertEquals(test.size(), 0);
assertEquals(test.getSensitivities().size(), 0);
}
public void test_of_single() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(ENTRY_USD);
assertEquals(test.size(), 1);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD));
}
public void test_of_array_none() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of();
assertEquals(test.size(), 0);
}
public void test_of_list_none() {
ImmutableList<CrossGammaParameterSensitivity> list = ImmutableList.of();
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(list);
assertEquals(test.size(), 0);
}
public void test_of_list_notNormalized() {
ImmutableList<CrossGammaParameterSensitivity> list = ImmutableList.of(ENTRY_USD, ENTRY_EUR);
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(list);
assertEquals(test.size(), 2);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD, ENTRY_EUR));
}
public void test_of_list_normalized() {
ImmutableList<CrossGammaParameterSensitivity> list = ImmutableList.of(ENTRY_USD, ENTRY_USD2);
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(list);
assertEquals(test.size(), 1);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD_TOTAL));
}
//-------------------------------------------------------------------------
public void test_getSensitivity() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(ENTRY_USD);
assertEquals(test.getSensitivity(NAME1, USD), ENTRY_USD);
assertThrowsIllegalArg(() -> test.getSensitivity(NAME1, EUR));
assertThrowsIllegalArg(() -> test.getSensitivity(NAME0, USD));
assertThrowsIllegalArg(() -> test.getSensitivity(NAME0, EUR));
}
public void test_findSensitivity() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.of(ENTRY_USD);
assertEquals(test.findSensitivity(NAME1, USD), Optional.of(ENTRY_USD));
assertEquals(test.findSensitivity(NAME1, EUR), Optional.empty());
assertEquals(test.findSensitivity(NAME0, USD), Optional.empty());
assertEquals(test.findSensitivity(NAME0, EUR), Optional.empty());
}
//-------------------------------------------------------------------------
public void test_combinedWith_one_notNormalized() {
CrossGammaParameterSensitivities test = SENSI_1.combinedWith(ENTRY_EUR);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD, ENTRY_EUR));
}
public void test_combinedWith_one_normalized() {
CrossGammaParameterSensitivities test = SENSI_1.combinedWith(ENTRY_USD2);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD_TOTAL));
}
public void test_combinedWith_other() {
CrossGammaParameterSensitivities test = SENSI_1.combinedWith(SENSI_2);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD_TOTAL, ENTRY_EUR));
}
public void test_combinedWith_otherEmpty() {
CrossGammaParameterSensitivities test = SENSI_1.combinedWith(CrossGammaParameterSensitivities.empty());
assertEquals(test, SENSI_1);
}
public void test_combinedWith_empty() {
CrossGammaParameterSensitivities test = CrossGammaParameterSensitivities.empty().combinedWith(SENSI_1);
assertEquals(test, SENSI_1);
}
//-------------------------------------------------------------------------
public void test_convertedTo_singleCurrency() {
CrossGammaParameterSensitivities test = SENSI_1.convertedTo(USD, FxMatrix.empty());
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD));
}
public void test_convertedTo_multipleCurrency() {
CrossGammaParameterSensitivities test = SENSI_2.convertedTo(USD, FX_RATE);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD2, ENTRY_EUR_IN_USD));
}
public void test_convertedTo_multipleCurrency_mergeWhenSameName() {
CrossGammaParameterSensitivities test = SENSI_1.combinedWith(ENTRY_USD2_IN_EUR).convertedTo(USD, FX_RATE);
assertEquals(test.getSensitivities(), ImmutableList.of(ENTRY_USD_TOTAL));
}
//-------------------------------------------------------------------------
public void test_total_singleCurrency() {
assertEquals(SENSI_1.total(USD, FxMatrix.empty()).getAmount(), MATRIX_USD1.total(), 1e-8);
}
public void test_total_multipleCurrency() {
assertEquals(SENSI_2.total(USD, FX_RATE).getAmount(), MATRIX_USD2.total() + MATRIX_EUR1.total() * 1.6d, 1e-8);
}
public void test_totalMulti_singleCurrency() {
assertEquals(SENSI_1.total().size(), 1);
assertEquals(SENSI_1.total().getAmount(USD).getAmount(), MATRIX_USD1.total(), 1e-8);
}
public void test_totalMulti_multipleCurrency() {
assertEquals(SENSI_2.total().size(), 2);
assertEquals(SENSI_2.total().getAmount(USD).getAmount(), MATRIX_USD2.total(), 1e-8);
assertEquals(SENSI_2.total().getAmount(EUR).getAmount(), MATRIX_EUR1.total(), 1e-8);
}
public void test_diagonal() {
assertEquals(SENSI_2.diagonal().size(), 2);
assertEquals(SENSI_2.diagonal().getSensitivity(NAME1, USD), ENTRY_USD2.diagonal());
assertEquals(SENSI_2.diagonal().getSensitivity(NAME2, EUR), ENTRY_EUR.diagonal());
assertEquals(SENSI_3.diagonal().getSensitivity(NAME1, USD), ENTRY_USD12.diagonal());
assertEquals(SENSI_3.diagonal().getSensitivity(NAME2, USD), ENTRY_USD21.diagonal());
}
//-------------------------------------------------------------------------
public void test_multipliedBy() {
CrossGammaParameterSensitivities multiplied = SENSI_1.multipliedBy(FACTOR1);
DoubleMatrix test = multiplied.getSensitivities().get(0).getSensitivity();
for (int i = 0; i < MATRIX_USD1.columnCount(); i++) {
for (int j = 0; j < MATRIX_USD1.rowCount(); j++) {
assertEquals(test.get(i, j), MATRIX_USD1.get(i, j) * FACTOR1);
}
}
}
public void test_mapSensitivities() {
CrossGammaParameterSensitivities multiplied = SENSI_1.mapSensitivities(a -> 1 / a);
DoubleMatrix test = multiplied.getSensitivities().get(0).getSensitivity();
for (int i = 0; i < MATRIX_USD1.columnCount(); i++) {
for (int j = 0; j < MATRIX_USD1.rowCount(); j++) {
assertEquals(test.get(i, j), 1 / MATRIX_USD1.get(i, j));
}
}
}
public void test_multipliedBy_vs_combinedWith() {
CrossGammaParameterSensitivities multiplied = SENSI_2.multipliedBy(2d);
CrossGammaParameterSensitivities added = SENSI_2.combinedWith(SENSI_2);
assertEquals(multiplied, added);
}
public void test_getSensitivity_name() {
assertEquals(SENSI_3.getSensitivity(NAME1, NAME1, USD), ENTRY_USD);
assertEquals(SENSI_3.getSensitivity(NAME1, NAME2, USD),
CrossGammaParameterSensitivity.of(NAME1, METADATA1, NAME2, METADATA2, USD, MATRIX_USD2));
assertEquals(SENSI_3.getSensitivity(NAME2, NAME1, USD),
CrossGammaParameterSensitivity.of(NAME2, METADATA2, NAME1, METADATA1, USD, MATRIX_USD2));
assertEquals(SENSI_3.getSensitivity(NAME2, NAME2, USD),
CrossGammaParameterSensitivity.of(NAME2, METADATA2, NAME2, METADATA2, USD,
DoubleMatrix.of(2, 2, -500, -400, -200, -300)));
}
//-------------------------------------------------------------------------
public void test_equalWithTolerance() {
CrossGammaParameterSensitivities sensUsdTotal = CrossGammaParameterSensitivities.of(ENTRY_USD_TOTAL);
CrossGammaParameterSensitivities sensEur = CrossGammaParameterSensitivities.of(ENTRY_EUR);
CrossGammaParameterSensitivities sens1plus2 = SENSI_1.combinedWith(ENTRY_USD2);
CrossGammaParameterSensitivities sensZeroA = CrossGammaParameterSensitivities.of(ENTRY_ZERO3);
CrossGammaParameterSensitivities sensZeroB = CrossGammaParameterSensitivities.of(ENTRY_ZERO0);
CrossGammaParameterSensitivities sens1plus2plus0a = SENSI_1.combinedWith(ENTRY_USD2).combinedWith(ENTRY_ZERO0);
CrossGammaParameterSensitivities sens1plus2plus0b = SENSI_1.combinedWith(ENTRY_USD2).combinedWith(ENTRY_ZERO3);
CrossGammaParameterSensitivities sens1plus2plus0 = SENSI_1
.combinedWith(ENTRY_USD2).combinedWith(ENTRY_ZERO0).combinedWith(ENTRY_ZERO3);
CrossGammaParameterSensitivities sens2plus0 = SENSI_2.combinedWith(sensZeroA);
assertEquals(SENSI_1.equalWithTolerance(sensZeroA, TOLERENCE_CMP), false);
assertEquals(SENSI_1.equalWithTolerance(SENSI_1, TOLERENCE_CMP), true);
assertEquals(SENSI_1.equalWithTolerance(SENSI_2, TOLERENCE_CMP), false);
assertEquals(SENSI_1.equalWithTolerance(sensUsdTotal, TOLERENCE_CMP), false);
assertEquals(SENSI_1.equalWithTolerance(sensEur, TOLERENCE_CMP), false);
assertEquals(SENSI_1.equalWithTolerance(sens1plus2, TOLERENCE_CMP), false);
assertEquals(SENSI_1.equalWithTolerance(sens2plus0, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(sensZeroA, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(SENSI_1, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(SENSI_2, TOLERENCE_CMP), true);
assertEquals(SENSI_2.equalWithTolerance(sensUsdTotal, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(sensEur, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(sens1plus2, TOLERENCE_CMP), false);
assertEquals(SENSI_2.equalWithTolerance(sens2plus0, TOLERENCE_CMP), true);
assertEquals(sensZeroA.equalWithTolerance(sensZeroA, TOLERENCE_CMP), true);
assertEquals(sensZeroA.equalWithTolerance(SENSI_1, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(SENSI_2, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(sensUsdTotal, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(sensEur, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(sens1plus2, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(sens2plus0, TOLERENCE_CMP), false);
assertEquals(sensZeroA.equalWithTolerance(sensZeroB, TOLERENCE_CMP), true);
assertEquals(sensZeroB.equalWithTolerance(sensZeroB, TOLERENCE_CMP), true);
assertEquals(sensZeroB.equalWithTolerance(SENSI_1, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(SENSI_2, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(sensUsdTotal, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(sensEur, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(sens1plus2, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(sens2plus0, TOLERENCE_CMP), false);
assertEquals(sensZeroB.equalWithTolerance(sensZeroA, TOLERENCE_CMP), true);
assertEquals(sens1plus2.equalWithTolerance(sens1plus2, TOLERENCE_CMP), true);
assertEquals(sens1plus2.equalWithTolerance(sens1plus2plus0a, TOLERENCE_CMP), true);
assertEquals(sens1plus2.equalWithTolerance(sens1plus2plus0b, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0a.equalWithTolerance(sens1plus2, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0a.equalWithTolerance(sens1plus2plus0, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0a.equalWithTolerance(sens1plus2plus0a, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0a.equalWithTolerance(sens1plus2plus0b, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0b.equalWithTolerance(sens1plus2, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0b.equalWithTolerance(sens1plus2plus0, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0b.equalWithTolerance(sens1plus2plus0a, TOLERENCE_CMP), true);
assertEquals(sens1plus2plus0b.equalWithTolerance(sens1plus2plus0b, TOLERENCE_CMP), true);
assertEquals(sens2plus0.equalWithTolerance(sens2plus0, TOLERENCE_CMP), true);
assertEquals(sensZeroA.equalWithTolerance(CrossGammaParameterSensitivities.empty(), TOLERENCE_CMP), true);
assertEquals(CrossGammaParameterSensitivities.empty().equalWithTolerance(sensZeroA, TOLERENCE_CMP), true);
}
//-------------------------------------------------------------------------
public void coverage() {
coverImmutableBean(CrossGammaParameterSensitivities.empty());
coverImmutableBean(SENSI_1);
coverBeanEquals(SENSI_1, SENSI_2);
}
}