/** * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.data.scenario; 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.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.offset; import static org.testng.Assert.assertThrows; import org.testng.annotations.Test; import com.opengamma.strata.basics.currency.Currency; import com.opengamma.strata.basics.currency.CurrencyPair; import com.opengamma.strata.basics.currency.FxRate; import com.opengamma.strata.collect.array.DoubleArray; @Test public class FxRateScenarioArrayTest { private static final double TOLERANCE = 1e-10; public void getValues() { FxRateScenarioArray rates = FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1.07, 1.08, 1.09)); assertThat(rates.getPair()).isEqualTo(CurrencyPair.of(Currency.EUR, Currency.USD)); assertThat(rates.getScenarioCount()).isEqualTo(3); assertThat(rates.get(0)).isEqualTo(FxRate.of(Currency.EUR, Currency.USD, 1.07)); assertThat(rates.get(1)).isEqualTo(FxRate.of(Currency.EUR, Currency.USD, 1.08)); assertThat(rates.get(2)).isEqualTo(FxRate.of(Currency.EUR, Currency.USD, 1.09)); assertThrows(ArrayIndexOutOfBoundsException.class, () -> rates.get(3)); } public void fxRate() { FxRateScenarioArray rates = FxRateScenarioArray.of(CurrencyPair.of(Currency.EUR, Currency.USD), DoubleArray.of(1.07, 1.08, 1.09)); assertThat(rates.fxRate(Currency.EUR, Currency.USD, 0)).isEqualTo(1.07); assertThat(rates.fxRate(Currency.EUR, Currency.USD, 1)).isEqualTo(1.08); assertThat(rates.fxRate(Currency.EUR, Currency.USD, 2)).isEqualTo(1.09); assertThat(rates.fxRate(Currency.USD, Currency.EUR, 0)).isEqualTo(1 / 1.07); assertThat(rates.fxRate(Currency.USD, Currency.EUR, 1)).isEqualTo(1 / 1.08); assertThat(rates.fxRate(Currency.USD, Currency.EUR, 2)).isEqualTo(1 / 1.09); } public void identicalCurrenciesHaveRateOfOne() { assertThrowsIllegalArg( () -> FxRateScenarioArray.of(Currency.EUR, Currency.EUR, DoubleArray.of(1.07, 1.08, 1.09)), "Conversion rate between identical currencies must be one"); } public void unknownCurrencyPair() { FxRateScenarioArray rates = FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1.07, 1.08, 1.09)); assertThrowsIllegalArg(() -> rates.fxRate(Currency.AED, Currency.ARS, 0)); } public void convert() { FxRateScenarioArray eurGbp = FxRateScenarioArray.of(Currency.EUR, Currency.GBP, DoubleArray.of(0.76, 0.75)); DoubleArray input = DoubleArray.of(1.11, 1.12); DoubleArray expected = DoubleArray.of(1.11 * 0.76, 1.12 * 0.75); DoubleArray converted = eurGbp.convert(input, Currency.EUR, Currency.GBP); for (int i = 0; i < converted.size(); i++) { assertThat(converted.get(i)).isEqualTo(expected.get(i), offset(TOLERANCE)); } } public void convert_inverse() { FxRateScenarioArray eurGbp = FxRateScenarioArray.of(Currency.EUR, Currency.GBP, DoubleArray.of(0.76, 0.75)); DoubleArray input = DoubleArray.of(1.11, 1.12); DoubleArray expected = DoubleArray.of(1.11 * 1 / 0.76, 1.12 * 1 / 0.75); DoubleArray converted = eurGbp.convert(input, Currency.GBP, Currency.EUR); for (int i = 0; i < converted.size(); i++) { assertThat(converted.get(i)).isEqualTo(expected.get(i), offset(TOLERANCE)); } } public void convert_unknown() { FxRateScenarioArray eurGbp = FxRateScenarioArray.of(Currency.EUR, Currency.GBP, DoubleArray.of(0.76, 0.75)); assertThrowsIllegalArg(() -> eurGbp.convert(DoubleArray.of(1.07, 1.08), Currency.EUR, Currency.USD)); } public void crossRates() { FxRateScenarioArray eurGbp = FxRateScenarioArray.of(Currency.EUR, Currency.GBP, DoubleArray.of(0.76, 0.75)); FxRateScenarioArray eurUsd = FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1.11, 1.12)); FxRateScenarioArray gbpEur = FxRateScenarioArray.of(Currency.GBP, Currency.EUR, DoubleArray.of(1 / 0.76, 1 / 0.75)); FxRateScenarioArray usdEur = FxRateScenarioArray.of(Currency.USD, Currency.EUR, DoubleArray.of(1 / 1.11, 1 / 1.12)); FxRateScenarioArray expectedGbpUsd = FxRateScenarioArray.of(Currency.GBP, Currency.USD, DoubleArray.of(1.460526315789474, 1.4933333333333334)); assertArraysEqual(eurGbp.crossRates(eurUsd), expectedGbpUsd); assertArraysEqual(eurGbp.crossRates(usdEur), expectedGbpUsd); assertArraysEqual(gbpEur.crossRates(eurUsd), expectedGbpUsd); assertArraysEqual(gbpEur.crossRates(usdEur), expectedGbpUsd); assertArraysEqual(eurUsd.crossRates(eurGbp), expectedGbpUsd); assertArraysEqual(usdEur.crossRates(eurGbp), expectedGbpUsd); assertArraysEqual(eurUsd.crossRates(gbpEur), expectedGbpUsd); assertArraysEqual(usdEur.crossRates(gbpEur), expectedGbpUsd); } public void crossRatesInvalidInputs() { // Argument has both currencies the same assertThrowsIllegalArg(() -> FxRateScenarioArray.of(Currency.GBP, Currency.USD, DoubleArray.of(1)) .crossRates(FxRateScenarioArray.of(Currency.EUR, Currency.EUR, DoubleArray.of(1)))); // Receiver has both currencies the same assertThrowsIllegalArg(() -> FxRateScenarioArray.of(Currency.GBP, Currency.GBP, DoubleArray.of(1)) .crossRates(FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1)))); // No currency in common assertThrowsIllegalArg(() -> FxRateScenarioArray.of(Currency.GBP, Currency.CHF, DoubleArray.of(1)) .crossRates(FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1)))); // Both pairs the same assertThrowsIllegalArg(() -> FxRateScenarioArray.of(Currency.GBP, Currency.CHF, DoubleArray.of(1)) .crossRates(FxRateScenarioArray.of(Currency.GBP, Currency.CHF, DoubleArray.of(1)))); // Different length arrays assertThrowsIllegalArg(() -> FxRateScenarioArray.of(Currency.GBP, Currency.CHF, DoubleArray.of(1)) .crossRates(FxRateScenarioArray.of(Currency.EUR, Currency.CHF, DoubleArray.of(1, 2)))); } //------------------------------------------------------------------------- public void coverage() { FxRateScenarioArray rates1 = FxRateScenarioArray.of(Currency.EUR, Currency.USD, DoubleArray.of(1.07, 1.08, 1.09)); FxRateScenarioArray rates2 = FxRateScenarioArray.of(Currency.GBP, Currency.USD, DoubleArray.of(1.46, 1.47, 1.48)); coverImmutableBean(rates1); coverBeanEquals(rates1, rates2); } //------------------------------------------------------------------------- private static void assertArraysEqual(FxRateScenarioArray a1, FxRateScenarioArray a2) { assertThat(a1.getScenarioCount()).isEqualTo(a2.getScenarioCount()); assertThat(a1.getPair()).isEqualTo(a2.getPair()); for (int i = 0; i < a1.getScenarioCount(); i++) { assertThat(a1.fxRate(Currency.GBP, Currency.USD, i)).isEqualTo(a2.fxRate(Currency.GBP, Currency.USD, i), offset(TOLERANCE)); } } }