Package com.opengamma.financial.generator

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

/**
* 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.math.BigDecimal;
import java.text.DecimalFormat;

import org.threeten.bp.ZonedDateTime;

import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.position.Counterparty;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.financial.currency.CurrencyPairs;
import com.opengamma.financial.currency.CurrencyPairsConfigPopulator;
import com.opengamma.financial.security.fx.FXForwardSecurity;
import com.opengamma.financial.security.fx.NonDeliverableFXForwardSecurity;
import com.opengamma.financial.security.option.BarrierDirection;
import com.opengamma.financial.security.option.BarrierType;
import com.opengamma.financial.security.option.EuropeanExerciseType;
import com.opengamma.financial.security.option.FXBarrierOptionSecurity;
import com.opengamma.financial.security.option.FXDigitalOptionSecurity;
import com.opengamma.financial.security.option.FXOptionSecurity;
import com.opengamma.financial.security.option.MonitoringType;
import com.opengamma.financial.security.option.NonDeliverableFXOptionSecurity;
import com.opengamma.financial.security.option.SamplingFrequency;
import com.opengamma.id.ExternalId;
import com.opengamma.master.position.ManageableTrade;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.util.i18n.Country;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.Expiry;
import com.opengamma.util.time.ExpiryAccuracy;
import com.opengamma.util.tuple.Pair;

/**
* Source of random, but reasonable, FX security instances.
*
* @param <T> the sub-type of the security
*/
public abstract class AbstractFXSecurityGenerator<T extends ManageableSecurity> extends SecurityGenerator<T> {

  private static final ExternalId REGION = ExternalSchemes.countryRegionId(Country.US);
  private static final double NOTIONAL = 100000;
  private static final DecimalFormat RATE_FORMATTER = new DecimalFormat("###.######");
  private static final DecimalFormat NOTIONAL_FORMATTER = new DecimalFormat("########.###");
  private static final Boolean[] BOOLEAN_VALUES = {Boolean.TRUE, Boolean.FALSE};
  private CurrencyPairs _currencyPairs = CurrencyPairsConfigPopulator.createCurrencyPairs();

  /**
   * Structured random information for creating the security.
   */
  protected class Bundle {

    private final boolean _long;
    private final boolean _up;
    private final Currency _firstCurrency;
    private final Currency _secondCurrency;
    private final Currency _paymentCurrency;
    private final int _daysOffset;
    private final ZonedDateTime _tradeDate;

    public Bundle() {
      _long = getRandom().nextBoolean();
      _up = getRandom().nextBoolean();
      _firstCurrency = getRandomCurrency();
      Currency secondCurrency;
      do {
        secondCurrency = getRandomCurrency();
      } while (secondCurrency == _firstCurrency);
      _secondCurrency = secondCurrency;
      _daysOffset = 100 + getRandom().nextInt(600);
      _tradeDate = previousWorkingDay(ZonedDateTime.now().minusDays(getRandom(30)), _firstCurrency, _secondCurrency);
      _paymentCurrency = getRandom().nextBoolean() ? _firstCurrency : _secondCurrency;
    }

  }

  protected Bundle createBundle() {
    return new Bundle();
  }

  protected FXBarrierOptionSecurity createFXBarrierOptionSecurity(final Bundle bundle) {
    final Currency putCurrency = bundle._firstCurrency;
    final Currency callCurrency = bundle._secondCurrency;
    final double putAmount = putCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime settlementDate = nextWorkingDay(bundle._tradeDate.plusDays(bundle._daysOffset), bundle._firstCurrency, bundle._secondCurrency);
    final Expiry expiry = new Expiry(settlementDate, ExpiryAccuracy.DAY_MONTH_YEAR);
    final Double fxRate = getApproxFXRate(settlementDate.toLocalDate(), Pair.of(bundle._firstCurrency, bundle._secondCurrency));
    if (fxRate == null) {
      return null;
    }
    final double callAmount = NOTIONAL * fxRate;
    final String dateString = settlementDate.toString(DATE_FORMATTER);
    final BarrierType barrierType = bundle._up ? BarrierType.UP : BarrierType.DOWN;
    final BarrierDirection barrierDirection = BarrierDirection.KNOCK_IN;
    final MonitoringType monitoringType = MonitoringType.CONTINUOUS;
    final SamplingFrequency samplingFrequency = SamplingFrequency.DAILY_CLOSE;
    final boolean invertBarrierLevel = !CurrencyPair.of(putCurrency, callCurrency).equals(getCurrencyPair(putCurrency, callCurrency));
    // so if UP and ccy convention order, multiple, if UP and inverted ccy order, divide, if DOWN and ccy convention order multiply, if DOWN and inverted ccy order, divide.
    final double barrierLevel = bundle._up ^ invertBarrierLevel ? fxRate * 1.5 : fxRate / 1.5;
    final FXBarrierOptionSecurity fxBarrierOptionSecurity = new FXBarrierOptionSecurity(putCurrency, callCurrency, putAmount, callAmount, expiry, settlementDate, barrierType, barrierDirection,
        monitoringType, samplingFrequency, barrierLevel, bundle._long);
    final String callAmountString = NOTIONAL_FORMATTER.format(callAmount);
    final String putAmountString = NOTIONAL_FORMATTER.format(putAmount);
    final String barrierLevelString = RATE_FORMATTER.format(barrierLevel);
    final String barrierUnitString = callCurrency + "/" + putCurrency;
    fxBarrierOptionSecurity.setName((bundle._long ? "Long " : "Short ") + (bundle._up ? "up" : "down") + " knock-in at " + barrierLevelString + " " + barrierUnitString + ", put " + putCurrency +
        " " +
        putAmountString + ", call " + callCurrency + " " + callAmountString + " on " + dateString);
    return fxBarrierOptionSecurity;
  }

