Package com.opengamma.financial.generator

Source Code of com.opengamma.financial.generator.SecurityGenerator

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

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalTime;
import org.threeten.bp.Period;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.ZonedDateTime;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeFormatterBuilder;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve;
import com.opengamma.analytics.math.linearalgebra.DecompositionFactory;
import com.opengamma.core.config.ConfigSource;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.core.organization.OrganizationSource;
import com.opengamma.core.position.Counterparty;
import com.opengamma.core.region.RegionSource;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.DefaultComputationTargetResolver;
import com.opengamma.engine.function.AbstractFunction;
import com.opengamma.engine.function.CompiledFunctionDefinition;
import com.opengamma.engine.function.DummyFunctionReinitializer;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputsImpl;
import com.opengamma.engine.marketdata.ExternalIdBundleResolver;
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.ircurve.ConfigDBInterpolatedYieldCurveDefinitionSource;
import com.opengamma.financial.analytics.ircurve.ConfigDBInterpolatedYieldCurveSpecificationBuilder;
import com.opengamma.financial.analytics.ircurve.CurveSpecificationBuilderConfiguration;
import com.opengamma.financial.analytics.ircurve.YieldCurveMarketDataFunction;
import com.opengamma.financial.analytics.ircurve.YieldCurveSpecificationFunction;
import com.opengamma.financial.analytics.model.curve.forward.FXForwardCurveFromYieldCurvesFunction;
import com.opengamma.financial.analytics.model.curve.interestrate.MultiYieldCurvePresentValueMethodFunction;
import com.opengamma.financial.analytics.model.curve.interestrate.MultiYieldCurvePropertiesAndDefaults;
import com.opengamma.financial.analytics.model.forex.FXUtils;
import com.opengamma.financial.analytics.timeseries.HistoricalTimeSeriesBundle;
import com.opengamma.financial.convention.ConventionBundleSource;
import com.opengamma.financial.convention.ConventionSource;
import com.opengamma.financial.currency.ConfigDBCurrencyMatrixSource;
import com.opengamma.financial.currency.ConfigDBCurrencyPairsSource;
import com.opengamma.financial.currency.CurrencyMatrixResolver;
import com.opengamma.financial.currency.CurrencyPairs;
import com.opengamma.financial.currency.CurrencyPairsResolver;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalScheme;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.lambdava.functions.Function2;
import com.opengamma.master.config.ConfigMaster;
import com.opengamma.master.exchange.ExchangeMaster;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesMaster;
import com.opengamma.master.historicaltimeseries.impl.DefaultHistoricalTimeSeriesResolver;
import com.opengamma.master.historicaltimeseries.impl.DefaultHistoricalTimeSeriesSelector;
import com.opengamma.master.position.ManageableTrade;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.master.security.SecurityMaster;
import com.opengamma.master.security.impl.MasterSecuritySource;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.async.AsynchronousExecution;
import com.opengamma.util.async.AsynchronousOperation;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.UnorderedCurrencyPair;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.tuple.Pair;

/**
* Utility class for constructing parameters to random (but reasonable) securities.
*
* @param <T> the security type, or a common super type if multiple types are being produced
*/
public abstract class SecurityGenerator<T extends ManageableSecurity> {

  private static final Logger s_logger = LoggerFactory.getLogger(SecurityGenerator.class);

  /**
   * Format dates.
   */
  public static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd").toFormatter();

  /**
   * Format rates.
   */
  public static final DecimalFormat RATE_FORMATTER = new DecimalFormat("0.###%");

  /**
   * Format notionals.
   */
  public static final DecimalFormat NOTIONAL_FORMATTER = new DecimalFormat("0,000");

  /**
   * Constant for the length of a year in days.
   */
  protected static final double YEAR_LENGTH = 365.25;

