Package com.opengamma.financial.view

Source Code of com.opengamma.financial.view.HistoricalViewEvaluationTarget

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

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.ObjectUtils;
import org.fudgemsg.FudgeField;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.MutableFudgeMsg;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.threeten.bp.LocalDate;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.marketdata.historical.HistoricalShockMarketDataSnapshot.ShockType;
import com.opengamma.engine.marketdata.spec.FixedHistoricalMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.HistoricalShockMarketDataSpecification;
import com.opengamma.engine.marketdata.spec.MarketDataSpecification;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.execution.ArbitraryViewCycleExecutionSequence;
import com.opengamma.engine.view.execution.ViewCycleExecutionOptions;
import com.opengamma.engine.view.execution.ViewCycleExecutionSequence;
import com.opengamma.financial.OpenGammaExecutionContext;
import com.opengamma.financial.analytics.timeseries.DateConstraint;
import com.opengamma.financial.convention.HolidaySourceCalendarAdapter;
import com.opengamma.id.UniqueId;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;

/**
* Target for {@link HistoricalViewEvaluationFunction} which ensures that an execution sequence is constructed which matches the function's expectations.
*/
public class HistoricalViewEvaluationTarget extends ViewEvaluationTarget {

  /**
   * Fudge field containing the start date
   */
  protected static final String START_DATE_FIELD = "startDate";
  /**
   * Fudge field containing whether the start date is inclusive.
   */
  protected static final String INCLUDE_START_FIELD = "includeStart";
  /**
   * Fudge field containing the end date.
   */
  protected static final String END_DATE_FIELD = "endDate";
  /**
   * Fudge field containing whether the end date is inclusive.
   */
  protected static final String INCLUDE_END_FIELD = "includeEnd";
  /**
   * Repeated Fudge field, each containing a currency ISO code for the compound holiday calendar to use.
   */
  protected static final String CURRENCY_CALENDAR_FIELD = "currencyCalendar";
  /**
   * Fudge field containing the market data mode.
   */
  protected static final String MARKET_DATA_MODE_FIELD = "marketDataMode";

  /**
   * Creates a new target.
   *
   * @param user  the user the view is created for, not null.
   * @param startDate  the start date as a {@link DateConstraint} encoded string, not null
   * @param includeStart  whether to include the start date in the evaluation.
   * @param endDate  the end date as a {@link DateConstraint} encoded string, not null
   * @param includeEnd  whether to include the end date in the evaluation.
   * @param currencyCalendars  the currencies for which to obtain a compound holiday calendar in order to obtain a valid sequence of dates, may be null
   * @param marketDataMode  the mode in which market data should be obtained, not null
   */
  public HistoricalViewEvaluationTarget(UserPrincipal user, String startDate, boolean includeStart, String endDate,
      boolean includeEnd, Set<Currency> currencyCalendars, HistoricalViewEvaluationMarketDataMode marketDataMode) {
    super(user, new HistoricalSequence(startDate, includeStart, endDate, includeEnd, currencyCalendars, marketDataMode));
  }

  protected HistoricalViewEvaluationTarget(ViewDefinition viewDefinition, final HistoricalSequence sequence) {
    super(viewDefinition, sequence);
  }

  private HistoricalViewEvaluationTarget(FudgeDeserializer deserializer, FudgeMsg message) {
    this(deserializer, message,
        message.getString(START_DATE_FIELD),
        message.getBoolean(INCLUDE_START_FIELD),
        message.getString(END_DATE_FIELD),
        message.getBoolean(INCLUDE_END_FIELD),
        getCurrencyCalendars(deserializer, message),
        deserializer.fieldValueToObject(HistoricalViewEvaluationMarketDataMode.class, message.getByName(MARKET_DATA_MODE_FIELD)));
  }

  private HistoricalViewEvaluationTarget(FudgeDeserializer deserializer, FudgeMsg message, String startDate,
      boolean includeStart, String endDate, boolean includeEnd, Set<Currency> currencyCalendars, HistoricalViewEvaluationMarketDataMode marketDataMode) {
    super(deserializer, message, new HistoricalSequence(startDate, includeStart, endDate, includeEnd, currencyCalendars, marketDataMode));
  }

  protected HistoricalViewEvaluationTarget(final HistoricalViewEvaluationTarget copyFrom, final UniqueId uid) {
    super(copyFrom, uid);
  }

