/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics.currency;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.coverImmutableBean;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Test {@link FxRate}.
*/
@Test
public class FxRateTest {
private static final Currency AUD = Currency.AUD;
private static final Currency CAD = Currency.CAD;
private static final Currency EUR = Currency.EUR;
private static final Currency GBP = Currency.GBP;
private static final Currency USD = Currency.USD;
//-------------------------------------------------------------------------
public void test_of_CurrencyCurrencyDouble() {
FxRate test = FxRate.of(GBP, USD, 1.5d);
assertEquals(test.getPair(), CurrencyPair.of(GBP, USD));
assertEquals(test.fxRate(GBP, USD), 1.5d, 0);
assertEquals(test.toString(), "GBP/USD 1.5");
}
public void test_of_CurrencyCurrencyDouble_reverseStandardOrder() {
FxRate test = FxRate.of(USD, GBP, 0.8d);
assertEquals(test.getPair(), CurrencyPair.of(USD, GBP));
assertEquals(test.fxRate(USD, GBP), 0.8d, 0);
assertEquals(test.toString(), "USD/GBP 0.8");
}
public void test_of_CurrencyCurrencyDouble_same() {
FxRate test = FxRate.of(USD, USD, 1d);
assertEquals(test.getPair(), CurrencyPair.of(USD, USD));
assertEquals(test.fxRate(USD, USD), 1d, 0);
assertEquals(test.toString(), "USD/USD 1");
}
public void test_of_CurrencyCurrencyDouble_invalid() {
assertThrowsIllegalArg(() -> FxRate.of(GBP, USD, -1.5d));
assertThrowsIllegalArg(() -> FxRate.of(GBP, GBP, 2d));
}
public void test_of_CurrencyCurrencyDouble_null() {
assertThrowsIllegalArg(() -> FxRate.of(null, USD, 1.5d));
assertThrowsIllegalArg(() -> FxRate.of(USD, null, 1.5d));
assertThrowsIllegalArg(() -> FxRate.of(null, null, 1.5d));
}
//-------------------------------------------------------------------------
public void test_of_CurrencyPairDouble() {
FxRate test = FxRate.of(CurrencyPair.of(GBP, USD), 1.5d);
assertEquals(test.getPair(), CurrencyPair.of(GBP, USD));
assertEquals(test.fxRate(GBP, USD), 1.5d, 0);
assertEquals(test.toString(), "GBP/USD 1.5");
}
public void test_of_CurrencyPairDouble_reverseStandardOrder() {
FxRate test = FxRate.of(CurrencyPair.of(USD, GBP), 0.8d);
assertEquals(test.getPair(), CurrencyPair.of(USD, GBP));
assertEquals(test.fxRate(USD, GBP), 0.8d, 0);
assertEquals(test.toString(), "USD/GBP 0.8");
}
public void test_of_CurrencyPairDouble_same() {
FxRate test = FxRate.of(CurrencyPair.of(USD, USD), 1d);
assertEquals(test.getPair(), CurrencyPair.of(USD, USD));
assertEquals(test.fxRate(USD, USD), 1d, 0);
assertEquals(test.toString(), "USD/USD 1");
}
public void test_of_CurrencyPairDouble_invalid() {
assertThrowsIllegalArg(() -> FxRate.of(CurrencyPair.of(GBP, USD), -1.5d));
assertThrowsIllegalArg(() -> FxRate.of(CurrencyPair.of(USD, USD), 2d));
}
public void test_of_CurrencyPairDouble_null() {
assertThrowsIllegalArg(() -> FxRate.of(null, 1.5d));
}
public void test_toConventional() {
assertEquals(FxRate.of(GBP, USD, 1.25), FxRate.of(USD, GBP, 0.8).toConventional());
assertEquals(FxRate.of(GBP, USD, 1.25), FxRate.of(GBP, USD, 1.25).toConventional());
}
//-------------------------------------------------------------------------
@DataProvider(name = "parseGood")
Object[][] data_parseGood() {
return new Object[][] {
{"USD/EUR 205.123", USD, EUR, 205.123d},
{"USD/EUR 3.00000000", USD, EUR, 3d},
{"USD/EUR 2", USD, EUR, 2d},
{"USD/EUR 0.1", USD, EUR, 0.1d},
{"EUR/USD 0.001", EUR, USD, 0.001d},
{"EUR/EUR 1", EUR, EUR, 1d},
{"cAd/GbP 1.25", CAD, GBP, 1.25d},
};
}
@Test(dataProvider = "parseGood")
public void test_parse_String_good(String input, Currency base, Currency counter, double rate) {
assertEquals(FxRate.parse(input), FxRate.of(base, counter, rate));
}
@DataProvider(name = "parseBad")
Object[][] data_parseBad() {
return new Object[][] {
{"AUD 1.25"},
{"AUD/GB 1.25"},
{"AUD GBP 1.25"},
{"AUD:GBP 1.25"},
{"123/456"},
{"EUR/GBP -1.25"},
{"EUR/GBP 0"},
{"EUR/EUR 1.25"},
{""},
{null},
};
}
@Test(dataProvider = "parseBad", expectedExceptions = IllegalArgumentException.class)
public void test_parse_String_bad(String input) {
FxRate.parse(input);
}
//-------------------------------------------------------------------------
public void test_inverse() {
FxRate test = FxRate.of(GBP, USD, 1.25d);
assertEquals(test.inverse(), FxRate.of(USD, GBP, 0.8d));
}
public void test_inverse_same() {
FxRate test = FxRate.of(GBP, GBP, 1d);
assertEquals(test.inverse(), FxRate.of(GBP, GBP, 1d));
}
//-------------------------------------------------------------------------
public void test_fxRate_forBase() {
FxRate test = FxRate.of(GBP, USD, 1.25d);
assertEquals(test.fxRate(GBP, USD), 1.25d);
assertEquals(test.fxRate(USD, GBP), 1d / 1.25d);
assertThrowsIllegalArg(() -> test.fxRate(GBP, AUD));
}
public void test_fxRate_forPair() {
FxRate test = FxRate.of(GBP, USD, 1.25d);
assertEquals(test.fxRate(GBP, USD), 1.25d);
assertEquals(test.fxRate(USD, GBP), 1d / 1.25d);
assertEquals(test.fxRate(GBP, GBP), 1d);
assertEquals(test.fxRate(USD, USD), 1d);
assertEquals(test.fxRate(AUD, AUD), 1d);
assertThrowsIllegalArg(() -> test.fxRate(AUD, GBP));
assertThrowsIllegalArg(() -> test.fxRate(GBP, AUD));
assertThrowsIllegalArg(() -> test.fxRate(AUD, USD));
assertThrowsIllegalArg(() -> test.fxRate(USD, AUD));
assertThrowsIllegalArg(() -> test.fxRate(EUR, AUD));
}
//-------------------------------------------------------------------------
public void test_convert() {
FxRate test = FxRate.of(GBP, USD, 1.25d);
assertEquals(test.convert(100, GBP, USD), 125d);
assertEquals(test.convert(100, USD, GBP), 100d / 1.25d);
assertThrowsIllegalArg(() -> test.convert(100, GBP, AUD));
}
//-------------------------------------------------------------------------
public void test_crossRate() {
FxRate gbpUsd = FxRate.of(GBP, USD, 5d / 4d);
FxRate usdGbp = FxRate.of(USD, GBP, 4d / 5d);
FxRate eurUsd = FxRate.of(EUR, USD, 8d / 7d);
FxRate usdEur = FxRate.of(USD, EUR, 7d / 8d);
FxRate eurGbp = FxRate.of(EUR, GBP, (8d / 7d) * (4d / 5d));
FxRate gbpGbp = FxRate.of(GBP, GBP, 1d);
FxRate usdUsd = FxRate.of(USD, USD, 1d);
assertEquals(eurUsd.crossRate(usdGbp), eurGbp);
assertEquals(eurUsd.crossRate(gbpUsd), eurGbp);
assertEquals(usdEur.crossRate(usdGbp), eurGbp);
assertEquals(usdEur.crossRate(gbpUsd), eurGbp);
assertEquals(gbpUsd.crossRate(usdEur), eurGbp);
assertEquals(gbpUsd.crossRate(eurUsd), eurGbp);
assertEquals(usdGbp.crossRate(usdEur), eurGbp);
assertEquals(usdGbp.crossRate(eurUsd), eurGbp);
assertThrowsIllegalArg(() -> gbpGbp.crossRate(gbpUsd)); // identity
assertThrowsIllegalArg(() -> usdUsd.crossRate(gbpUsd)); // identity
assertThrowsIllegalArg(() -> gbpUsd.crossRate(gbpUsd)); // same currencies
assertThrowsIllegalArg(() -> gbpUsd.crossRate(usdGbp)); // same currencies
assertThrowsIllegalArg(() -> gbpUsd.crossRate(FxRate.of(EUR, CAD, 12d / 5d))); // no common currency
}
//-------------------------------------------------------------------------
public void test_equals_hashCode() {
FxRate a1 = FxRate.of(AUD, GBP, 1.25d);
FxRate a2 = FxRate.of(AUD, GBP, 1.25d);
FxRate b = FxRate.of(USD, GBP, 1.25d);
FxRate c = FxRate.of(USD, GBP, 1.35d);
assertEquals(a1.equals(a1), true);
assertEquals(a1.equals(a2), true);
assertEquals(a1.equals(b), false);
assertEquals(a1.equals(c), false);
assertEquals(b.equals(a1), false);
assertEquals(b.equals(a2), false);
assertEquals(b.equals(b), true);
assertEquals(b.equals(c), false);
assertEquals(c.equals(a1), false);
assertEquals(c.equals(a2), false);
assertEquals(c.equals(b), false);
assertEquals(c.equals(c), true);
assertEquals(a1.hashCode(), a2.hashCode());
}
public void test_equals_bad() {
FxRate test = FxRate.of(AUD, GBP, 1.25d);
assertFalse(test.equals(""));
assertFalse(test.equals(null));
}
//-----------------------------------------------------------------------
public void test_serialization() {
assertSerialization(FxRate.of(GBP, USD, 1.25d));
assertSerialization(FxRate.of(GBP, GBP, 1d));
}
//-----------------------------------------------------------------------
public void coverage() {
coverImmutableBean(FxRate.of(GBP, USD, 1.25d));
}
}