  private Random _random = new Random();
  private ConventionBundleSource _conventionBundleSource;
  private ConfigSource _configSource;
  private ConfigMaster _configMaster;
  private HolidaySource _holidaySource;
  private HistoricalTimeSeriesSource _historicalSource;
  private HistoricalTimeSeriesMaster _htsMaster;
  private RegionSource _regionSource;
  private OrganizationSource _organizationSource;
  private ExchangeMaster _exchangeMaster;
  private SecurityMaster _securityMaster;
  private String _currencyCurveName;
  private final Map<Currency, String> _curveCalculationConfig = new HashMap<Currency, String>();
  private ExternalScheme _preferredScheme;
  private Function2<Currency, Currency, ExternalId> _spotRateIdentifier;
  private ConventionSource _conventionSource;

  private Currency[] _currencies;

  public Random getRandom() {
    return _random;
  }

  public void setRandom(final Random random) {
    _random = random;
  }

  protected int getRandom(final int n) {
    return getRandom().nextInt(n);
  }

  protected double getRandom(final double low, final double high) {
    return low + (high - low) * getRandom().nextDouble();
  }

  protected <X> X getRandom(final X[] xs) {
    return xs[getRandom(xs.length)];
  }

  protected <X> X getRandom(final List<X> xs) {
    return xs.get(getRandom(xs.size()));
  }

  protected int getRandom(final int[] xs) {
    return xs[getRandom(xs.length)];
  }

  protected double getRandom(final double[] xs) {
    return xs[getRandom(xs.length)];
  }

  public ConventionBundleSource getConventionBundleSource() {
    return _conventionBundleSource;
  }

  public void setConventionBundleSource(final ConventionBundleSource conventionBundleSource) {
    _conventionBundleSource = conventionBundleSource;
  }

  public ConventionSource getConventionSource() {
    return _conventionSource;
  }

  public void setConventionSource(final ConventionSource conventionSource) {
    _conventionSource = conventionSource;
  }

  public ConfigSource getConfigSource() {
    return _configSource;
  }

  public void setConfigSource(final ConfigSource configSource) {
    _configSource = configSource;
  }

  public ConfigMaster getConfigMaster() {
    return _configMaster;
  }

  public void setConfigMaster(final ConfigMaster configMaster) {
    _configMaster = configMaster;
  }

  public HolidaySource getHolidaySource() {
    return _holidaySource;
  }

  public void setHolidaySource(final HolidaySource holidaySource) {
    _holidaySource = holidaySource;
  }

  public HistoricalTimeSeriesSource getHistoricalSource() {
    return _historicalSource;
  }

  public void setHistoricalSource(final HistoricalTimeSeriesSource historicalSource) {
    _historicalSource = historicalSource;
  }

  public HistoricalTimeSeriesMaster getHistoricalTimeSeriesMaster() {
    return _htsMaster;
  }

  public void setHistoricalTimeSeriesMaster(final HistoricalTimeSeriesMaster htsMaster) {
    _htsMaster = htsMaster;
  }

  public ExchangeMaster getExchangeMaster() {
    return _exchangeMaster;
  }

  public void setExchangeMaster(final ExchangeMaster exchangeMaster) {
    _exchangeMaster = exchangeMaster;
  }

  public RegionSource getRegionSource() {
    return _regionSource;
  }

  public void setRegionSource(final RegionSource regionSource) {
    _regionSource = regionSource;
  }

  public OrganizationSource getOrganizationSource() {
    return _organizationSource;
  }

  public void setOrganizationSource(final OrganizationSource organizationSource) {
    _organizationSource = organizationSource;
  }

  public SecurityMaster getSecurityMaster() {
    return _securityMaster;
  }

  public void setSecurityMaster(final SecurityMaster securityMaster) {
    _securityMaster = securityMaster;
  }

  public String getCurrencyCurveName() {
    return _currencyCurveName;
  }

  public void setCurrencyCurveName(final String currencyCurveName) {
    _currencyCurveName = currencyCurveName;
  }

  public String getCurveCalculationConfig(final Currency currency) {
    return _curveCalculationConfig.get(currency);
  }

