Package com.opengamma.financial.analytics.model.pnl

Source Code of com.opengamma.financial.analytics.model.pnl.FXOptionBlackDeltaPnLFunction$Compiled

/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.pnl;

import java.util.Collections;
import java.util.Set;

import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.opengamma.analytics.financial.schedule.HolidayDateRemovalFunction;
import com.opengamma.analytics.financial.schedule.Schedule;
import com.opengamma.analytics.financial.schedule.ScheduleCalculatorFactory;
import com.opengamma.analytics.financial.schedule.TimeSeriesSamplingFunction;
import com.opengamma.analytics.financial.schedule.TimeSeriesSamplingFunctionFactory;
import com.opengamma.analytics.financial.timeseries.util.TimeSeriesDifferenceOperator;
import com.opengamma.core.position.Position;
import com.opengamma.core.security.Security;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.function.AbstractFunction;
import com.opengamma.engine.function.CompiledFunctionDefinition;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.financial.OpenGammaCompilationContext;
import com.opengamma.financial.OpenGammaExecutionContext;
import com.opengamma.financial.analytics.model.CalculationPropertyNamesAndValues;
import com.opengamma.financial.analytics.model.InterpolatedDataProperties;
import com.opengamma.financial.analytics.model.forex.ConventionBasedFXRateFunction;
import com.opengamma.financial.analytics.model.forex.ForexVisitors;
import com.opengamma.financial.analytics.model.forex.option.black.FXOptionBlackFunction;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.calendar.MondayToFridayCalendar;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.financial.currency.CurrencyPairs;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.option.FXDigitalOptionSecurity;
import com.opengamma.financial.security.option.FXOptionSecurity;
import com.opengamma.timeseries.DoubleTimeSeries;
import com.opengamma.timeseries.date.DateDoubleTimeSeries;
import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;

/**
*
*/
public class FXOptionBlackDeltaPnLFunction extends AbstractFunction {

  private static final HolidayDateRemovalFunction HOLIDAY_REMOVER = HolidayDateRemovalFunction.getInstance();
  private static final Calendar WEEKEND_CALENDAR = new MondayToFridayCalendar("Weekend");
  private static final TimeSeriesDifferenceOperator DIFFERENCE = new TimeSeriesDifferenceOperator();

