package com.opengamma.sesame.pnl;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.threeten.bp.LocalDate;
import org.threeten.bp.ZonedDateTime;
import com.google.common.collect.Sets;
import com.opengamma.analytics.financial.forex.method.FXMatrix;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.integration.regression.EqualityChecker;
import com.opengamma.sesame.FXMatrixFn;
import com.opengamma.sesame.SimpleEnvironment;
import com.opengamma.sesame.marketdata.HistoricalMarketDataFn;
import com.opengamma.sesame.marketdata.MarketDataBundle;
import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries;
import com.opengamma.util.money.Currency;
import com.opengamma.util.result.Result;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.LocalDateRange;
/**
* Tests calculation of conversion from historical rates to today's rates.
*/
@Test(groups= TestGroup.UNIT)
public class DefaultHistoricalPnLFXConverterFnTest {
private static final double DELTA = 0.000001;
private static double[] FX_RATES = {1.499, 1.5, 1.501, 1.502, 1.502, 1.503};
private static double[] PNL = {100, 101, 99, 5, 55};
private static LocalDate PNL_START = LocalDate.of(2014, 1, 8);
private static double[] EXPECTED_PNL_WITH_START_FX = {99.7338656, 100.7984032, 98.86826347, 4.99667332, 54.96340652};
private static double[] EXPECTED_PNL_WITH_END_FX = {99.8003992, 100.8656021, 98.93413174, 4.99667332, 55};
private FXMatrixFn _fxMatrixFn;
private HistoricalMarketDataFn _mdFn;
private final CurrencyPair _ccyPair = CurrencyPair.of(Currency.GBP, Currency.USD);
private final SimpleEnvironment env = new SimpleEnvironment(ZonedDateTime.now(), mock(MarketDataBundle.class));
private final FXMatrix fxMatrix = new FXMatrix(_ccyPair.getBase());
private LocalDateRange _range;
private LocalDateRange _adjustedRange;
private LocalDateDoubleTimeSeries _inputPnL;
private LocalDateDoubleTimeSeries _reciprocalFxRates;
@BeforeClass
public void init() {
LocalDate[] pnlDates = new LocalDate[PNL.length];
LocalDate[] fxDates = new LocalDate[FX_RATES.length];
fxDates[0] = PNL_START.minusDays(1);
for (int i = 0; i < pnlDates.length; i++) {
pnlDates[i] = PNL_START.plusDays(i);
fxDates[i + 1] = PNL_START.plusDays(i);
}
_fxMatrixFn = mock(FXMatrixFn.class);
_mdFn = mock(HistoricalMarketDataFn.class);
fxMatrix.addCurrency(_ccyPair.getCounter(), _ccyPair.getBase(), 1.0 / FX_RATES[FX_RATES.length-1]);
_inputPnL = ImmutableLocalDateDoubleTimeSeries.of(pnlDates, PNL);
_reciprocalFxRates = ImmutableLocalDateDoubleTimeSeries.of(fxDates, FX_RATES).reciprocal();
_range = LocalDateRange.of(PNL_START, PNL_START.plusDays(_inputPnL.size()-1), true);
_adjustedRange = LocalDateRange.of(PNL_START.minusWeeks(1), _range.getEndDateInclusive(), true);
when(_fxMatrixFn.getFXMatrix(env, Sets.newHashSet(_ccyPair.getBase(), _ccyPair.getCounter()))).thenReturn(Result.success(fxMatrix));
}
@Test
public void convertToSpotEnd() {
HistoricalPnLFXConverterFn fn = new DefaultHistoricalPnLFXConverterFn(_fxMatrixFn, _mdFn, PnLPeriodBound.END);
when(_mdFn.getFxRates(env, _ccyPair, _range)).thenReturn(Result.success(_reciprocalFxRates));
Result<LocalDateDoubleTimeSeries> result = fn.convertToSpotRate(env, _ccyPair, _inputPnL);
assertTrue(result.isSuccess());
assertEquals("Expected size of series to remain the same", _inputPnL.size(), result.getValue().size());
assertTrue("Converted PnL did not match expected results.", checkResult(result, EXPECTED_PNL_WITH_END_FX));
}
@Test
public void convertToSpotStart() {
HistoricalPnLFXConverterFn fn = new DefaultHistoricalPnLFXConverterFn(_fxMatrixFn, _mdFn, PnLPeriodBound.START);
when(_mdFn.getFxRates(env, _ccyPair, _adjustedRange)).thenReturn(Result.success(_reciprocalFxRates));
Result<LocalDateDoubleTimeSeries> result = fn.convertToSpotRate(env, _ccyPair, _inputPnL);
assertEquals("Expected size of series to remain the same", _inputPnL.size(), result.getValue().size());
assertTrue("Converted PnL did not match expected results.", checkResult(result, EXPECTED_PNL_WITH_START_FX));
}
private boolean checkResult(Result<LocalDateDoubleTimeSeries> result, double[] expected) {
return EqualityChecker.equals(result.getValue().valuesArrayFast(), expected, DELTA);
}
}