  @Override
  protected ViewEvaluationTarget createUnion(final ViewDefinition newViewDefinition) {
    return new HistoricalViewEvaluationTarget(newViewDefinition, (HistoricalSequence) getExecutionSequence());
  }
 
  private static Set<Currency> getCurrencyCalendars(FudgeDeserializer deserializer, FudgeMsg message) {
    Set<Currency> currencies = new HashSet<Currency>();
    for (FudgeField ccyField : message.getAllByName(CURRENCY_CALENDAR_FIELD)) {
      Currency ccy = deserializer.fieldValueToObject(Currency.class, ccyField);
      currencies.add(ccy);
    }
    return !currencies.isEmpty() ? currencies : null;
  }

  private static final class HistoricalSequence implements ViewCycleExecutionSequenceDescriptor {

    /**
     * The description of the start date.
     */
    private final String _startDateDescriptor;
    /**
     * Indicates whether to include the start date.
     */
    private final boolean _includeStart;
    /**
     * The description of the end date.
     */
    private final String _endDateDescriptor;
    /**
     * Indicates whether to include the end date.
     */
    private final boolean _includeEnd;
    /**
     * The currencies for which to obtain a compound calendar in order to generate the correct sequence of dates, null to ignore holidays.
     */
    private final Set<Currency> _currencyCalendars;
    /**
     * The historical market data type
     */
    private final HistoricalViewEvaluationMarketDataMode _marketDataMode;

    public HistoricalSequence(String startDateDescriptor, boolean includeStart, String endDateDescriptor,
        boolean includeEnd, Set<Currency> currencyCalendars, HistoricalViewEvaluationMarketDataMode marketDataMode) {
      ArgumentChecker.notNull(startDateDescriptor, "startDate");
      ArgumentChecker.notNull(endDateDescriptor, "endDate");
      ArgumentChecker.notNull(marketDataMode, "marketDataMode");
      _startDateDescriptor = startDateDescriptor;
      _includeStart = includeStart;
      _endDateDescriptor = endDateDescriptor;
      _includeEnd = includeEnd;
      _currencyCalendars = currencyCalendars;
      _marketDataMode = marketDataMode;
    }

    // ViewCycleExecutionSequenceDescriptor

    @Override
    public ViewCycleExecutionSequence createSequence(FunctionExecutionContext executionContext) {
      LocalDate startDate = DateConstraint.evaluate(executionContext, _startDateDescriptor);
      LocalDate endDate = DateConstraint.evaluate(executionContext, _endDateDescriptor);
      if (!_includeStart) {
        startDate = startDate.plusDays(1);
      }
      if (!_includeEnd) {
        endDate = endDate.minusDays(1);
      }
      HolidaySourceCalendarAdapter calendar;
      if (_currencyCalendars != null) {
        Currency[] currencies = _currencyCalendars.toArray(new Currency[_currencyCalendars.size()]);
        HolidaySource holidaySource = OpenGammaExecutionContext.getHolidaySource(executionContext);
        calendar = new HolidaySourceCalendarAdapter(holidaySource, currencies);
      } else {
        calendar = null;
      }
      List<ViewCycleExecutionOptions> executionSequence = new LinkedList<ViewCycleExecutionOptions>();
      LocalDate previousWorkingDate = null;
      LocalDate currentDate = startDate;
      while (!currentDate.isAfter(endDate)) {
        if (calendar == null || calendar.isWorkingDay(currentDate)) {
          MarketDataSpecification marketDataSpec = createMarketDataSpec(previousWorkingDate, currentDate, LocalDate.now(executionContext.getValuationClock()));
          if (marketDataSpec != null) {
            ViewCycleExecutionOptions executionOptions = ViewCycleExecutionOptions.builder()
                .setMarketDataSpecification(marketDataSpec)
                .create();
            executionSequence.add(executionOptions);
          }
          previousWorkingDate = currentDate;
        }
        currentDate = currentDate.plusDays(1);
      }
      return new ArbitraryViewCycleExecutionSequence(executionSequence);
    }

