/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.currency; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import java.util.Collections; import java.util.Set; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.opengamma.core.value.MarketDataRequirementNames; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.DefaultComputationTargetResolver; import com.opengamma.engine.function.EmptyFunctionInputs; import com.opengamma.engine.function.FunctionCompilationContext; import com.opengamma.engine.function.FunctionExecutionContext; import com.opengamma.engine.function.FunctionInputsImpl; import com.opengamma.engine.target.ComputationTargetRequirement; import com.opengamma.engine.target.ComputationTargetSpecificationResolver; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.value.ComputedValue; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValuePropertyNames; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueRequirementNames; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.id.ExternalId; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.util.money.Currency; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.UNIT) public class CurrencyMatrixSpotSourcingFunctionTest { private final Currency _currencyUSD = Currency.USD; private final Currency _currencyGBP = Currency.GBP; private final Currency _currencyEUR = Currency.EUR; private final double _rateUSD_GBP = 1.6; private final double _rateEUR_GBP = 1.1; private FunctionExecutionContext _functionExecutionContext; private FunctionCompilationContext _functionCompilationContext; private CurrencyMatrixSpotSourcingFunction _function; private ComputationTarget _matrixTarget; @BeforeMethod public void setupContexts() { _functionExecutionContext = new FunctionExecutionContext(); _functionCompilationContext = new FunctionCompilationContext(); SimpleCurrencyMatrix matrix = new SimpleCurrencyMatrix(); matrix.setUniqueId(UniqueId.of("Matrix", "Test")); matrix.setLiveData(_currencyUSD, _currencyGBP, new ValueRequirement(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetType.PRIMITIVE, ExternalId.of("LiveData", "USD_GBP"))); matrix.setFixedConversion(_currencyEUR, _currencyGBP, _rateEUR_GBP); matrix.setCrossConversion(_currencyEUR, _currencyUSD, _currencyGBP); _matrixTarget = new ComputationTarget(CurrencyMatrixResolver.TYPE, matrix); _function = new CurrencyMatrixSpotSourcingFunction(); _function.setUniqueId("currencyMatrixSourcing"); _function.init(_functionCompilationContext); } @Test public void testGetResults() { final Set<ValueSpecification> results = _function.getResults(_functionCompilationContext, _matrixTarget); assertEquals(6, results.size()); } @Test public void testGetRequirementsAndExecute() { final ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "liveDataSourcing").get(); final ComputationTargetSpecificationResolver resolver = new DefaultComputationTargetResolver().getSpecificationResolver(); // Require value the "right" way up // [PLAT-2290] Execute should be taking a ValueSpecification, getRequirements should be taking a ValueRequirement ValueRequirement outRequirement = new ValueRequirement(ValueRequirementNames.SPOT_RATE, _matrixTarget.toSpecification(), ValueProperties .with(AbstractCurrencyMatrixSourcingFunction.SOURCE_CURRENCY_PROPERTY, "USD").with(AbstractCurrencyMatrixSourcingFunction.TARGET_CURRENCY_PROPERTY, "GBP") .with(ValuePropertyNames.FUNCTION, "CMSF").get()); Set<ValueRequirement> inRequirements = _function.getRequirements(_functionCompilationContext, _matrixTarget, outRequirement); assertEquals(1, inRequirements.size()); final ComputationTargetRequirement inRequirementTarget = new ComputationTargetRequirement(ComputationTargetType.PRIMITIVE, ExternalId.of("LiveData", "USD_GBP")); for (ValueRequirement requirement : inRequirements) { assertEquals(requirement.getValueName(), MarketDataRequirementNames.MARKET_VALUE); assertEquals(requirement.getTargetReference(), inRequirementTarget); assertTrue(requirement.getConstraints().isSatisfiedBy(ValueProperties.none())); } Set<ComputedValue> outputs = _function.execute(_functionExecutionContext, new FunctionInputsImpl(resolver.atVersionCorrection(VersionCorrection.LATEST), new ComputedValue(new ValueSpecification( MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.of(UniqueId.of("ExternalId-LiveData", "USD_GBP")), properties), _rateUSD_GBP)), _matrixTarget, Collections.singleton(outRequirement)); assertEquals(1, outputs.size()); ComputedValue output = outputs.iterator().next(); assertTrue(output.getValue() instanceof Double); assertEquals(_rateUSD_GBP, (Double) output.getValue(), Double.MIN_NORMAL); // Require value the "wrong" way up // [PLAT-2290] Execute should be taking a ValueSpecification, getRequirements should be taking a ValueRequirement outRequirement = new ValueRequirement(ValueRequirementNames.SPOT_RATE, _matrixTarget.toSpecification(), ValueProperties .with(AbstractCurrencyMatrixSourcingFunction.SOURCE_CURRENCY_PROPERTY, "GBP").with(AbstractCurrencyMatrixSourcingFunction.TARGET_CURRENCY_PROPERTY, "USD") .with(ValuePropertyNames.FUNCTION, "CMSF").get()); inRequirements = _function.getRequirements(_functionCompilationContext, _matrixTarget, outRequirement); assertEquals(1, inRequirements.size()); for (ValueRequirement requirement : inRequirements) { assertEquals(requirement.getValueName(), MarketDataRequirementNames.MARKET_VALUE); assertEquals(requirement.getTargetReference(), inRequirementTarget); assertTrue(requirement.getConstraints().isSatisfiedBy(ValueProperties.none())); } outputs = _function.execute(_functionExecutionContext, new FunctionInputsImpl(resolver.atVersionCorrection(VersionCorrection.LATEST), new ComputedValue(new ValueSpecification(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.of(UniqueId.of("ExternalId-LiveData", "USD_GBP")), properties), _rateUSD_GBP)), _matrixTarget, Collections.singleton(outRequirement)); assertEquals(1, outputs.size()); output = outputs.iterator().next(); assertTrue(output.getValue() instanceof Double); assertEquals(1.0 / _rateUSD_GBP, (Double) output.getValue(), Double.MIN_NORMAL); // Require no additional live data // [PLAT-2290] Execute should be taking a ValueSpecification, getRequirements should be taking a ValueRequirement outRequirement = new ValueRequirement(ValueRequirementNames.SPOT_RATE, _matrixTarget.toSpecification(), ValueProperties .with(AbstractCurrencyMatrixSourcingFunction.SOURCE_CURRENCY_PROPERTY, "GBP").with(AbstractCurrencyMatrixSourcingFunction.TARGET_CURRENCY_PROPERTY, "EUR") .with(ValuePropertyNames.FUNCTION, "CMSF").get()); inRequirements = _function.getRequirements(_functionCompilationContext, _matrixTarget, outRequirement); assertEquals(0, inRequirements.size()); outputs = _function.execute(_functionExecutionContext, new EmptyFunctionInputs(), _matrixTarget, Collections.singleton(outRequirement)); assertEquals(1, outputs.size()); output = outputs.iterator().next(); assertTrue(output.getValue() instanceof Double); assertEquals(1.0 / _rateEUR_GBP, (Double) output.getValue(), Double.MIN_NORMAL); // Require intermediate value // [PLAT-2290] Execute should be taking a ValueSpecification, getRequirements should be taking a ValueRequirement outRequirement = new ValueRequirement(ValueRequirementNames.SPOT_RATE, _matrixTarget.toSpecification(), ValueProperties .with(AbstractCurrencyMatrixSourcingFunction.SOURCE_CURRENCY_PROPERTY, "EUR").with(AbstractCurrencyMatrixSourcingFunction.TARGET_CURRENCY_PROPERTY, "USD") .with(ValuePropertyNames.FUNCTION, "CMSF").get()); inRequirements = _function.getRequirements(_functionCompilationContext, _matrixTarget, outRequirement); assertEquals(1, inRequirements.size()); for (ValueRequirement requirement : inRequirements) { assertEquals(requirement.getValueName(), MarketDataRequirementNames.MARKET_VALUE); assertEquals(requirement.getTargetReference(), inRequirementTarget); assertTrue(requirement.getConstraints().isSatisfiedBy(ValueProperties.none())); } outputs = _function.execute(_functionExecutionContext, new FunctionInputsImpl(resolver.atVersionCorrection(VersionCorrection.LATEST), new ComputedValue(new ValueSpecification(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.of(UniqueId.of("ExternalId-LiveData", "USD_GBP")), properties), _rateUSD_GBP)), _matrixTarget, Collections.singleton(outRequirement)); assertEquals(1, outputs.size()); output = outputs.iterator().next(); assertTrue(output.getValue() instanceof Double); assertEquals(_rateEUR_GBP / _rateUSD_GBP, (Double) output.getValue(), Double.MIN_NORMAL); } }