CurrencyMatrixSpotSourcingFunction extends AbstractCurrencyMatrixSourcingFunction { private boolean getRequirements(final CurrencyMatrix matrix, final Set<ValueRequirement> requirements, final Set<Pair<Currency, Currency>> visited, final Pair<Currency, Currency> currencies) { if (!visited.add(currencies)) { throw new IllegalStateException(); } final CurrencyMatrixValue value = matrix.getConversion(currencies.getFirst(), currencies.getSecond()); if (value != null) { return value.accept(new CurrencyMatrixValueVisitor<Boolean>() { @Override public Boolean visitCross(final CurrencyMatrixCross cross) { return getRequirements(matrix, requirements, visited, Pairs.of(currencies.getFirst(), cross.getCrossCurrency())) && getRequirements(matrix, requirements, visited, Pairs.of(cross.getCrossCurrency(), currencies.getSecond())); } @Override public Boolean visitFixed(final CurrencyMatrixFixed fixedValue) { return Boolean.TRUE; } @Override public Boolean visitValueRequirement(final CurrencyMatrixValueRequirement valueRequirement) { requirements.add(tagInput(valueRequirement.getValueRequirement(), currencies.getFirst(), currencies.getSecond())); return Boolean.TRUE; } }); } else { return false; } } CurrencyMatrixSpotSourcingFunction(); static ValueRequirement getConversionRequirement(final Currency source, final Currency target); static Set<ValueRequirement> getConversionRequirements(final Currency source, final Currency target); static ValueRequirement getConversionRequirement(final String source, final String target);  }
@Test public void testGetRequirementsAndExecute() { final ValueProperties properties = ValueProperties.with(ValuePropertyNames.FUNCTION, "liveDataSourcing").get(); final ComputationTargetSpecificationResolver resolver = new DefaultComputationTargetResolver().getSpecificationResolver(); 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); 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); 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); 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); }