  public void setCurveCalculationConfigs(final Map<Currency, String> curveCalculationConfigs) {
    _curveCalculationConfig.clear();
    _curveCalculationConfig.putAll(curveCalculationConfigs);
  }

  public void setCurveCalculationConfig(final Currency currency, final String curveCalculationConfig) {
    _curveCalculationConfig.put(currency, curveCalculationConfig);
  }

  protected CurveSpecificationBuilderConfiguration getCurrencyCurveConfig(final Currency currency) {
    final CurveSpecificationBuilderConfiguration config = getConfigSource().getSingle(CurveSpecificationBuilderConfiguration.class, getCurrencyCurveName() + "_" + currency.getCode(), null);
    return config;
  }

  public Function2<Currency, Currency, ExternalId> getSpotRateIdentifier() {
    return _spotRateIdentifier;
  }

  public void setSpotRateIdentifier(final Function2<Currency, Currency, ExternalId> spotRateIdentifier) {
    _spotRateIdentifier = spotRateIdentifier;
  }

  private FunctionExecutionContext createFunctionExecutionContext(final LocalDate valuationTime) {
    final FunctionExecutionContext context = new FunctionExecutionContext();
    context.setValuationTime(valuationTime.atTime(LocalTime.NOON).toInstant(ZoneOffset.UTC));
    context.setValuationClock(DateUtils.fixedClockUTC(context.getValuationTime()));
    context.setComputationTargetResolver(
        new DefaultComputationTargetResolver(context.getSecuritySource()).atVersionCorrection(VersionCorrection.LATEST));
    OpenGammaExecutionContext.setHolidaySource(context, getHolidaySource());
    OpenGammaExecutionContext.setRegionSource(context, getRegionSource());
    OpenGammaExecutionContext.setConventionBundleSource(context, getConventionBundleSource());
    OpenGammaExecutionContext.setConventionSource(context, getConventionSource());
    OpenGammaExecutionContext.setSecuritySource(context, new MasterSecuritySource(getSecurityMaster()));
    OpenGammaExecutionContext.setHistoricalTimeSeriesSource(context, getHistoricalSource());
    OpenGammaExecutionContext.setConfigSource(context, getConfigSource());
    OpenGammaExecutionContext.setOrganizationSource(context, getOrganizationSource());
    return context;
  }

  private FunctionCompilationContext createFunctionCompilationContext() {
    final FunctionCompilationContext context = new FunctionCompilationContext();
    OpenGammaCompilationContext.setInterpolatedYieldCurveDefinitionSource(context, new ConfigDBInterpolatedYieldCurveDefinitionSource(getConfigSource()));
    OpenGammaCompilationContext.setInterpolatedYieldCurveSpecificationBuilder(context, new ConfigDBInterpolatedYieldCurveSpecificationBuilder(getConfigSource()));
    context.setFunctionReinitializer(new DummyFunctionReinitializer());
    OpenGammaCompilationContext.setHolidaySource(context, getHolidaySource());
    OpenGammaCompilationContext.setRegionSource(context, getRegionSource());
    OpenGammaCompilationContext.setOrganizationSource(context, getOrganizationSource());
    OpenGammaCompilationContext.setConventionBundleSource(context, getConventionBundleSource());
    OpenGammaCompilationContext.setConventionSource(context, getConventionSource());
    OpenGammaCompilationContext.setSecuritySource(context, new MasterSecuritySource(getSecurityMaster()));
    OpenGammaCompilationContext.setHistoricalTimeSeriesResolver(context, new DefaultHistoricalTimeSeriesResolver(new DefaultHistoricalTimeSeriesSelector(getConfigSource()),
        getHistoricalTimeSeriesMaster()));
    final DefaultComputationTargetResolver targetResolver = new DefaultComputationTargetResolver(context.getSecuritySource());
    targetResolver.addResolver(CurrencyPairs.TYPE, new CurrencyPairsResolver(new ConfigDBCurrencyPairsSource(getConfigSource())));
    targetResolver.addResolver(CurrencyMatrixResolver.TYPE, new CurrencyMatrixResolver(new ConfigDBCurrencyMatrixSource(getConfigSource())));
    context.setRawComputationTargetResolver(targetResolver);
    context.setComputationTargetResolver(context.getRawComputationTargetResolver().atVersionCorrection(VersionCorrection.LATEST));
    OpenGammaCompilationContext.setConfigSource(context, getConfigSource());
    return context;
  }