  protected FXDigitalOptionSecurity createFXDigitalOptionSecurity(final Bundle bundle) {
    final Currency putCurrency = bundle._firstCurrency;
    final Currency callCurrency = bundle._secondCurrency;
    final Currency paymentCurrency = bundle._paymentCurrency;
    final double putAmount = putCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime expiry = nextWorkingDay(bundle._tradeDate.plusDays(bundle._daysOffset), putCurrency, callCurrency);
    final Double rate = getApproxFXRate(expiry.toLocalDate(), Pair.of(putCurrency, callCurrency));
    if (rate == null) {
      return null;
    }
    final double callAmount = rate * NOTIONAL;
    final ZonedDateTime settlementDate = nextWorkingDay(expiry.plusDays(2), putCurrency, callCurrency);
    final FXDigitalOptionSecurity security = new FXDigitalOptionSecurity(putCurrency, callCurrency, putAmount, callAmount, paymentCurrency, new Expiry(expiry), settlementDate, bundle._long);
    final StringBuilder sb = new StringBuilder("Digital ");
    sb.append(bundle._long ? "Long" : "Short");
    sb.append(" put ").append(putCurrency).append(' ').append(NOTIONAL_FORMATTER.format(putAmount));
    sb.append(", call ").append(callCurrency).append(' ').append(NOTIONAL_FORMATTER.format(callAmount));
    sb.append(" on ").append(expiry.toString(DATE_FORMATTER));
    security.setName(sb.toString());
    return security;
  }

  protected FXForwardSecurity createFXForwardSecurity(final Bundle bundle) {
    final double putAmount = bundle._firstCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime forwardDate = nextWorkingDay(bundle._tradeDate.plusDays(bundle._daysOffset), bundle._firstCurrency, bundle._secondCurrency);
    final Double fxRate = getApproxFXRate(forwardDate.toLocalDate(), Pair.of(bundle._firstCurrency, bundle._secondCurrency));
    if (fxRate == null) {
      return null;
    }
    final double callAmount = NOTIONAL * fxRate;
    final Currency payCurrency = bundle._long ? bundle._secondCurrency : bundle._firstCurrency;
    final Currency receiveCurrency = bundle._long ? bundle._firstCurrency : bundle._secondCurrency;
    final String dateString = forwardDate.toString(DATE_FORMATTER);
    final FXForwardSecurity fxForwardSecurity = new FXForwardSecurity(payCurrency, callAmount, receiveCurrency, putAmount, forwardDate, REGION);
    final String callAmountString = NOTIONAL_FORMATTER.format(callAmount);
    final String putAmountString = NOTIONAL_FORMATTER.format(putAmount);
    fxForwardSecurity.setName("Pay " + payCurrency + " " + callAmountString + ", receive " + receiveCurrency + " " + putAmountString + " on " + dateString);
    return fxForwardSecurity;
  }
 
  protected NonDeliverableFXForwardSecurity createNDFXForwardSecurity(final Bundle bundle) {
    final double putAmount = bundle._firstCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime forwardDate = nextWorkingDay(bundle._tradeDate.plusDays(bundle._daysOffset), bundle._firstCurrency, bundle._secondCurrency);
    final Double fxRate = getApproxFXRate(forwardDate.toLocalDate(), Pair.of(bundle._firstCurrency, bundle._secondCurrency));
    if (fxRate == null) {
      return null;
    }
    final double callAmount = NOTIONAL * fxRate;
    final Currency payCurrency = bundle._long ? bundle._secondCurrency : bundle._firstCurrency;
    final Currency receiveCurrency = bundle._long ? bundle._firstCurrency : bundle._secondCurrency;
    final String dateString = forwardDate.toString(DATE_FORMATTER);
    final NonDeliverableFXForwardSecurity security = new NonDeliverableFXForwardSecurity(payCurrency, callAmount, receiveCurrency, putAmount, forwardDate,
        REGION, getRandom(BOOLEAN_VALUES));
   
    final String callAmountString = NOTIONAL_FORMATTER.format(callAmount);
    final String putAmountString = NOTIONAL_FORMATTER.format(putAmount);
    security.setName("Pay " + payCurrency + " " + callAmountString + ", receive " + receiveCurrency + " " + putAmountString + " on " + dateString);
    return security;
  }

