Package com.opengamma.examples.bloomberg.loader

Source Code of com.opengamma.examples.bloomberg.loader.ExampleFxForwardPortfolioLoader

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

import static com.google.common.collect.Sets.newHashSet;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.LocalDate;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.bbg.BloombergIdentifierProvider;
import com.opengamma.bbg.loader.hts.BloombergHistoricalTimeSeriesLoader;
import com.opengamma.component.tool.AbstractTool;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.financial.security.fx.FXForwardSecurity;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.integration.tool.IntegrationToolContext;
import com.opengamma.master.historicaltimeseries.impl.HistoricalTimeSeriesRatingFieldNames;
import com.opengamma.master.portfolio.ManageablePortfolio;
import com.opengamma.master.portfolio.ManageablePortfolioNode;
import com.opengamma.master.portfolio.PortfolioDocument;
import com.opengamma.master.portfolio.PortfolioMaster;
import com.opengamma.master.position.ManageablePosition;
import com.opengamma.master.position.PositionDocument;
import com.opengamma.master.position.PositionMaster;
import com.opengamma.master.security.SecurityDocument;
import com.opengamma.master.security.SecurityMaster;
import com.opengamma.util.GUIDGenerator;
import com.opengamma.util.i18n.Country;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.UnorderedCurrencyPair;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.time.Tenor;

/**
* Example code to load a very simple FX forward portfolio.
* <p>
* This code is kept deliberately as simple as possible.
* There are no checks for the securities or portfolios already existing, so if you run it
* more than once you will get multiple copies portfolios and securities with the same names.
* It is designed to run against the HSQLDB example database.
*/
public class ExampleFxForwardPortfolioLoader extends AbstractTool<IntegrationToolContext> {
  /** The logger */
  private static final Logger s_logger = LoggerFactory.getLogger(ExampleFxForwardPortfolioLoader.class);
  /** The number of securities in this portfolio */
  private static final int SIZE = 200;
  /** The name of the portfolio */
  public static final String PORTFOLIO_NAME = "FX Forward Portfolio";
  /** The currency pairs */
  public static final UnorderedCurrencyPair[] CCYS = new UnorderedCurrencyPair[] {UnorderedCurrencyPair.of(Currency.USD, Currency.JPY)};
  /** The scheme used for an identifier */
  private static final String ID_SCHEME = "FX_FORWARD_GENERATOR";
  /** The tenors */
  private static final Tenor[] TENORS = new Tenor[] {Tenor.ONE_YEAR, Tenor.TWO_YEARS, Tenor.FIVE_YEARS, Tenor.TEN_YEARS};
  /** The region */
  private static final ExternalId REGION = ExternalSchemes.countryRegionId(Country.US);
  /** Formats the rates in the security name */
  private static final DecimalFormat FORMATTER = new DecimalFormat("##.###");

  /**
   * Main method to run the tool. No arguments are needed.
   * @param args The arguments, unused
   */
  public static void main(final String[] args) { // CSIGNORE
    new ExampleTimeSeriesRatingLoader().initAndRun(args, IntegrationToolContext.class);
    new ExampleFxForwardPortfolioLoader().initAndRun(args, IntegrationToolContext.class);
    System.exit(0);
  }

  @Override
  protected void doRun() {
    final Collection<FXForwardSecurity> fxForwards = createRandomFXForwards();
    if (fxForwards.size() == 0) {
      throw new OpenGammaRuntimeException("No valid FX forwards were generated");
    }
    persistToPortfolio(fxForwards, PORTFOLIO_NAME);
  }

  private Collection<FXForwardSecurity> createRandomFXForwards() {
    fetch(CCYS);
    final Collection<FXForwardSecurity> fxForwards = new ArrayList<>();
    final Random random = new Random(1235);
    for (int i = 0; i < SIZE; i++) {
      FXForwardSecurity fxForward = null;
      try {
        final UnorderedCurrencyPair ccys = CCYS[random.nextInt(CCYS.length)];
        final LocalDate tradeDate = getTradeDate(random, ccys.getFirstCurrency());
        final Tenor tenor = TENORS[random.nextInt(TENORS.length)];
        fxForward = makeFXForward(random, ccys, tradeDate, tenor);
      } catch (final Exception e) {
        e.printStackTrace();
      }
      if (fxForward != null) {
        fxForwards.add(fxForward);
      }
    }
    final StringBuilder sb = new StringBuilder();
    sb.append("Parsed ").append(fxForwards.size()).append(" FX forwards:\n");
    for (final FXForwardSecurity fxForward : fxForwards) {
      sb.append("\t").append(fxForward.getName()).append("\n");
    }
    s_logger.info(sb.toString());
    return fxForwards;
  }

  private void fetch(final UnorderedCurrencyPair[] ccys) {
    final Set<ExternalId> externalIds = newHashSet();
    for (final UnorderedCurrencyPair pair : ccys) {
      final List<ExternalId> tickers = getFXRateFor(pair);
      externalIds.addAll(tickers);
    }
    final BloombergHistoricalTimeSeriesLoader loader = new BloombergHistoricalTimeSeriesLoader(
      getToolContext().getHistoricalTimeSeriesMaster(),
      getToolContext().getHistoricalTimeSeriesProvider(),
      new BloombergIdentifierProvider(getToolContext().getBloombergReferenceDataProvider()));
    loader.loadTimeSeries(externalIds, "UNKNOWN", "PX_LAST", LocalDate.now().minusYears(1), LocalDate.now());
  }

