Package com.opengamma.examples.bloomberg.loader

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

/**
* Copyright (C) 2009 - 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.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.config.ConfigSource;
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.analytics.ircurve.CurveSpecificationBuilderConfiguration;
import com.opengamma.financial.convention.ConventionBundle;
import com.opengamma.financial.convention.ConventionBundleSource;
import com.opengamma.financial.convention.InMemoryConventionBundleMaster;
import com.opengamma.financial.security.swap.FixedInterestRateLeg;
import com.opengamma.financial.security.swap.FloatingInterestRateLeg;
import com.opengamma.financial.security.swap.FloatingRateType;
import com.opengamma.financial.security.swap.InterestRateNotional;
import com.opengamma.financial.security.swap.SwapLeg;
import com.opengamma.financial.security.swap.SwapSecurity;
import com.opengamma.id.ExternalId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.integration.tool.IntegrationToolContext;
import com.opengamma.master.config.impl.MasterConfigSource;
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.scripts.Scriptable;
import com.opengamma.util.GUIDGenerator;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.time.Tenor;
import com.opengamma.util.tuple.Triple;

/**
* Example code to load a very simple multicurrency swap 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.
*/
@Scriptable
public class ExampleMultiCurrencySwapPortfolioLoader extends AbstractTool<IntegrationToolContext> {

  /**
   * Logger.
   */
  private static Logger s_logger = LoggerFactory.getLogger(ExampleMultiCurrencySwapPortfolioLoader.class);

  /**
   * Size of securities in portfolio
   */
  private static final int SECURITIES_SIZE = 200;

  /**
   * The name of the portfolio.
   */
  public static final String PORTFOLIO_NAME = "Multi-currency Swap Portfolio";

  /**
   * The scheme used for an identifier which is added to each swap created from the CSV file
   */
  private static final String ID_SCHEME = "SWAP_GENERATOR";

  /**
   * Portfolio currencies
   */
  public static final Currency[] s_currencies;

  private static final Tenor[] s_tenors;

  private static final int DAYS_TRADING = 60;

  static {
    s_currencies = new Currency[]{Currency.USD, Currency.GBP, Currency.EUR, Currency.JPY, Currency.CHF};
    s_tenors = new Tenor[]{Tenor.ONE_YEAR, Tenor.TWO_YEARS, Tenor.THREE_YEARS, Tenor.FIVE_YEARS,
      Tenor.ofYears(7), Tenor.ofYears(10), Tenor.ofYears(12), Tenor.ofYears(15), Tenor.ofYears(20)};
  }