  protected FXOptionSecurity createFXOptionSecurity(final Bundle bundle) {
    final Currency putCurrency = bundle._firstCurrency;
    final Currency callCurrency = bundle._secondCurrency;
    final double putAmount = bundle._firstCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime settlementDate = bundle._tradeDate.plusDays(bundle._daysOffset);
    final Double fxRate = getApproxFXRate(settlementDate.toLocalDate(), Pair.of(bundle._firstCurrency, bundle._secondCurrency));
    if (fxRate == null) {
      return null;
    }
    final double callAmount = NOTIONAL * fxRate;
    final Expiry expiry = new Expiry(settlementDate, ExpiryAccuracy.DAY_MONTH_YEAR);
    final String dateString = settlementDate.toString(DATE_FORMATTER);
    final FXOptionSecurity fxOptionSecurity = new FXOptionSecurity(putCurrency, callCurrency, putAmount, callAmount, expiry, settlementDate, bundle._long, new EuropeanExerciseType());
    final String callAmountString = NOTIONAL_FORMATTER.format(callAmount);
    final String putAmountString = NOTIONAL_FORMATTER.format(putAmount);
    fxOptionSecurity.setName((bundle._long ? "Long " : "Short ") + "put " + putCurrency + " " + putAmountString + ", call " + callCurrency + " " + callAmountString + " on " + dateString);
    return fxOptionSecurity;
  }
 
  protected NonDeliverableFXOptionSecurity createNDFXOptionSecurity(final Bundle bundle) {
    final Currency putCurrency = bundle._firstCurrency;
    final Currency callCurrency = bundle._secondCurrency;
    final double putAmount = bundle._firstCurrency.equals(Currency.JPY) ? NOTIONAL * 100 : NOTIONAL;
    final ZonedDateTime settlementDate = bundle._tradeDate.plusDays(bundle._daysOffset);
    final Double fxRate = getApproxFXRate(settlementDate.toLocalDate(), Pair.of(bundle._firstCurrency, bundle._secondCurrency));
    if (fxRate == null) {
      return null;
    }
    final double callAmount = NOTIONAL * fxRate;
    final Expiry expiry = new Expiry(settlementDate, ExpiryAccuracy.DAY_MONTH_YEAR);
    final String dateString = settlementDate.toString(DATE_FORMATTER);
   
    final NonDeliverableFXOptionSecurity optionSecurity = new NonDeliverableFXOptionSecurity(putCurrency, callCurrency, putAmount, callAmount, expiry, settlementDate,
        getRandom(BOOLEAN_VALUES), new EuropeanExerciseType(), getRandom(BOOLEAN_VALUES));
   
    final String callAmountString = NOTIONAL_FORMATTER.format(callAmount);
    final String putAmountString = NOTIONAL_FORMATTER.format(putAmount);
    optionSecurity.setName((bundle._long ? "Long " : "Short ") + "put " + putCurrency + " " + putAmountString + ", call " + callCurrency + " " + callAmountString + " on " + dateString);
    return optionSecurity;
  }

  protected ManageableTrade createFXBarrierOptionSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final FXBarrierOptionSecurity security = createFXBarrierOptionSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getCallAmount());
    trade.setPremiumCurrency(security.getCallCurrency());
    return trade;
  }

  protected ManageableTrade createFXDigitalOptionSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final FXDigitalOptionSecurity security = createFXDigitalOptionSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getCallAmount());
    trade.setPremiumCurrency(security.getCallCurrency());
    return trade;
  }

  protected ManageableTrade createFXForwardSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final FXForwardSecurity security = createFXForwardSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getPayAmount());
    trade.setPremiumCurrency(security.getPayCurrency());
    return trade;
   
  }
 
  protected ManageableTrade createNDFXForwardSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final NonDeliverableFXForwardSecurity security = createNDFXForwardSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getPayAmount());
    trade.setPremiumCurrency(security.getPayCurrency());
    return trade;
  }

  protected ManageableTrade createFXOptionSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final FXOptionSecurity security = createFXOptionSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getCallAmount());
    trade.setPremiumCurrency(security.getCallCurrency());
    return trade;
  }
 
  protected ManageableTrade createNDFXOptionSecurityTrade(final Bundle bundle, final BigDecimal quantity, final SecurityPersister persister, final NameGenerator counterPartyGenerator) {
    final NonDeliverableFXOptionSecurity security = createNDFXOptionSecurity(bundle);
    if (security == null) {
      return null;
    }
    ManageableTrade trade = new ManageableTrade(quantity, persister.storeSecurity(security), bundle._tradeDate.toLocalDate(), bundle._tradeDate.toOffsetDateTime().toOffsetTime(),
        ExternalId.of(Counterparty.DEFAULT_SCHEME, counterPartyGenerator.createName()));
    trade.setPremium(security.getCallAmount());
    trade.setPremiumCurrency(security.getCallCurrency());
    return trade;
  }
 
  protected CurrencyPair getCurrencyPair(Currency ccy1, Currency ccy2) {
    return _currencyPairs.getCurrencyPair(ccy1, ccy2);
  }
 
}
TOP

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

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.