  private CompiledFunctionDefinition createFunction(final FunctionCompilationContext compContext, final FunctionExecutionContext execContext, final AbstractFunction function) {
    function.setUniqueId(function.getClass().getSimpleName());
    function.init(compContext);
    return function.compile(compContext, execContext.getValuationTime());
  }

  private ComputedValue execute(final FunctionExecutionContext context, final CompiledFunctionDefinition function, final ComputationTarget target, final ValueRequirement output,
      final ComputedValue... inputs) {
    final FunctionInputsImpl functionInputs = new FunctionInputsImpl(context.getComputationTargetResolver().getSpecificationResolver(), Arrays.asList(inputs));
    Set<ComputedValue> results;
    try {
      results = function.getFunctionInvoker().execute(context, functionInputs, target, Collections.singleton(output));
    } catch (final AsynchronousExecution ex) {
      results = AsynchronousOperation.getResult(ex);
    }
    for (final ComputedValue result : results) {
      if (output.getValueName().equals(result.getSpecification().getValueName())) {
        return result;
      }
    }
    throw new OpenGammaRuntimeException("Function " + function + " didn't produce " + output + " from " + functionInputs);
  }

  private ComputedValue findMarketData(final ExternalIdBundleResolver resolver, final ValueRequirement requirement) {
    final ComputationTargetSpecification targetSpec = resolver.getTargetSpecification(requirement.getTargetReference());
    // TODO: What to do if the targetSpec can't be resolved. We can still get an identifier bundle, but the spec for the CV will be wrong
    final Pair<LocalDate, Double> value = getHistoricalSource().getLatestDataPoint(MarketDataRequirementNames.MARKET_VALUE, resolver.getExternalIdBundle(targetSpec), null);
    if (value == null) {
      return null;
    }
    return new ComputedValue(new ValueSpecification(requirement.getValueName(), targetSpec,
        ValueProperties.with(ValuePropertyNames.FUNCTION, "MARKET_DATA").get()), value.getSecond());
  }

  private ComputedValue[] findMarketData(final FunctionCompilationContext compilationContext, final Collection<ValueRequirement> requirements) {
    s_logger.debug("Resolving {}", requirements);
    final ExternalIdBundleResolver lookup = new ExternalIdBundleResolver(compilationContext.getComputationTargetResolver());
    final ComputedValue[] values = new ComputedValue[requirements.size()];
    int i = 0;
    for (final ValueRequirement requirement : requirements) {
      final ComputedValue value = findMarketData(lookup, requirement);
      if (value == null) {
        s_logger.debug("Couldn't resolve {}", requirement);
        return null;
      }
      values[i++] = value;
    }
    return values;
  }

