@Override
public CompiledFunctionDefinition compile(final FunctionCompilationContext context, final Instant atInstant) {
final ZonedDateTime atZDT = ZonedDateTime.ofInstant(atInstant, ZoneOffset.UTC);
final ConfigSource configSource = OpenGammaCompilationContext.getConfigSource(context);
final ConfigDBFXForwardCurveDefinitionSource curveDefinitionSource = new ConfigDBFXForwardCurveDefinitionSource(configSource);
final ConfigDBFXForwardCurveSpecificationSource curveSpecificationSource = new ConfigDBFXForwardCurveSpecificationSource(configSource);
return new AbstractInvokingCompiledFunction(atZDT.with(LocalTime.MIDNIGHT), atZDT.plusDays(1).with(LocalTime.MIDNIGHT).minusNanos(1000000)) {
@Override
public ComputationTargetType getTargetType() {
return ComputationTargetType.UNORDERED_CURRENCY_PAIR;
}
@Override
public Set<ValueSpecification> getResults(final FunctionCompilationContext myContext, final ComputationTarget target) {
@SuppressWarnings("synthetic-access")
final ValueProperties properties = createValueProperties().withAny(ValuePropertyNames.CURVE).get();
final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.FX_FORWARD_CURVE_MARKET_DATA, target.toSpecification(), properties);
return Collections.singleton(spec);
}
@SuppressWarnings("synthetic-access")
@Override
public Set<ValueRequirement> getRequirements(final FunctionCompilationContext myContext, final ComputationTarget target, final ValueRequirement desiredValue) {
final ValueProperties constraints = desiredValue.getConstraints();
final Set<String> curveNames = constraints.getValues(ValuePropertyNames.CURVE);
if (curveNames == null || curveNames.size() != 1) {
s_logger.error("Asked for FX forward curve market data, but did not supply a single FX forward curve name. The property Curve must be set.");
return null;
}
final UnorderedCurrencyPair currencyPair = UnorderedCurrencyPair.of(target.getUniqueId());
final String curveName = curveNames.iterator().next();
final FXForwardCurveDefinition definition = curveDefinitionSource.getDefinition(curveName, currencyPair.toString());
if (definition == null) {
s_logger.error("Couldn't find FX forward curve definition called " + curveName + " with target " + target);
return null;
}
final FXForwardCurveSpecification specification = curveSpecificationSource.getSpecification(curveName, currencyPair.toString());
if (specification == null) {
s_logger.error("Couldn't find FX forward curve specification called " + curveName + " with target " + target);
return null;
}
final QuoteType quoteType = specification.getQuoteType();
if (quoteType != FXForwardCurveSpecification.QuoteType.Outright && quoteType != FXForwardCurveSpecification.QuoteType.Points) {
s_logger.error("Cannot handle quote type " + quoteType);
return null;
}
final Set<ValueRequirement> requirements = new HashSet<>();
final FXForwardCurveInstrumentProvider provider = specification.getCurveInstrumentProvider();
for (final Tenor tenor : definition.getTenors()) {
final ExternalId identifier = provider.getInstrument(atZDT.toLocalDate(), tenor);
requirements.add(new ValueRequirement(provider.getDataFieldName(), ComputationTargetType.PRIMITIVE, identifier));
}
requirements.add(new ValueRequirement(provider.getDataFieldName(), ComputationTargetType.PRIMITIVE, provider.getSpotInstrument()));
return requirements;
}
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target,
final Set<ValueRequirement> desiredValues) {
final Clock snapshotClock = executionContext.getValuationClock();
final ZonedDateTime now = ZonedDateTime.now(snapshotClock);
final ValueRequirement desiredValue = desiredValues.iterator().next();
final String curveName = desiredValue.getConstraint(ValuePropertyNames.CURVE);
final UnorderedCurrencyPair currencyPair = UnorderedCurrencyPair.of(target.getUniqueId());
final FXForwardCurveDefinition definition = curveDefinitionSource.getDefinition(curveName, currencyPair.toString());
if (definition == null) {
throw new OpenGammaRuntimeException("Couldn't find FX forward curve definition called " + curveName + " for target " + target);
}
final FXForwardCurveSpecification specification = curveSpecificationSource.getSpecification(curveName, currencyPair.toString());
if (specification == null) {
throw new OpenGammaRuntimeException("Couldn't find FX forward curve specification called " + curveName + " for target " + target);
}
final FXForwardCurveInstrumentProvider provider = specification.getCurveInstrumentProvider();
final ValueRequirement spotRequirement = new ValueRequirement(provider.getDataFieldName(), ComputationTargetType.PRIMITIVE, provider.getSpotInstrument());