private static final TimeSeriesDifferenceOperator DIFFERENCE = new TimeSeriesDifferenceOperator();
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target,
final Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
final Position position = target.getPosition();
final Clock snapshotClock = executionContext.getValuationClock();
final LocalDate now = ZonedDateTime.now(snapshotClock).toLocalDate();
final String currency = FinancialSecurityUtils.getCurrency(position.getSecurity()).getCode();
final ValueRequirement desiredValue = Iterables.getOnlyElement(desiredValues);
final ValueProperties constraints = desiredValue.getConstraints();
final String desiredCurrency;
final Set<String> desiredCurrencies = constraints.getValues(ValuePropertyNames.CURRENCY);
if (desiredCurrencies != null && !desiredCurrencies.isEmpty()) {
desiredCurrency = Iterables.getOnlyElement(desiredCurrencies);
} else {
desiredCurrency = currency;
}
final Period samplingPeriod = getSamplingPeriod(desiredValue.getConstraint(ValuePropertyNames.SAMPLING_PERIOD));
final LocalDate startDate = now.minus(samplingPeriod);
final Schedule scheduleCalculator = getScheduleCalculator(desiredValue.getConstraint(ValuePropertyNames.SCHEDULE_CALCULATOR));
final TimeSeriesSamplingFunction samplingFunction = getSamplingFunction(desiredValue.getConstraint(ValuePropertyNames.SAMPLING_FUNCTION));
final LocalDate[] schedule = HOLIDAY_REMOVER.getStrippedSchedule(scheduleCalculator.getSchedule(startDate, now, true, false), WEEKEND_CALENDAR);
final ConfigSource configSource = OpenGammaExecutionContext.getConfigSource(executionContext);
final CreditSecurityToIdentifierVisitor identifierVisitor = new CreditSecurityToIdentifierVisitor(OpenGammaExecutionContext.getSecuritySource(executionContext));
final FinancialSecurity security = (FinancialSecurity) target.getPosition().getSecurity();
final String spreadCurveName = security.accept(identifierVisitor).getUniqueId().getValue();
//TODO
final String curveName = getCurvePrefix() + "_" + spreadCurveName;
final CurveSpecification curveSpecification = CurveUtils.getCurveSpecification(snapshotClock.instant(), configSource, now, curveName);
DoubleTimeSeries<?> fxSeries = null;
boolean isInverse = true;
if (!desiredCurrency.equals(currency)) {
final Object fxSeriesObject = inputs.getValue(ValueRequirementNames.HISTORICAL_FX_TIME_SERIES);
if (fxSeriesObject == null) {
throw new OpenGammaRuntimeException("Could not get historical FX series");
}
@SuppressWarnings("unchecked")
final Map.Entry<UnorderedCurrencyPair, DoubleTimeSeries<?>> entry = Iterables.getOnlyElement(((Map<UnorderedCurrencyPair, DoubleTimeSeries<?>>) fxSeriesObject).entrySet());
final Object currencyPairObject = inputs.getValue(ValueRequirementNames.CURRENCY_PAIRS);
if (currencyPairObject == null) {
throw new OpenGammaRuntimeException("Could not get currency pairs");
}
final CurrencyPairs currencyPairs = (CurrencyPairs) currencyPairObject;
if (desiredCurrency.equals(currencyPairs.getCurrencyPair(Currency.of(desiredCurrency), Currency.of(currency)).getCounter().getCode())) {
isInverse = false;
}
fxSeries = entry.getValue();
}
final Object bucketedCS01Object = inputs.getValue(ValueRequirementNames.BUCKETED_CS01);
if (bucketedCS01Object == null) {
throw new OpenGammaRuntimeException("Could not get bucketed CS01");
}
final LocalDateLabelledMatrix1D bucketedCS01 = (LocalDateLabelledMatrix1D) bucketedCS01Object;
final Object htsObject = inputs.getValue(ValueRequirementNames.CREDIT_SPREAD_CURVE_HISTORICAL_TIME_SERIES);
if (htsObject == null) {
throw new OpenGammaRuntimeException("Could not get credit spread curve historical time series");
}
final HistoricalTimeSeriesBundle hts = (HistoricalTimeSeriesBundle) htsObject;
final NavigableSet<CurveNodeWithIdentifier> nodes = getNodes(now, security, curveSpecification.getNodes());
DoubleTimeSeries<?> pnlSeries = getPnLSeries(nodes, bucketedCS01, hts, schedule, samplingFunction, fxSeries, isInverse);
if (pnlSeries == null) {
throw new OpenGammaRuntimeException("Could not get any values for security " + position.getSecurity());
}
pnlSeries = pnlSeries.multiply(position.getQuantity().doubleValue());
final ValueSpecification resultSpec = new ValueSpecification(ValueRequirementNames.PNL_SERIES, target.toSpecification(), desiredValue.getConstraints());
return Sets.newHashSet(new ComputedValue(resultSpec, pnlSeries));
}