/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.forex.method;
import java.util.Iterator;
import java.util.Set;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* Utility class to manipulate FXMatrix.
*/
public class FXMatrixUtils {
/**
* Merges two FXMatrix. The two matrix should have at least one currency in common. The matrix return is a new matrix.
* The merged matrix will contain the data in the initial matrix1 and all the currencies of the two matrices.
* The missing currencies from matrix2 are added one by one and the exchange rate data created is coherent with some data in the initial matrices.
* If the data in the initial matrices are not coherent between them, there is no guarantee which data will be used and the final result may be incoherent.
* @param matrix1 The first matrix.
* @param matrix2 The second matrix.
* @return The merged matrix.
*/
public static FXMatrix merge(final FXMatrix matrix1, final FXMatrix matrix2) {
ArgumentChecker.notNull(matrix1, "first FX matrix");
ArgumentChecker.notNull(matrix2, "second FX matrix");
// Implementation note: Check is one matrix is empty
if (matrix1.getNumberOfCurrencies() == 0) {
return new FXMatrix(matrix2);
}
if (matrix2.getNumberOfCurrencies() == 0) {
return new FXMatrix(matrix1);
}
// Implementation note: Finding a common currency
final Set<Currency> set1 = matrix1.getCurrencies().keySet();
final Set<Currency> set2 = matrix2.getCurrencies().keySet();
final Set<Currency> intersection = Sets.intersection(set1, set2);
if (intersection.isEmpty()) {
throw new OpenGammaRuntimeException("Currency sets of the two matrices don't have an intersection");
}
final Currency ccyCommon = intersection.iterator().next(); // Implementation note: take any currency in the intersection.
// Implementation note: New matrix with the same element as matrix1
final FXMatrix result = new FXMatrix(matrix1);
// Implementation note: adding the missing currencies from matrix2 one by one.
for (Currency loopccy : set2) {
if (!set1.contains(loopccy)) {
result.addCurrency(loopccy, ccyCommon, matrix2.getFxRate(loopccy, ccyCommon));
}
}
return result;
}
/**
* Compares two FX Matrix within a given tolerance. The comparison is done only on one secondary diagonal.
* Other rates will also be correct if the input matrices are coherent
* @param matrix1 The first matrix.
* @param matrix2 The second matrix.
* @param tolerance The tolerance.
* @return The comparison result. Will be true if for each element in the diagonal tested, the two matrix have a difference in exchange rate lower thatn the tolerance.
*/
public static boolean compare(final FXMatrix matrix1, final FXMatrix matrix2, final double tolerance) {
// Implementation note: Compare currency set
final Set<Currency> set1 = matrix1.getCurrencies().keySet();
final Set<Currency> set2 = matrix2.getCurrencies().keySet();
if (!set1.equals(set2)) {
return false;
}
// Implementation note: Compare one diagonal (other will be correct also if matrices are coherent).
final Iterator<Currency> iterator = set1.iterator();
if (set1.size() > 0) {
final Currency initialCurrency = iterator.next();
while (iterator.hasNext()) {
final Currency otherCurrency = iterator.next();
final boolean correct = Math.abs(matrix1.getFxRate(initialCurrency, otherCurrency) - matrix2.getFxRate(initialCurrency, otherCurrency)) < tolerance;
if (!correct) {
return false;
}
}
}
return true;
}
}