  protected Double getApproxFXRate(final LocalDate date, final Pair<Currency, Currency> currencies) {
    final Currency payCurrency;
    final Currency receiveCurrency;
    if (FXUtils.isInBaseQuoteOrder(currencies.getFirst(), currencies.getSecond())) {
      payCurrency = currencies.getFirst();
      receiveCurrency = currencies.getSecond();
    } else {
      payCurrency = currencies.getSecond();
      receiveCurrency = currencies.getFirst();
    }
    final ExternalId spotRateIdentifier = getSpotRateIdentifier().execute(payCurrency, receiveCurrency);
    final Pair<LocalDate, Double> spotRate = getHistoricalSource().getLatestDataPoint(MarketDataRequirementNames.MARKET_VALUE,
        spotRateIdentifier.toBundle(), null);
    if (spotRate == null) {
      s_logger.debug("No spot rate for {}", spotRateIdentifier);
      return null;
    }
    s_logger.debug("Got spot rate {} for {}", spotRate, spotRateIdentifier);
    final FunctionExecutionContext execContext = createFunctionExecutionContext(spotRate.getFirst());
    final FunctionCompilationContext compContext = createFunctionCompilationContext();
    final CompiledFunctionDefinition payYieldCurveSpecificationFunction = createFunction(compContext, execContext, new YieldCurveSpecificationFunction(payCurrency, getCurrencyCurveName()));
    final CompiledFunctionDefinition payYieldCurveMarketDataFunction = createFunction(compContext, execContext, new YieldCurveMarketDataFunction(payCurrency, getCurrencyCurveName()));
    final CompiledFunctionDefinition receiveYieldCurveSpecificationFunction = createFunction(compContext, execContext, new YieldCurveSpecificationFunction(receiveCurrency, getCurrencyCurveName()));
    final CompiledFunctionDefinition receiveYieldCurveMarketDataFunction = createFunction(compContext, execContext, new YieldCurveMarketDataFunction(receiveCurrency, getCurrencyCurveName()));
    final CompiledFunctionDefinition yieldCurveFunction = createFunction(compContext, execContext, new MultiYieldCurvePresentValueMethodFunction());
    final CompiledFunctionDefinition fxForwardCurveFromYieldCurveFunction = createFunction(compContext, execContext, new FXForwardCurveFromYieldCurvesFunction());
    ComputationTarget target;
    // PAY
    target = new ComputationTarget(ComputationTargetType.CURRENCY, payCurrency);
    // PAY - YieldCurveMarketDataFunction
    final ComputedValue[] payCurveDataRequirements = findMarketData(compContext, payYieldCurveMarketDataFunction.getRequirements(compContext, target, null));
    if (payCurveDataRequirements == null) {
      s_logger.debug("Missing market data for curve on {}", payCurrency);
      return null;
    }
    final ComputedValue payCurveMarketData = execute(execContext, payYieldCurveMarketDataFunction, target,
        new ValueRequirement(ValueRequirementNames.YIELD_CURVE_MARKET_DATA, target.toSpecification()), payCurveDataRequirements);
    // PAY - YieldCurveSpecificationFunction
    final ComputedValue payCurveSpec = execute(execContext, payYieldCurveSpecificationFunction, target, new ValueRequirement(ValueRequirementNames.YIELD_CURVE_SPEC, target.toSpecification(),
        ValueProperties.none()), payCurveMarketData);
    // PAY - MultiYieldCurvePresentValueMethodFunction
    final ComputedValue payHtsConversion = new ComputedValue(new ValueSpecification(ValueRequirementNames.YIELD_CURVE_INSTRUMENT_CONVERSION_HISTORICAL_TIME_SERIES, target.toSpecification(),
        ValueProperties.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, getCurveCalculationConfig(payCurrency)).with(ValuePropertyNames.FUNCTION, "").get()), new HistoricalTimeSeriesBundle());
    final ComputedValue payCurve = execute(execContext, yieldCurveFunction, target, new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target.toSpecification(),
        ValueProperties
        .with(ValuePropertyNames.CURVE, getCurrencyCurveName())
        .with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, getCurveCalculationConfig(payCurrency))
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_ABSOLUTE_TOLERANCE, "0.0001")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_RELATIVE_TOLERANCE, "0.0001")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_MAX_ITERATIONS, "1000")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_DECOMPOSITION, DecompositionFactory.SV_COLT_NAME)
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_USE_FINITE_DIFFERENCE, "false")
        .get()), payCurveSpec,
        payCurveMarketData, payHtsConversion);
    // RECEIVE
    target = new ComputationTarget(ComputationTargetType.CURRENCY, receiveCurrency);
    // RECEIVE - YieldCurveMarketDataFunction
    final ComputedValue[] receiveCurveDataRequirements = findMarketData(compContext, receiveYieldCurveMarketDataFunction.getRequirements(compContext, target, null));
    if (receiveCurveDataRequirements == null) {
      s_logger.debug("Missing market data for curve on {}", receiveCurrency);
      return null;
    }
    final ComputedValue receiveCurveMarketData = execute(execContext, receiveYieldCurveMarketDataFunction, target,
        new ValueRequirement(ValueRequirementNames.YIELD_CURVE_MARKET_DATA, target.toSpecification()), receiveCurveDataRequirements);
    // RECEIVE - YieldCurveSpecificationFunction
    final ComputedValue receiveCurveSpec = execute(execContext, receiveYieldCurveSpecificationFunction, target, new ValueRequirement(ValueRequirementNames.YIELD_CURVE_SPEC, target.toSpecification(),
        ValueProperties.none()), receiveCurveMarketData);
    // RECEIVE - MultiYieldCurvePresentValueMethodFunction
    final ComputedValue receiveHtsConversion = new ComputedValue(new ValueSpecification(ValueRequirementNames.YIELD_CURVE_INSTRUMENT_CONVERSION_HISTORICAL_TIME_SERIES, target.toSpecification(),
        ValueProperties.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, getCurveCalculationConfig(receiveCurrency)).with(ValuePropertyNames.FUNCTION, "").get()), new HistoricalTimeSeriesBundle());
    final ComputedValue receiveCurve = execute(execContext, yieldCurveFunction, target, new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target.toSpecification(),
        ValueProperties
        .with(ValuePropertyNames.CURVE, getCurrencyCurveName())
        .with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, getCurveCalculationConfig(receiveCurrency))
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_ABSOLUTE_TOLERANCE, "0.0001")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_RELATIVE_TOLERANCE, "0.0001")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_MAX_ITERATIONS, "1000")
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_DECOMPOSITION, DecompositionFactory.SV_COLT_NAME)
        .with(MultiYieldCurvePropertiesAndDefaults.PROPERTY_USE_FINITE_DIFFERENCE, "false")
        .get()), receiveCurveSpec,
        receiveCurveMarketData, receiveHtsConversion);
    // FXForwardCurveFromYieldCurveFunction
    target = new ComputationTarget(ComputationTargetType.UNORDERED_CURRENCY_PAIR, UnorderedCurrencyPair.of(payCurrency, receiveCurrency));
    final ForwardCurve fxForwardCurve = (ForwardCurve) execute(
        execContext,
        fxForwardCurveFromYieldCurveFunction,
        target,
        new ValueRequirement(ValueRequirementNames.FORWARD_CURVE, target.toSpecification(), ValueProperties.with(ValuePropertyNames.CURVE, getCurrencyCurveName()).get()),
        payCurve,
        receiveCurve,
        new ComputedValue(ValueSpecification.of(ValueRequirementNames.SPOT_RATE, ComputationTargetType.PRIMITIVE,
            UniqueId.of(spotRateIdentifier.getScheme().getName(), spotRateIdentifier.getValue()),
            ValueProperties.with(ValuePropertyNames.FUNCTION, "SPOT").get()), spotRate.getSecond())).getValue();
    double rate = fxForwardCurve.getForward(Period.between(spotRate.getFirst(), date).getDays() / YEAR_LENGTH);
    if (!FXUtils.isInBaseQuoteOrder(currencies.getFirst(), currencies.getSecond())) {
      rate = 1 / rate;
    }
    s_logger.debug("Calculated rate {} for {} on {}", new Object[] {rate, currencies, date });
    return rate;
  }

  public ExternalScheme getPreferredScheme() {
    return _preferredScheme;
  }

  public void setPreferredScheme(final ExternalScheme preferredScheme) {
    _preferredScheme = preferredScheme;
  }

  public static Currency[] getDefaultCurrencies() {
    return new Currency[] {Currency.USD, Currency.GBP, Currency.EUR, Currency.JPY, Currency.CHF };
  }

  public void setCurrencies(final Currency[] currencies) {
    _currencies = currencies;
  }

  public Currency[] getCurrencies() {
    if (_currencies == null) {
      return getDefaultCurrencies();
    } else {
      return _currencies;
    }
  }

  protected Currency getRandomCurrency() {
    return getRandom(getCurrencies());
  }

  private boolean isWorkday(final DayOfWeek dow, final Currency currency) {
    // TODO: use a proper convention/holiday source
    return dow.getValue() < 6;
  }

  private boolean isHoliday(final LocalDate ldp, final Currency currency) {
    return getHolidaySource().isHoliday(ldp, currency);
  }

  /**
   * Returns the date unchanged if this is a working day, otherwise advances the date.
   *
   * @param zdt the date to consider
   * @param currency the currency identifying the holiday zone
   * @return the original or adjusted date
   */
  // TODO: replace this with a date adjuster
  protected ZonedDateTime nextWorkingDay(ZonedDateTime zdt, final Currency currency) {
    while (!isWorkday(zdt.getDayOfWeek(), currency) || isHoliday(zdt.toLocalDate(), currency)) {
      zdt = zdt.plusDays(1);
    }
    return zdt;
  }

  protected ZonedDateTime nextWorkingDay(ZonedDateTime zdt, final Currency... currencies) {
    ArgumentChecker.isTrue(currencies.length > 0, "currencies");
    do {
      for (final Currency currency : currencies) {
        if (!isWorkday(zdt.getDayOfWeek(), currency) || isHoliday(zdt.toLocalDate(), currency)) {
          zdt = zdt.plusDays(1);
          continue;
        }
      }
      return zdt;
    } while (true);
  }

  /**
   * Returns the date unchanged if this is a working day, otherwise retreats the date.
   *
   * @param zdt the date to consider
   * @param currency the currency identifying the holiday zone
   * @return the original or adjusted date
   */
  // TODO: replace this with a date adjuster
  protected ZonedDateTime previousWorkingDay(ZonedDateTime zdt, final Currency currency) {
    while (!isWorkday(zdt.getDayOfWeek(), currency) || isHoliday(zdt.toLocalDate(), currency)) {
      zdt = zdt.minusDays(1);
    }
    return zdt;
  }

  protected ZonedDateTime previousWorkingDay(ZonedDateTime zdt, final Currency... currencies) {
    ArgumentChecker.isTrue(currencies.length > 0, "currencies");
    do {
      for (final Currency currency : currencies) {
        if (!isWorkday(zdt.getDayOfWeek(), currency) || isHoliday(zdt.toLocalDate(), currency)) {
          zdt = zdt.minusDays(1);
          continue;
        }
      }
      return zdt;
    } while (true);
  }

  /**
   * Creates a new random, but reasonable, security.
   *
   * @return the new security, or null if no security can be generated
   */
  public abstract T createSecurity();

  /**
   * Creates a new random, but reasonable, trade.
   *
   * @param quantityGenerator the supplied quantity generator
   * @param securityPersister the supplied security persister
   * @param counterPartyGenerator the supplied counter party generator
   * @return the new trade, or null if no trade can be generated
   */
  public ManageableTrade createSecurityTrade(final QuantityGenerator quantityGenerator, final SecurityPersister securityPersister, final NameGenerator counterPartyGenerator) {
    ManageableTrade trade = null;
    final T security = createSecurity();
    if (security != null) {
      final ZonedDateTime tradeDate = previousWorkingDay(ZonedDateTime.now().minusDays(getRandom(30)), getRandomCurrency());
      trade = new ManageableTrade(quantityGenerator.createQuantity(), securityPersister.storeSecurity(security), tradeDate.toLocalDate(), tradeDate.toOffsetDateTime().toOffsetTime(),
          ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    }
    return trade;
  }

}
TOP

Related Classes of com.opengamma.financial.generator.SecurityGenerator

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.