Ejemplo n.º 1
0
 @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 = snapshotClock.zonedDateTime();
   final FinancialSecurity security = (FinancialSecurity) target.getSecurity();
   final Currency payCurrency, receiveCurrency;
   if (security instanceof FXForwardSecurity) {
     final FXForwardSecurity forward = (FXForwardSecurity) security;
     payCurrency = forward.getPayCurrency();
     receiveCurrency = forward.getReceiveCurrency();
   } else {
     final NonDeliverableFXForwardSecurity ndf = (NonDeliverableFXForwardSecurity) security;
     payCurrency = ndf.getPayCurrency();
     receiveCurrency = ndf.getReceiveCurrency();
   }
   final ForexDefinition definition = (ForexDefinition) security.accept(VISITOR);
   final ValueRequirement desiredValue = desiredValues.iterator().next();
   final String payCurveName = desiredValue.getConstraint(ValuePropertyNames.PAY_CURVE);
   final String receiveCurveName = desiredValue.getConstraint(ValuePropertyNames.RECEIVE_CURVE);
   final String payCurveConfig = desiredValue.getConstraint(PAY_CURVE_CALC_CONFIG);
   final String receiveCurveConfig = desiredValue.getConstraint(RECEIVE_CURVE_CALC_CONFIG);
   final String fullPutCurveName = payCurveName + "_" + payCurrency.getCode();
   final String fullCallCurveName = receiveCurveName + "_" + receiveCurrency.getCode();
   final YieldAndDiscountCurve payFundingCurve =
       getCurve(inputs, payCurrency, payCurveName, payCurveConfig);
   final YieldAndDiscountCurve receiveFundingCurve =
       getCurve(inputs, receiveCurrency, receiveCurveName, receiveCurveConfig);
   final YieldAndDiscountCurve[] curves;
   final Map<String, Currency> curveCurrency = new HashMap<String, Currency>();
   curveCurrency.put(fullPutCurveName, payCurrency);
   curveCurrency.put(fullCallCurveName, receiveCurrency);
   final String[] allCurveNames;
   if (FXUtils.isInBaseQuoteOrder(
       payCurrency, receiveCurrency)) { // To get Base/quote in market standard order.
     curves = new YieldAndDiscountCurve[] {payFundingCurve, receiveFundingCurve};
     allCurveNames = new String[] {fullPutCurveName, fullCallCurveName};
   } else {
     curves = new YieldAndDiscountCurve[] {receiveFundingCurve, payFundingCurve};
     allCurveNames = new String[] {fullCallCurveName, fullPutCurveName};
   }
   final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves);
   final ValueProperties.Builder properties =
       getResultProperties(
           payCurveName, receiveCurveName, payCurveConfig, receiveCurveConfig, target);
   final ValueSpecification spec =
       new ValueSpecification(
           ValueRequirementNames.VALUE_THETA, target.toSpecification(), properties.get());
   final ConstantSpreadHorizonThetaCalculator calculator =
       ConstantSpreadHorizonThetaCalculator.getInstance();
   final MultipleCurrencyAmount theta =
       calculator.getTheta(definition, now, allCurveNames, yieldCurves, DAYS_TO_MOVE_FORWARD);
   return Collections.singleton(new ComputedValue(spec, theta));
 }
 @Override
 public Set<ValueSpecification> getResults(
     final FunctionCompilationContext context,
     final ComputationTarget target,
     final Map<ValueSpecification, ValueRequirement> inputs) {
   if (inputs.size() == 1) {
     final ValueSpecification input = Iterables.getOnlyElement(inputs.keySet());
     if (ValueRequirementNames.PNL_SERIES.equals(input.getValueName())) {
       return Collections.singleton(input);
     }
   }
   final FXForwardSecurity security = (FXForwardSecurity) target.getPosition().getSecurity();
   final CurrencyPair currencyPair =
       _currencyPairs.getCurrencyPair(security.getPayCurrency(), security.getReceiveCurrency());
   if (currencyPair == null) {
     return null;
   }
   final Currency currencyBase = currencyPair.getBase();
   String resultCurrency = null;
   final ValueProperties.Builder builder = createValueProperties();
   for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) {
     final ValueSpecification inputSpec = entry.getKey();
     final ValueRequirement inputReq = entry.getValue();
     if (inputReq.getValueName().equals(RETURN_SERIES)) {
       final Set<String> resultCurrencies = inputReq.getConstraints().getValues(CURRENCY);
       if (resultCurrencies != null && resultCurrencies.size() == 1) {
         resultCurrency = inputReq.getConstraint(CURRENCY);
       } else {
         resultCurrency = currencyBase.getCode();
       }
     }
     for (final String propertyName : inputSpec.getProperties().getProperties()) {
       if (ValuePropertyNames.FUNCTION.equals(propertyName)) {
         continue;
       }
       final Set<String> values = inputSpec.getProperties().getValues(propertyName);
       if (values == null || values.isEmpty()) {
         builder.withAny(propertyName);
       } else {
         builder.with(propertyName, values);
       }
     }
   }
   if (resultCurrency == null) {
     return null;
   }
   builder
       .with(ValuePropertyNames.CURRENCY, resultCurrency)
       .with(
           ValuePropertyNames.PROPERTY_PNL_CONTRIBUTIONS,
           ValueRequirementNames.FX_CURRENCY_EXPOSURE);
   return ImmutableSet.of(
       new ValueSpecification(
           ValueRequirementNames.PNL_SERIES, target.toSpecification(), builder.get()));
 }
    @Override
    public Set<ComputedValue> execute(
        final FunctionExecutionContext executionContext,
        final FunctionInputs inputs,
        final ComputationTarget target,
        final Set<ValueRequirement> desiredValues) {
      final Position position = target.getPosition();
      final ValueRequirement desiredValue = desiredValues.iterator().next();
      final ValueProperties constraints = desiredValue.getConstraints();
      final Set<String> resultCurrencies = constraints.getValues(CURRENCY);
      final FXForwardSecurity security = (FXForwardSecurity) position.getSecurity();
      final MultipleCurrencyAmount mca =
          (MultipleCurrencyAmount) inputs.getValue(ValueRequirementNames.FX_CURRENCY_EXPOSURE);
      final Currency payCurrency = security.getPayCurrency();
      final Currency receiveCurrency = security.getReceiveCurrency();
      final CurrencyPair currencyPair =
          _currencyPairs.getCurrencyPair(payCurrency, receiveCurrency);
      final Currency baseCurrency = currencyPair.getBase();
      final Currency currencyNonBase = currencyPair.getCounter(); // The non-base currency
      final double exposure = mca.getAmount(currencyNonBase);

      final ValueSpecification spec =
          new ValueSpecification(
              ValueRequirementNames.PNL_SERIES,
              target.toSpecification(),
              desiredValue.getConstraints());
      if (resultCurrencies == null || resultCurrencies.size() != 1) {
        s_logger.warn("No Currency property - returning result in base currency");
        final LocalDateDoubleTimeSeries fxSpotReturnSeries =
            (LocalDateDoubleTimeSeries) inputs.getValue(ValueRequirementNames.RETURN_SERIES);
        final LocalDateDoubleTimeSeries pnlSeries =
            fxSpotReturnSeries.multiply(
                position.getQuantity().doubleValue()
                    * exposure); // The P/L time series is in the base currency
        return Collections.singleton(new ComputedValue(spec, pnlSeries));
      }
      final Currency resultCurrency = Currency.of(Iterables.getOnlyElement(resultCurrencies));
      final LocalDateDoubleTimeSeries conversionTS =
          (LocalDateDoubleTimeSeries) inputs.getValue(HISTORICAL_FX_TIME_SERIES);
      if (conversionTS == null) {
        throw new OpenGammaRuntimeException(
            "Asked for result in "
                + resultCurrency
                + " but could not get "
                + baseCurrency
                + "/"
                + resultCurrency
                + " conversion series");
      }
      if (resultCurrency.equals(baseCurrency)) {
        final LocalDateDoubleTimeSeries fxSpotReturnSeries =
            (LocalDateDoubleTimeSeries) inputs.getValue(ValueRequirementNames.RETURN_SERIES);
        final LocalDateDoubleTimeSeries convertedSeries =
            conversionTS
                .reciprocal()
                .multiply(
                    position.getQuantity().doubleValue()
                        * exposure); // The P/L time series is in the base currency
        final LocalDateDoubleTimeSeries pnlSeries =
            fxSpotReturnSeries.multiply(
                convertedSeries); // The P/L time series is in the base currency
        return Collections.singleton(new ComputedValue(spec, pnlSeries));
      }
      final LocalDateDoubleTimeSeries fxSpotReturnSeries =
          (LocalDateDoubleTimeSeries) inputs.getValue(ValueRequirementNames.RETURN_SERIES);
      final LocalDateDoubleTimeSeries convertedSeries =
          conversionTS.multiply(
              position.getQuantity().doubleValue()
                  * exposure); // The P/L time series is in the base currency
      final LocalDateDoubleTimeSeries pnlSeries = convertedSeries.multiply(fxSpotReturnSeries);
      return Collections.singleton(new ComputedValue(spec, pnlSeries));
    }