  private static List<ExternalId> getFXRateFor(final UnorderedCurrencyPair ccys) {
    final Currency firstCurrency = ccys.getFirstCurrency();
    final Currency secondCurrency = ccys.getSecondCurrency();
    final List<ExternalId> tickers = new ArrayList<>();
    tickers.add(ExternalSchemes.bloombergTickerSecurityId(firstCurrency.getCode() + " Curncy"));
    tickers.add(ExternalSchemes.bloombergTickerSecurityId(secondCurrency.getCode() + " Curncy"));
    tickers.add(ExternalSchemes.bloombergTickerSecurityId(firstCurrency.getCode() + secondCurrency.getCode() + " Curncy"));
    tickers.add(ExternalSchemes.bloombergTickerSecurityId(secondCurrency.getCode() + firstCurrency.getCode() + " Curncy"));
    return tickers;
  }

  private FXForwardSecurity makeFXForward(final Random random, final UnorderedCurrencyPair ccys, final LocalDate tradeDate, final Tenor maturity) {
    final ZonedDateTime forwardDate = tradeDate.plus(maturity.getPeriod()).atStartOfDay().atZone(ZoneOffset.UTC);
    final double payAmount, receiveAmount;
    final Currency payCurrency, receiveCurrency;
    final double forwardRate;
    if (random.nextBoolean()) {
      payCurrency = ccys.getFirstCurrency();
      receiveCurrency = ccys.getSecondCurrency();
      final double spot = getSpotRate(CurrencyPair.of(payCurrency, receiveCurrency), tradeDate);
      payAmount = 10000000 * (1 + random.nextInt(10)) / 100;
      receiveAmount = payAmount * spot * (1 + random.nextDouble() / 20);
      forwardRate = payAmount / receiveAmount;
    } else {
      receiveCurrency = ccys.getFirstCurrency();
      payCurrency = ccys.getSecondCurrency();
      final double spot = getSpotRate(CurrencyPair.of(receiveCurrency, payCurrency), tradeDate);
      receiveAmount = 10000000 * (1 + random.nextInt(10)) / 100;
      payAmount = receiveAmount * spot * (1 + random.nextDouble() / 20);
      forwardRate = payAmount / receiveAmount;
    }
    final StringBuilder sb = new StringBuilder();
    sb.append(forwardDate.toLocalDate());
    sb.append(" ");
    sb.append(payCurrency);
    sb.append("/");
    sb.append(receiveCurrency);
    sb.append(" @ ");
    sb.append(FORMATTER.format(forwardRate));
    final FXForwardSecurity fxForward = new FXForwardSecurity(payCurrency, payAmount, receiveCurrency, receiveAmount, forwardDate, REGION);
    fxForward.addExternalId(ExternalId.of(ID_SCHEME, GUIDGenerator.generate().toString()));
    fxForward.setName(sb.toString());
    return fxForward;
  }

  private LocalDate getTradeDate(final Random random, final Currency ccy) {
    final HolidaySource holidaySource = getToolContext().getHolidaySource();
    LocalDate tradeDate;
    do {
      tradeDate = DateUtils.previousWeekDay().minusDays(random.nextInt(30));
    } while (holidaySource.isHoliday(tradeDate, ccy));
    return tradeDate;
  }

  private Double getSpotRate(final CurrencyPair ccys, final LocalDate tradeDate) {
    final HistoricalTimeSeriesSource historicalSource = getToolContext().getHistoricalTimeSeriesSource();
    final String ticker = ccys.getBase().getCode() + ccys.getCounter().getCode() + " Curncy";
    final ExternalIdBundle idBundle = ExternalIdBundle.of(ExternalSchemes.bloombergTickerSecurityId(ticker));
    final HistoricalTimeSeries spotSeries = historicalSource.getHistoricalTimeSeries("PX_LAST",
        idBundle, HistoricalTimeSeriesRatingFieldNames.DEFAULT_CONFIG_NAME, tradeDate.minusDays(30), true, tradeDate, true);
    if (spotSeries == null) {
      throw new OpenGammaRuntimeException("Could not get spot rate series for " + ticker);
    }
    if (spotSeries.getTimeSeries().isEmpty()) {
      throw new OpenGammaRuntimeException("Series for " + ticker + " was empty");
    }
    return spotSeries.getTimeSeries().getLatestValue();
  }

  private void persistToPortfolio(final Collection<FXForwardSecurity> fxForwards, final String portfolioName) {
    final PortfolioMaster portfolioMaster = getToolContext().getPortfolioMaster();
    final PositionMaster positionMaster = getToolContext().getPositionMaster();
    final SecurityMaster securityMaster = getToolContext().getSecurityMaster();

    final ManageablePortfolioNode rootNode = new ManageablePortfolioNode(portfolioName);
    final ManageablePortfolio portfolio = new ManageablePortfolio(portfolioName, rootNode);
    final PortfolioDocument portfolioDoc = new PortfolioDocument();
    portfolioDoc.setPortfolio(portfolio);

    for (final FXForwardSecurity fxForward : fxForwards) {
      final SecurityDocument fxForwardToAddDoc = new SecurityDocument();
      fxForwardToAddDoc.setSecurity(fxForward);
      securityMaster.add(fxForwardToAddDoc);
      final ManageablePosition fxForwardPosition = new ManageablePosition(BigDecimal.ONE, fxForward.getExternalIdBundle());
      final PositionDocument addedDoc = positionMaster.add(new PositionDocument(fxForwardPosition));
      rootNode.addPosition(addedDoc.getUniqueId());
    }
    portfolioMaster.add(portfolioDoc);
  }
}
TOP

Related Classes of com.opengamma.examples.bloomberg.loader.ExampleFxForwardPortfolioLoader

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.