public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
final ValueRequirement desiredValue = desiredValues.iterator().next();
BigDecimal tradeValue = null;
HistoricalTimeSeries htsMarkToMarket = null;
HistoricalTimeSeries htsCostOfCarry = null;
final PositionOrTrade trade = target.getPositionOrTrade();
for (final ComputedValue input : inputs.getAllValues()) {
if (ValueRequirementNames.VALUE.equals(input.getSpecification().getValueName())) {
tradeValue = BigDecimal.valueOf((Double) input.getValue());
if (trade instanceof Trade) {
// Need to scale the value by the trade quantity
tradeValue = ((Trade) trade).getQuantity().multiply(tradeValue);
}
} else if (ValueRequirementNames.HISTORICAL_TIME_SERIES.equals(input.getSpecification().getValueName())) {
final String field = input.getSpecification().getProperty(HistoricalTimeSeriesFunctionUtils.DATA_FIELD_PROPERTY);
if (_costOfCarryField.equals(field)) {
htsCostOfCarry = (HistoricalTimeSeries) input.getValue();
} else if (_mark2MarketField.equals(field)) {
htsMarkToMarket = (HistoricalTimeSeries) input.getValue();
}
}
}
final Security security = trade.getSecurity();
LocalDate tradeDate = getPreferredTradeDate(executionContext.getValuationClock(), trade);
tradeDate = checkAvailableData(tradeDate, htsMarkToMarket, security, _mark2MarketField, _resolutionKey);
final ValueSpecification valueSpecification = new ValueSpecification(getResultValueRequirementName(), target.toSpecification(), desiredValue.getConstraints());
final double costOfCarry = getCostOfCarry(security, tradeDate, htsCostOfCarry);
Double markToMarket = htsMarkToMarket.getTimeSeries().getValue(tradeDate);
if (security instanceof FutureSecurity) {
final FutureSecurity futureSecurity = (FutureSecurity) security;
markToMarket = markToMarket * futureSecurity.getUnitAmount();
}
final BigDecimal dailyPnL = tradeValue.subtract(trade.getQuantity().multiply(BigDecimal.valueOf(markToMarket + costOfCarry)));
s_logger.debug("{} security: {} quantity: {} fairValue: {} markToMarket: {} costOfCarry: {} dailyPnL: {}",
new Object[] {trade.getUniqueId(), trade.getSecurity().getExternalIdBundle(), trade.getQuantity(), tradeValue, markToMarket, costOfCarry, dailyPnL });
final ComputedValue result = new ComputedValue(valueSpecification, MoneyCalculationUtils.rounded(dailyPnL).doubleValue());
return Sets.newHashSet(result);
}