private void configureCompilationContext(final FunctionCompilationContext context) { OpenGammaCompilationContext.setConfigSource(context, _configSource); OpenGammaCompilationContext.setRegionSource(context, _regionSource); OpenGammaCompilationContext.setConventionBundleSource(context, _conventionBundleSource); OpenGammaCompilationContext.setInterpolatedYieldCurveDefinitionSource( context, _interpolatedYieldCurveDefinitionSource); OpenGammaCompilationContext.setInterpolatedYieldCurveSpecificationBuilder( context, _interpolatedYieldCurveSpecificationBuilder); OpenGammaCompilationContext.setCurrencyMatrixSource(context, _currencyMatrixSource); context.setSecuritySource(getSecuritySource()); context.setPortfolioStructure(new PortfolioStructure(getPositionSource())); }
@Override public Set<ValueRequirement> getRequirements( final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) { final Set<String> curves = desiredValue.getConstraints().getValues(ValuePropertyNames.CURVE); final Set<String> curveCalcConfigs = desiredValue.getConstraints().getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG); if ((curves == null) || (curves.size() != 1)) { s_logger.warn("no curve specified"); // Can't support an unbound request; an injection function must be used (or declare all as // optional and use [PLAT-1771]) return null; } if ((curveCalcConfigs == null) || (curveCalcConfigs.size() != 1)) { s_logger.warn("no curve config specified"); return null; } final String curve = curves.iterator().next(); final String curveCalcConfig = curveCalcConfigs.iterator().next(); final Set<ValueRequirement> requirements = Sets.newHashSet(); requirements.add(getCurveRequirement(target, curve, curveCalcConfig)); requirements.add(getCurveSpecRequirement(target, curve)); requirements.addAll( getSensitivityRequirements( context.getSecuritySource(), (RawSecurity) target.getSecurity())); return requirements; }
@Override public CompiledFunctionRepository compile( final FunctionRepository repository, final FunctionCompilationContext context, final ExecutorService executor, final InstantProvider atInstantProvider) { clearInvalidCache(context.getFunctionInitId()); final Instant atInstant = Instant.of(atInstantProvider); final Pair<FunctionRepository, Instant> key = Pair.of(repository, atInstant); // Try a previous compilation final InMemoryCompiledFunctionRepository previous = getPreviousCompilation(key); if (previous != null) { if (previous.getLatestInvocationTime() == null) { return previous; } else { if (!atInstant.isAfter(previous.getLatestInvocationTime())) { return previous; } } } // Try a future compilation final InMemoryCompiledFunctionRepository next = getNextCompilation(key); if (next != null) { if (next.getEarliestInvocationTime() == null) { return next; } else { if (!atInstant.isBefore(next.getEarliestInvocationTime())) { return next; } } } // Try the exact timestamp InMemoryCompiledFunctionRepository compiled = getCachedCompilation(key); if (compiled != null) { return compiled; } // Create a compilation, salvaging results from previous and next if possible compiled = compile(context, repository, atInstant, previous, next, executor); cacheCompilation(key, compiled); return compiled; }
@Override public Set<ValueRequirement> getRequirements( final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) { final LegacyVanillaCDSSecurity cds = (LegacyVanillaCDSSecurity) target.getSecurity(); final Currency ccy = cds.getNotional().getCurrency(); final CreditCurveIdentifier isdaIdentifier = getISDACurveIdentifier(cds); final CreditCurveIdentifier spreadIdentifier = getSpreadCurveIdentifier(cds); final String isdaOffset = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_CURVE_OFFSET); if (isdaOffset == null) { return null; } final String isdaCurveDate = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_CURVE_DATE); if (isdaCurveDate == null) { return null; } final String isdaCurveMethod = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_IMPLEMENTATION); if (isdaCurveMethod == null) { return null; } // isda curve final ValueProperties isdaProperties = ValueProperties.builder() .with(ValuePropertyNames.CURVE, isdaIdentifier.toString()) .with( ValuePropertyNames.CURVE_CALCULATION_METHOD, ISDAFunctionConstants.ISDA_METHOD_NAME) .with(ISDAFunctionConstants.ISDA_CURVE_OFFSET, isdaOffset) .with(ISDAFunctionConstants.ISDA_CURVE_DATE, isdaCurveDate) .with(ISDAFunctionConstants.ISDA_IMPLEMENTATION, isdaCurveMethod) .get(); final ValueRequirement isdaRequirment = new ValueRequirement( ValueRequirementNames.YIELD_CURVE, ComputationTargetType.CURRENCY, ccy.getUniqueId(), isdaProperties); final String quoteConvention = desiredValue.getConstraint(ISDAFunctionConstants.CDS_QUOTE_CONVENTION); if (quoteConvention == null) { return null; } final String bucketTenors = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_BUCKET_TENORS); if (bucketTenors == null) { return null; } // market spreads final ValueProperties spreadProperties = ValueProperties.builder() .with(ISDAFunctionConstants.CDS_QUOTE_CONVENTION, quoteConvention) .with( ValuePropertyNames.CURVE_CALCULATION_METHOD, ISDAFunctionConstants.ISDA_METHOD_NAME) .with(ISDAFunctionConstants.ISDA_CURVE_OFFSET, isdaOffset) .with(ISDAFunctionConstants.ISDA_CURVE_DATE, isdaCurveDate) .with(ISDAFunctionConstants.ISDA_IMPLEMENTATION, isdaCurveMethod) .with(ISDAFunctionConstants.ISDA_BUCKET_TENORS, bucketTenors) .get(); final ValueRequirement spreadRequirment = new ValueRequirement( ValueRequirementNames.BUCKETED_SPREADS, target.toSpecification(), spreadProperties); final ValueRequirement pillarRequirment = new ValueRequirement( ValueRequirementNames.PILLAR_SPREADS, target.toSpecification(), spreadProperties); final ValueRequirement creditCurveRequirement = new ValueRequirement( ValueRequirementNames.HAZARD_RATE_CURVE, target.toSpecification(), spreadProperties); // get individual spread for this cds (ignore business day adjustment on either) final Period period = Period.between( cds.getStartDate().toLocalDate().withDayOfMonth(20), cds.getMaturityDate().toLocalDate().withDayOfMonth(20)); final ValueRequirement cdsSpreadRequirement = new ValueRequirement( MarketDataRequirementNames.MARKET_VALUE, ComputationTargetType.PRIMITIVE, ExternalId.of("Tenor", period.toString())); final CdsRecoveryRateIdentifier recoveryRateIdentifier = cds.accept(new CreditSecurityToRecoveryRateVisitor(context.getSecuritySource())); final ValueRequirement recoveryRateRequirement = new ValueRequirement( "PX_LAST", ComputationTargetType.PRIMITIVE, recoveryRateIdentifier.getExternalId()); return Sets.newHashSet( isdaRequirment, spreadRequirment, cdsSpreadRequirement, creditCurveRequirement, pillarRequirment, recoveryRateRequirement); }
@Override public CompiledFunctionDefinition compile( final FunctionCompilationContext context, final Instant atInstant) { final MultiCurveCalculationConfig impliedConfiguration = _multiCurveCalculationConfig.get(_curveCalculationConfig); if (impliedConfiguration == null) { throw new OpenGammaRuntimeException( "Multi-curve calculation called " + _curveCalculationConfig + " was null"); } ComputationTarget target = context.getComputationTargetResolver().resolve(impliedConfiguration.getTarget()); if (!(target.getValue() instanceof Currency)) { throw new OpenGammaRuntimeException( "Target of curve calculation configuration was not a currency"); } final Currency impliedCurrency = (Currency) target.getValue(); if (!IMPLIED_DEPOSIT.equals(impliedConfiguration.getCalculationMethod())) { throw new OpenGammaRuntimeException( "Curve calculation method was not " + IMPLIED_DEPOSIT + " for configuration called " + _curveCalculationConfig); } final String[] impliedCurveNames = impliedConfiguration.getYieldCurveNames(); if (impliedCurveNames.length != 1) { throw new OpenGammaRuntimeException( "Can only handle configurations with a single implied curve"); } final LinkedHashMap<String, String[]> originalConfigurationName = impliedConfiguration.getExogenousConfigData(); if (originalConfigurationName == null || originalConfigurationName.size() != 1) { throw new OpenGammaRuntimeException("Need a configuration with one exogenous configuration"); } final Map.Entry<String, String[]> entry = Iterables.getOnlyElement(originalConfigurationName.entrySet()); final String[] originalCurveNames = entry.getValue(); if (originalCurveNames.length != 1) { s_logger.warn("Found more than one exogenous configuration name; using only the first"); } final MultiCurveCalculationConfig originalConfiguration = _multiCurveCalculationConfig.get(entry.getKey()); if (originalConfiguration == null) { throw new OpenGammaRuntimeException( "Multi-curve calculation called " + entry.getKey() + " was null"); } target = context.getComputationTargetResolver().resolve(originalConfiguration.getTarget()); if (!(target.getValue() instanceof Currency)) { throw new OpenGammaRuntimeException( "Target of curve calculation configuration was not a currency"); } final Currency originalCurrency = (Currency) target.getValue(); if (!originalCurrency.equals(impliedCurrency)) { throw new OpenGammaRuntimeException( "Currency targets for configurations " + _curveCalculationConfig + " and " + entry.getKey() + " did not match"); } final YieldCurveDefinition impliedDefinition = _yieldCurveDefinition.get(impliedCurveNames[0] + "_" + impliedCurrency.getCode()); if (impliedDefinition == null) { throw new OpenGammaRuntimeException( "Could not get implied definition called " + impliedCurveNames[0] + "_" + impliedCurrency.getCode()); } final Set<FixedIncomeStrip> strips = impliedDefinition.getStrips(); for (final FixedIncomeStrip strip : strips) { if (strip.getInstrumentType() != StripInstrumentType.CASH) { throw new OpenGammaRuntimeException( "Can only handle yield curve definitions with CASH strips"); } } final ZonedDateTime atZDT = ZonedDateTime.ofInstant(atInstant, ZoneOffset.UTC); return new MyCompiledFunction( atZDT.with(LocalTime.MIDNIGHT), atZDT.plusDays(1).with(LocalTime.MIDNIGHT).minusNanos(1000000), impliedConfiguration, impliedDefinition, originalConfiguration, originalCurveNames[0]); };