  @Override
  public CompiledFunctionDefinition compile(final FunctionCompilationContext context, final Instant atInstant) {
    final CurrencyPairs currencyPairs = OpenGammaCompilationContext.getCurrencyPairsSource(context).getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS);
    return new Compiled(currencyPairs);
  }

  /**
   * Compiled form.
   */
  protected class Compiled extends AbstractInvokingCompiledFunction {

    private final CurrencyPairs _currencyPairs;

    public Compiled(final CurrencyPairs currencyPairs) {
      _currencyPairs = currencyPairs;
    }

    // CompiledFunctionDefinition

    @Override
    public ComputationTargetType getTargetType() {
      return ComputationTargetType.POSITION;
    }

    @Override
    public boolean canApplyTo(final FunctionCompilationContext context, final ComputationTarget target) {
      final Security security = target.getPosition().getSecurity();
      return security instanceof FXOptionSecurity || security instanceof FXDigitalOptionSecurity;
    }

    @Override
    public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) {
      final FinancialSecurity security = (FinancialSecurity) target.getPosition().getSecurity();
      final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
      final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
      final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(putCurrency, callCurrency);
      final Currency currencyBase = currencyPair.getBase(); // The base currency
      final ValueProperties properties = createValueProperties()
          .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
          .withAny(FXOptionBlackFunction.PUT_CURVE)
          .withAny(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG)
          .withAny(FXOptionBlackFunction.CALL_CURVE)
          .withAny(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG)
          .withAny(ValuePropertyNames.SURFACE)
          .withAny(InterpolatedDataProperties.X_INTERPOLATOR_NAME)
          .withAny(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME)
          .withAny(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME)
          .with(ValuePropertyNames.CURRENCY, currencyBase.getCode())
          .withAny(ValuePropertyNames.SAMPLING_PERIOD)
          .withAny(ValuePropertyNames.SCHEDULE_CALCULATOR)
          .withAny(ValuePropertyNames.SAMPLING_FUNCTION)
          .with(ValuePropertyNames.PROPERTY_PNL_CONTRIBUTIONS, ValueRequirementNames.FX_CURRENCY_EXPOSURE)
          .get();
      return Sets.newHashSet(new ValueSpecification(ValueRequirementNames.PNL_SERIES, target.toSpecification(), properties));
    }

    @Override
    public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) {
      final ValueProperties constraints = desiredValue.getConstraints();
      final Set<String> putCurveNames = constraints.getValues(FXOptionBlackFunction.PUT_CURVE);
      if (putCurveNames == null || putCurveNames.size() != 1) {
        return null;
      }
      final Set<String> putCurveCalculationConfigs = constraints.getValues(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG);
      if (putCurveCalculationConfigs == null || putCurveCalculationConfigs.size() != 1) {
        return null;
      }
      final Set<String> callCurveNames = constraints.getValues(FXOptionBlackFunction.CALL_CURVE);
      if (callCurveNames == null || callCurveNames.size() != 1) {
        return null;
      }
      final Set<String> callCurveCalculationConfigs = constraints.getValues(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG);
      if (callCurveCalculationConfigs == null || callCurveCalculationConfigs.size() != 1) {
        return null;
      }
      final Set<String> surfaceNames = constraints.getValues(ValuePropertyNames.SURFACE);
      if (surfaceNames == null || surfaceNames.size() != 1) {
        return null;
      }
      final Set<String> interpolatorNames = constraints.getValues(InterpolatedDataProperties.X_INTERPOLATOR_NAME);
      if (interpolatorNames == null || interpolatorNames.size() != 1) {
        return null;
      }
      final Set<String> leftExtrapolatorNames = constraints.getValues(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME);
      if (leftExtrapolatorNames == null || leftExtrapolatorNames.size() != 1) {
        return null;
      }
      final Set<String> rightExtrapolatorNames = constraints.getValues(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME);
      if (rightExtrapolatorNames == null || rightExtrapolatorNames.size() != 1) {
        return null;
      }
      final Set<String> samplingPeriods = constraints.getValues(ValuePropertyNames.SAMPLING_PERIOD);
      if (samplingPeriods == null || samplingPeriods.size() != 1) {
        return null;
      }
      final FinancialSecurity security = (FinancialSecurity) target.getPosition().getSecurity();
      final ValueProperties exposureConstraints = ValueProperties.builder()
          .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
          .with(FXOptionBlackFunction.PUT_CURVE, putCurveNames.iterator().next())
          .with(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG, putCurveCalculationConfigs.iterator().next())
          .with(FXOptionBlackFunction.CALL_CURVE, callCurveNames.iterator().next())
          .with(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG, callCurveCalculationConfigs.iterator().next())
          .with(ValuePropertyNames.SURFACE, surfaceNames.iterator().next())
          .with(InterpolatedDataProperties.X_INTERPOLATOR_NAME, interpolatorNames.iterator().next())
          .with(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME, leftExtrapolatorNames.iterator().next())
          .with(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME, rightExtrapolatorNames.iterator().next()).get();
      final ValueRequirement fxCurrencyExposureRequirement = new ValueRequirement(
          ValueRequirementNames.FX_CURRENCY_EXPOSURE, ComputationTargetType.SECURITY, security.getUniqueId(), exposureConstraints);
      final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
      final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
      final ValueRequirement fxSpotRequirement = ConventionBasedFXRateFunction.getHistoricalTimeSeriesRequirement(putCurrency, callCurrency);
      return ImmutableSet.of(fxCurrencyExposureRequirement, fxSpotRequirement);
    }

    // FunctionInvoker

    @Override
    public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
      final Position position = target.getPosition();
      final ZonedDateTime now = ZonedDateTime.now(executionContext.getValuationClock());
      final ValueRequirement desiredValue = desiredValues.iterator().next();
      final String samplingPeriod = desiredValue.getConstraint(ValuePropertyNames.SAMPLING_PERIOD);
      final String scheduleCalculator = desiredValue.getConstraint(ValuePropertyNames.SCHEDULE_CALCULATOR);
      final String samplingFunction = desiredValue.getConstraint(ValuePropertyNames.SAMPLING_FUNCTION);
      final FinancialSecurity security = (FinancialSecurity) position.getSecurity();
      final MultipleCurrencyAmount mca = (MultipleCurrencyAmount) inputs.getValue(ValueRequirementNames.FX_CURRENCY_EXPOSURE);
      final LocalDateDoubleTimeSeries timeSeries = (LocalDateDoubleTimeSeries) inputs.getValue(ValueRequirementNames.HISTORICAL_FX_TIME_SERIES);
      final LocalDate startDate = now.toLocalDate().minus(Period.parse(samplingPeriod));
      final Schedule schedule = ScheduleCalculatorFactory.getScheduleCalculator(scheduleCalculator);
      final TimeSeriesSamplingFunction sampling = TimeSeriesSamplingFunctionFactory.getFunction(samplingFunction);
      final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
      final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
      final CurrencyPairs currencyPairs = OpenGammaExecutionContext.getCurrencyPairsSource(executionContext).getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS);
      final CurrencyPair currencyPair = currencyPairs.getCurrencyPair(putCurrency, callCurrency);
      final Currency currencyNonBase = currencyPair.getCounter(); // The non-base currency
      final double delta = mca.getAmount(currencyNonBase);
      DoubleTimeSeries<?> result = getPnLSeries(startDate, now.toLocalDate(), schedule, sampling, timeSeries);
      result = result.multiply(position.getQuantity().doubleValue() * delta);
      final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.PNL_SERIES, target.toSpecification(), desiredValue.getConstraints());
      return Collections.singleton(new ComputedValue(spec, result));
    }

  }

  private DateDoubleTimeSeries<?> getPnLSeries(final LocalDate startDate, final LocalDate now, final Schedule scheduleCalculator,
      final TimeSeriesSamplingFunction samplingFunction, final LocalDateDoubleTimeSeries timeSeries) {
    final LocalDate[] dates = HOLIDAY_REMOVER.getStrippedSchedule(scheduleCalculator.getSchedule(startDate, now, true, false), WEEKEND_CALENDAR);
    LocalDateDoubleTimeSeries result = samplingFunction.getSampledTimeSeries(timeSeries, dates);
    result = result.reciprocal(); // Implementation note: to obtain the P/L for one unit of non-base currency expressed in base currency.
    return DIFFERENCE.evaluate(result);
  }
}
TOP

Related Classes of com.opengamma.financial.analytics.model.pnl.FXOptionBlackDeltaPnLFunction$Compiled

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.