    private MarketDataSpecification createMarketDataSpec(LocalDate previousHistoricalDate, LocalDate historicalDate, LocalDate valuationDate) {
      FixedHistoricalMarketDataSpecification historicalDateSpec = new FixedHistoricalMarketDataSpecification(historicalDate);
      switch (_marketDataMode) {
        case HISTORICAL:
          return historicalDateSpec;
        case RELATIVE_SHOCK:
          if (previousHistoricalDate == null) {
            return null;
          }
          FixedHistoricalMarketDataSpecification valuationDateSpec = new FixedHistoricalMarketDataSpecification(valuationDate);
          FixedHistoricalMarketDataSpecification previousHistoricalDateSpec = new FixedHistoricalMarketDataSpecification(previousHistoricalDate);
          return new HistoricalShockMarketDataSpecification(ShockType.PROPORTIONAL, previousHistoricalDateSpec, historicalDateSpec, valuationDateSpec);
        default:
          throw new OpenGammaRuntimeException("Unsupported market data mode: " + _marketDataMode);
      }
    }

    // Object

    @Override
    public int hashCode() {
      int hc = 1;
      hc += (hc << 4) + ObjectUtils.hashCode(_startDateDescriptor);
      hc += (hc << 4) + (_includeStart ? 1 : 0);
      hc += (hc << 4) + ObjectUtils.hashCode(_endDateDescriptor);
      hc += (hc << 4) + (_includeEnd ? 1 : 0);
      hc += (hc << 4) + (_currencyCalendars != null ? _currencyCalendars.hashCode() : 0);
      hc += (hc << 4) + _marketDataMode.hashCode();
      return hc;
    }

    @Override
    public boolean equals(final Object o) {
      if (o == this) {
        return true;
      }
      if (!(o instanceof HistoricalSequence)) {
        return false;
      }
      final HistoricalSequence other = (HistoricalSequence) o;
      return ObjectUtils.equals(_startDateDescriptor, other._startDateDescriptor)
          && (_includeStart == other._includeStart)
          && ObjectUtils.equals(_endDateDescriptor, other._endDateDescriptor)
          && (_includeEnd == other._includeEnd)
          && ObjectUtils.equals(_currencyCalendars, other._currencyCalendars)
          && (_marketDataMode == other._marketDataMode);
    }

  }

  public String getStartDate() {
    return ((HistoricalSequence) getExecutionSequence())._startDateDescriptor;
  }

  public boolean isIncludeStart() {
    return ((HistoricalSequence) getExecutionSequence())._includeStart;
  }

  public String getEndDate() {
    return ((HistoricalSequence) getExecutionSequence())._endDateDescriptor;
  }

  public boolean isIncludeEnd() {
    return ((HistoricalSequence) getExecutionSequence())._includeEnd;
  }
 
  public Set<Currency> getCurrencyCalendars() {
    return ((HistoricalSequence) getExecutionSequence())._currencyCalendars;
  }
 
  public HistoricalViewEvaluationMarketDataMode getMarketDataMode() {
    return ((HistoricalSequence) getExecutionSequence())._marketDataMode;
  }

  @Override
  public HistoricalViewEvaluationTarget withUniqueId(final UniqueId uid) {
    return new HistoricalViewEvaluationTarget(this, uid);
  }

  @Override
  protected void toFudgeMsgImpl(FudgeSerializer serializer, MutableFudgeMsg message) {
    super.toFudgeMsgImpl(serializer, message);
  }

  @Override
  protected void serializeExecutionSequence(FudgeSerializer serializer, MutableFudgeMsg message) {
    // More efficient to recreate the execution sequence rather than serializing it
    message.add(START_DATE_FIELD, getStartDate());
    message.add(INCLUDE_START_FIELD, isIncludeStart());
    message.add(END_DATE_FIELD, getEndDate());
    message.add(INCLUDE_END_FIELD, isIncludeEnd());
    if (getCurrencyCalendars() != null) {
      for (Currency ccy : getCurrencyCalendars()) {
        serializer.addToMessage(message, CURRENCY_CALENDAR_FIELD, null, ccy);
      }
    }
    serializer.addToMessage(message, MARKET_DATA_MODE_FIELD, null, getMarketDataMode());
  }

  public static HistoricalViewEvaluationTarget fromFudgeMsg(FudgeDeserializer deserializer, FudgeMsg message) {
    return new HistoricalViewEvaluationTarget(deserializer, message);
  }

}
TOP

Related Classes of com.opengamma.financial.view.HistoricalViewEvaluationTarget

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.