  /**
   * 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 ExampleMultiCurrencySwapPortfolioLoader().initAndRun(args, IntegrationToolContext.class);
    System.exit(0);
  }

  //-------------------------------------------------------------------------
  @Override
  protected void doRun() {
    final Collection<SwapSecurity> swaps = createRandomSwaps();
    if (swaps.size() == 0) {
      throw new OpenGammaRuntimeException("No (valid) swaps were generated.");
    }
    persistToPortfolio(swaps, PORTFOLIO_NAME);
  }

  private Collection<SwapSecurity> createRandomSwaps() {
    final Collection<SwapSecurity> swaps = new ArrayList<>();

    final SecureRandom random = new SecureRandom();

    // Currency, TradeDate, Maturity
    final List<Triple<Currency, LocalDate, Tenor>> swapsArgs = newArrayList();

    for (int i = 0; i < SECURITIES_SIZE; i++) {
      final Currency ccy = getCurrency(random);
      final LocalDate tradeDate = getTradeDate(random, ccy);
      final Tenor maturity = s_tenors[random.nextInt(s_tenors.length)];
      swapsArgs.add(Triple.of(ccy, tradeDate, maturity));
    }

    fetch(swapsArgs);

    for (final Triple<Currency, LocalDate, Tenor> swapArgs : swapsArgs) {
      SwapSecurity swap = null;
      try {
        swap = makeSwap(random, swapArgs.getFirst(), swapArgs.getSecond(), swapArgs.getThird());
      } catch (final Exception e) {
        e.printStackTrace();
      }
      if (swap != null) {
        swaps.add(swap);
      }
    }

    final StringBuilder sb = new StringBuilder();
    sb.append("Parsed ").append(swaps.size()).append(" swaps:\n");
    for (final SwapSecurity swap : swaps) {
      sb.append("\t").append(swap.getName()).append("\n");
    }
    s_logger.info(sb.toString());
    return swaps;
  }

  private void fetch(final List<Triple<Currency, LocalDate, Tenor>> swapsArgs) {
    final MasterConfigSource configSource = new MasterConfigSource(getToolContext().getConfigMaster());
    final Set<ExternalId> externalIds = newHashSet();
    for (final Triple<Currency, LocalDate, Tenor> swapArgs : swapsArgs) {
      final ExternalId swapRateForMaturityIdentifier = getSwapRateFor(configSource, swapArgs.getFirst(), swapArgs.getSecond(), swapArgs.getThird());
      externalIds.add(swapRateForMaturityIdentifier);
    }

    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 SwapSecurity makeSwap(final SecureRandom random, final Currency ccy, final LocalDate tradeDate, final Tenor maturity) {

    // get the identifier for the swap rate for the maturity we're interested in (assuming the fixed rate will be =~ swap rate)
    final Double fixedRate = getFixedRate(random, ccy, tradeDate, maturity);
    final Double notional = (double) (random.nextInt(99999) + 1) * 1000;
    final boolean isPayFixed = random.nextBoolean();

    final ConventionBundle swapConvention = getSwapConventionBundle(ccy);
    final ConventionBundle liborConvention = getLiborConventionBundle(swapConvention);

    // look up the BLOOMBERG ticker out of the bundle
    final ExternalId liborIdentifier = liborConvention.getIdentifiers().getExternalId(ExternalSchemes.BLOOMBERG_TICKER);
    if (liborIdentifier == null) {
      throw new OpenGammaRuntimeException("No bloomberg ticker set up for " + swapConvention.getName());
    }

    final ZonedDateTime tradeDateTime = tradeDate.atStartOfDay(ZoneOffset.UTC);
    final ZonedDateTime maturityDateTime = tradeDate.plus(maturity.getPeriod()).atStartOfDay(ZoneOffset.UTC);
    final String counterparty = "CParty";

    final SwapLeg fixedLeg = new FixedInterestRateLeg(swapConvention.getSwapFixedLegDayCount(),
      swapConvention.getSwapFixedLegFrequency(),
      swapConvention.getSwapFixedLegRegion(),
      swapConvention.getSwapFixedLegBusinessDayConvention(),
      new InterestRateNotional(ccy, notional),
      false, fixedRate);

    final FloatingInterestRateLeg floatingLeg = new FloatingInterestRateLeg(swapConvention.getSwapFloatingLegDayCount(),
      swapConvention.getSwapFloatingLegFrequency(),
      swapConvention.getSwapFloatingLegRegion(),
      swapConvention.getSwapFloatingLegBusinessDayConvention(),
      new InterestRateNotional(ccy, notional),
      false, ExternalId.of(liborIdentifier.getScheme().toString(), liborIdentifier.getValue()),
      FloatingRateType.IBOR);
    // look up the value on our chosen trade date
    final Double initialRate = getInitialRate(tradeDate, liborIdentifier);
    floatingLeg.setInitialFloatingRate(initialRate);

    final String fixedLegDescription = PortfolioLoaderHelper.RATE_FORMATTER.format(fixedRate);
    final String floatingLegDescription = swapConvention.getSwapFloatingLegInitialRate().getValue();
    SwapLeg payLeg;
    String payLegDescription;
    SwapLeg receiveLeg;
    String receiveLegDescription;
    if (isPayFixed) {
      payLeg = fixedLeg;
      payLegDescription = fixedLegDescription;
      receiveLeg = floatingLeg;
      receiveLegDescription = floatingLegDescription;
    } else {
      payLeg = floatingLeg;
      payLegDescription = floatingLegDescription;
      receiveLeg = fixedLeg;
      receiveLegDescription = fixedLegDescription;
    }
    final SwapSecurity swap = new SwapSecurity(tradeDateTime, tradeDateTime, maturityDateTime, counterparty, payLeg, receiveLeg);
    swap.addExternalId(ExternalId.of(ID_SCHEME, GUIDGenerator.generate().toString()));
    swap.setName("IR Swap " + ccy + " " + PortfolioLoaderHelper.NOTIONAL_FORMATTER.format(notional) + " " +
      maturityDateTime.toString(PortfolioLoaderHelper.OUTPUT_DATE_FORMATTER) + " - " + payLegDescription + " / " + receiveLegDescription);
    return swap;
  }

  private Double getFixedRate(final SecureRandom random, final Currency ccy, final LocalDate tradeDate, final Tenor maturity) {
    final HistoricalTimeSeriesSource historicalSource = getToolContext().getHistoricalTimeSeriesSource();
    final MasterConfigSource configSource = new MasterConfigSource(getToolContext().getConfigMaster());
    final ExternalId swapRateForMaturityIdentifier = getSwapRateFor(configSource, ccy, tradeDate, maturity);
    if (swapRateForMaturityIdentifier == null) {
      throw new OpenGammaRuntimeException("Couldn't get swap rate identifier for " + ccy + " [" + maturity + "]" + " from " + tradeDate);
    }

    final HistoricalTimeSeries fixedRateSeries = historicalSource.getHistoricalTimeSeries("PX_LAST",
        swapRateForMaturityIdentifier.toBundle(), HistoricalTimeSeriesRatingFieldNames.DEFAULT_CONFIG_NAME, tradeDate.minusDays(30), true, tradeDate, true);
    if (fixedRateSeries == null) {
      throw new OpenGammaRuntimeException("can't find time series for " + swapRateForMaturityIdentifier + " on " + tradeDate);
    }
    final Double fixedRate = (fixedRateSeries.getTimeSeries().getLatestValue() + random.nextDouble()) / 100d;
    return fixedRate;
  }

  private Double getInitialRate(final LocalDate tradeDate, final ExternalId liborIdentifier) {
    final HistoricalTimeSeriesSource historicalSource = getToolContext().getHistoricalTimeSeriesSource();
    final HistoricalTimeSeries initialRateSeries = historicalSource.getHistoricalTimeSeries(
      "PX_LAST", liborIdentifier.toBundle(),
      HistoricalTimeSeriesRatingFieldNames.DEFAULT_CONFIG_NAME, tradeDate.minusDays(30), true, tradeDate, true);
    if (initialRateSeries == null || initialRateSeries.getTimeSeries().isEmpty()) {
      throw new OpenGammaRuntimeException("couldn't get series for " + liborIdentifier);
    }
    return initialRateSeries.getTimeSeries().getLatestValue();
  }

  private ConventionBundle getLiborConventionBundle(final ConventionBundle swapConvention) {
    // get the convention of the identifier of the initial rate
    final ConventionBundleSource conventionSource = getToolContext().getConventionBundleSource();
    final ConventionBundle liborConvention = conventionSource.getConventionBundle(swapConvention.getSwapFloatingLegInitialRate());
    if (liborConvention == null) {
      throw new OpenGammaRuntimeException("Couldn't get libor convention for " + swapConvention.getSwapFloatingLegInitialRate());
    }
    return liborConvention;
  }

  private ConventionBundle getSwapConventionBundle(final Currency ccy) {
    final ConventionBundleSource conventionSource = getToolContext().getConventionBundleSource();
    final ConventionBundle swapConvention = conventionSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, ccy.getCode() + "_SWAP"));
    if (swapConvention == null) {
      throw new OpenGammaRuntimeException("Couldn't get swap convention for " + ccy.getCode());
    }
    return swapConvention;
  }

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

  private Currency getCurrency(final SecureRandom random) {
    final int offset = random.nextInt(s_currencies.length);
    final Currency ccy = s_currencies[offset];
    return ccy;
  }

  private static ExternalId getSwapRateFor(final ConfigSource configSource, final Currency ccy, final LocalDate tradeDate, final Tenor tenor) {
    final CurveSpecificationBuilderConfiguration curveSpecConfig = configSource.getSingle(CurveSpecificationBuilderConfiguration.class, "DEFAULT_" + ccy.getCode(), VersionCorrection.LATEST);
    if (curveSpecConfig == null) {
      throw new OpenGammaRuntimeException("No curve spec builder configuration for DEFAULT_" + ccy.getCode());
    }
    ExternalId swapSecurity;
    if (ccy.equals(Currency.USD)) {
      // Standard (i.e. matches convention) floating leg tenor for USD is 3M
      swapSecurity = curveSpecConfig.getSwap3MSecurity(tradeDate, tenor);
    } else {
      // Standard (i.e. matches convention) floating leg tenor for CHF, JPY, GBP, EUR is 6M
      swapSecurity = curveSpecConfig.getSwap6MSecurity(tradeDate, tenor);
    }
    return swapSecurity;
  }

  private void persistToPortfolio(final Collection<SwapSecurity> swaps, 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 SwapSecurity swap : swaps) {
      final SecurityDocument swapToAddDoc = new SecurityDocument();
      swapToAddDoc.setSecurity(swap);
      securityMaster.add(swapToAddDoc);
      final ManageablePosition swapPosition = new ManageablePosition(BigDecimal.ONE, swap.getExternalIdBundle());
      final PositionDocument addedDoc = positionMaster.add(new PositionDocument(swapPosition));
      rootNode.addPosition(addedDoc.getUniqueId());
    }
    portfolioMaster.add(portfolioDoc);
  }

}
TOP

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

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.