Package com.opengamma.integration.copier.snapshot.reader

Source Code of com.opengamma.integration.copier.snapshot.reader.FileSnapshotReader

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

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Instant;
import org.threeten.bp.LocalDate;

import com.opengamma.core.marketdatasnapshot.CurveKey;
import com.opengamma.core.marketdatasnapshot.CurveSnapshot;
import com.opengamma.core.marketdatasnapshot.UnstructuredMarketDataSnapshot;
import com.opengamma.core.marketdatasnapshot.ValueSnapshot;
import com.opengamma.core.marketdatasnapshot.VolatilitySurfaceKey;
import com.opengamma.core.marketdatasnapshot.VolatilitySurfaceSnapshot;
import com.opengamma.core.marketdatasnapshot.YieldCurveKey;
import com.opengamma.core.marketdatasnapshot.YieldCurveSnapshot;
import com.opengamma.core.marketdatasnapshot.impl.ManageableCurveSnapshot;
import com.opengamma.core.marketdatasnapshot.impl.ManageableUnstructuredMarketDataSnapshot;
import com.opengamma.core.marketdatasnapshot.impl.ManageableVolatilitySurfaceSnapshot;
import com.opengamma.core.marketdatasnapshot.impl.ManageableYieldCurveSnapshot;
import com.opengamma.financial.analytics.volatility.surface.BloombergFXOptionVolatilitySurfaceInstrumentProvider;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.id.UniqueId;
import com.opengamma.integration.copier.sheet.reader.CsvSheetReader;
import com.opengamma.integration.copier.snapshot.SnapshotColumns;
import com.opengamma.integration.copier.snapshot.SnapshotType;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.Tenor;
import com.opengamma.util.tuple.Pair;

/**
* Reads a snapshot from an imported file
*/
public class FileSnapshotReader implements SnapshotReader {

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

  private CsvSheetReader _sheetReader;
  private Map<CurveKey, CurveSnapshot> _curves;
  private UnstructuredMarketDataSnapshot _global;
  private Map<VolatilitySurfaceKey, VolatilitySurfaceSnapshot> _surface;
  private Map<YieldCurveKey, YieldCurveSnapshot> _yieldCurve;
  private String _name;
  private String _basisName;

  public FileSnapshotReader(String filename) {
    _sheetReader = new CsvSheetReader(filename);
    iterateSheetRows();
  }

  private void iterateSheetRows() {

    _curves = new HashMap<>();
    _surface = new HashMap<>();
    _yieldCurve = new HashMap<>();

    //Temporary maps for data structures
    HashMap<String, ManageableCurveSnapshot> curvesBuilder = new HashMap<>();
    HashMap<String, Pair<YieldCurveKey, ManageableYieldCurveSnapshot>> yieldCurveBuilder = new HashMap<>();
    HashMap<String, Pair<VolatilitySurfaceKey, ManageableVolatilitySurfaceSnapshot>> surfaceBuilder = new HashMap<>();
    ManageableUnstructuredMarketDataSnapshot globalBuilder = new ManageableUnstructuredMarketDataSnapshot();

    while (true) {
      Map<String, String> currentRow = _sheetReader.loadNextRow();

      // When rows are complete create snapshot elements from temporary structures
      if (currentRow == null) {
        for (Map.Entry<String, ManageableCurveSnapshot> entry : curvesBuilder.entrySet()) {
          _curves.put(new CurveKey(entry.getKey()), entry.getValue());
        }
        for (Map.Entry<String, Pair<YieldCurveKey, ManageableYieldCurveSnapshot>> entry : yieldCurveBuilder.entrySet()) {
          _yieldCurve.put(entry.getValue().getFirst(), entry.getValue().getSecond());
        }
        for (Map.Entry<String, Pair<VolatilitySurfaceKey, ManageableVolatilitySurfaceSnapshot>> entry : surfaceBuilder.entrySet()) {
          _surface.put(entry.getValue().getFirst(), entry.getValue().getSecond());
        }
        _global = globalBuilder;
        return;
      }

      String type = currentRow.get(SnapshotColumns.TYPE.get());

      switch (SnapshotType.from(type)) {
        case NAME:
          _name = currentRow.get(SnapshotColumns.NAME.get());
          break;
        case BASIS_NAME:
          _basisName = currentRow.get(SnapshotColumns.NAME.get());
          break;
        case CURVE:
          buildCurves(curvesBuilder, currentRow);
          break;
        case YIELD_CURVE:
          buildYieldCurves(yieldCurveBuilder, currentRow);
          break;
        case GOBAL_VALUES:
          buildGlobalValues(globalBuilder, currentRow);
          break;
        case VOL_SURFACE:
          buildSurface(surfaceBuilder, currentRow);
          break;
        default:
          s_logger.error("Unknown snapshot element of type {}", type);
          break;
      }
    }
  }

  private void buildGlobalValues(ManageableUnstructuredMarketDataSnapshot globalBuilder , Map<String, String> currentRow) {
    globalBuilder.putValue(createExternalIdBundle(currentRow),
                           currentRow.get(SnapshotColumns.VALUE_NAME.get()),
                           createValueSnapshot(currentRow));
  }

  private void buildSurface(HashMap<String, Pair<VolatilitySurfaceKey, ManageableVolatilitySurfaceSnapshot>> surfaceBuilder,
                            Map<String, String> currentRow) {
    String name = currentRow.get(SnapshotColumns.NAME.get());

    if (!surfaceBuilder.containsKey(name)) {
      ManageableVolatilitySurfaceSnapshot surface = new ManageableVolatilitySurfaceSnapshot();
      VolatilitySurfaceKey key = new VolatilitySurfaceKey(UniqueId.parse(currentRow.get(SnapshotColumns.SURFACE_TARGET.get())),
                                                          currentRow.get(SnapshotColumns.NAME.get()),
                                                          currentRow.get(SnapshotColumns.SURFACE_INSTRUMENT_TYPE.get()),
                                                          currentRow.get(SnapshotColumns.SURFACE_QUOTE_TYPE.get()),
                                                          currentRow.get(SnapshotColumns.SURFACE_QUOTE_UNITS.get()));
      HashMap values = new HashMap<Pair<Object, Object>, ValueSnapshot>();

      values.put(Pair.of(currentRow.get(SnapshotColumns.SURFACE_X.get()),
                         currentRow.get(SnapshotColumns.SURFACE_Y.get())), createValueSnapshot(currentRow));
      surface.setValues(values);
      surfaceBuilder.put(name, Pair.of(key, surface));
    } else {
      surfaceBuilder.get(name).getSecond().getValues().put(createOrdinatePair(currentRow),
                                                           createValueSnapshot(currentRow));
    }

  }

  private void buildYieldCurves(HashMap<String, Pair<YieldCurveKey, ManageableYieldCurveSnapshot>> yieldCurveBuilder,
                                Map<String, String> currentRow) {
    String name = currentRow.get(SnapshotColumns.NAME.get());

    if (!yieldCurveBuilder.containsKey(name)) {
      ManageableYieldCurveSnapshot curve = new ManageableYieldCurveSnapshot();
      ManageableUnstructuredMarketDataSnapshot snapshot = new ManageableUnstructuredMarketDataSnapshot();
      YieldCurveKey key = new YieldCurveKey(Currency.of(currentRow.get(SnapshotColumns.YIELD_CURVE_CURRENCY.get())),
                                            currentRow.get(SnapshotColumns.NAME.get()));

      curve.setValuationTime(Instant.parse(currentRow.get(SnapshotColumns.INSTANT.get())));
      snapshot.putValue(createExternalIdBundle(currentRow),
                        currentRow.get(SnapshotColumns.VALUE_NAME.get()),
                        createValueSnapshot(currentRow));
      curve.setValues(snapshot);
      yieldCurveBuilder.put(name, Pair.of(key, curve));
    } else {
      yieldCurveBuilder.get(name).getSecond().getValues().putValue(createExternalIdBundle(currentRow),
                                                   currentRow.get(SnapshotColumns.VALUE_NAME.get()),
                                                   createValueSnapshot(currentRow));
    }
  }

  private void buildCurves(HashMap<String, ManageableCurveSnapshot> curvesBuilder, Map<String, String> currentRow) {
    String name = currentRow.get(SnapshotColumns.NAME.get());

    if (!curvesBuilder.containsKey(name)) {
      ManageableCurveSnapshot curve = new ManageableCurveSnapshot();
      ManageableUnstructuredMarketDataSnapshot snapshot = new ManageableUnstructuredMarketDataSnapshot();

      curve.setValuationTime(Instant.parse(currentRow.get(SnapshotColumns.INSTANT.get())));
      snapshot.putValue(createExternalIdBundle(currentRow),
                        currentRow.get(SnapshotColumns.VALUE_NAME.get()),
                        createValueSnapshot(currentRow));
      curve.setValues(snapshot);
      curvesBuilder.put(name, curve);
    } else {
      curvesBuilder.get(name).getValues().putValue(createExternalIdBundle(currentRow),
                                                   currentRow.get(SnapshotColumns.VALUE_NAME.get()),
                                                   createValueSnapshot(currentRow));
    }

  }

  private Pair<Object, Object> createOrdinatePair(Map<String, String> currentRow) {
    String x = currentRow.get(SnapshotColumns.SURFACE_X.get());
    String[] y = currentRow.get(SnapshotColumns.SURFACE_Y.get()).split("\\|");
    Object surfaceX = null;
    Object surfaceY = null;

    if (x != null) {
      if (NumberUtils.isNumber(x)) {
        surfaceX = NumberUtils.createDouble(x);
      } else {
        try {
          surfaceX = Tenor.parse(x);
        } catch (IllegalArgumentException e)  {
          s_logger.error("Volatility surface X ordinate {} should be a Double, Tenor or empty.", x);
        }
      }
    }

    if (y != null) {
      if (y.length == 1 && NumberUtils.isNumber(y[0])) {
        surfaceY = NumberUtils.createDouble(y[0]);
      } else {
        try {
          surfaceY = createYOrdinatePair(y);
        } catch (IllegalArgumentException e)  {
          s_logger.error("Volatility surface Y ordinate {} should be a Double, Pair<Number, FXVolQuoteType> or empty.", x);
        }
      }
    }

    return Pair.of(surfaceX, surfaceY);
  }

  // Bloomberg FX option volatility surface codes given a tenor, quote type (ATM, butterfly, risk reversal) and distance from ATM.
  private Pair<Number, BloombergFXOptionVolatilitySurfaceInstrumentProvider.FXVolQuoteType> createYOrdinatePair(String[] yPair) {
    Number firstElement = null;
    BloombergFXOptionVolatilitySurfaceInstrumentProvider.FXVolQuoteType secondElement = null;
    if (NumberUtils.isNumber(yPair[0])) {
      firstElement = NumberUtils.createDouble(yPair[0]);
    }
    switch (yPair[1]) {
      case "ATM":
        secondElement = BloombergFXOptionVolatilitySurfaceInstrumentProvider.FXVolQuoteType.ATM;
        break;
      case "RISK_REVERSAL":
        secondElement = BloombergFXOptionVolatilitySurfaceInstrumentProvider.FXVolQuoteType.RISK_REVERSAL;
        break;
      case "BUTTERFLY":
        secondElement = BloombergFXOptionVolatilitySurfaceInstrumentProvider.FXVolQuoteType.BUTTERFLY;
        break;
    }
    return Pair.of(firstElement, secondElement);
  }

  private ValueSnapshot createValueSnapshot(Map<String, String> currentRow) {
    String market = currentRow.get(SnapshotColumns.MARKET_VALUE.get());
    String override = currentRow.get(SnapshotColumns.OVERRIDE_VALUE.get());
    Object marketValue = null;
    Object overrideValue = null;

    // marketValue can only be Double, LocalDate or empty
    if (market != null) {
      if (NumberUtils.isNumber(market)) {
        marketValue = NumberUtils.createDouble(market);
      } else {
        try {
          marketValue = LocalDate.parse(market);
        } catch (IllegalArgumentException e)  {
          s_logger.error("Market value {} should be a Double, LocalDate or empty.", market);
        }
      }
    }

    //overrideValue can only be Double, LocalDate or empty
    if (override != null) {
      if (NumberUtils.isNumber(override)) {
        overrideValue = NumberUtils.createDouble(override);
      } else {
        try {
          overrideValue = LocalDate.parse(override);
        } catch (IllegalArgumentException e)  {
          s_logger.error("Override value {} should be a Double, LocalDate or empty.", override);
        }
      }
    }

    return new ValueSnapshot(marketValue, overrideValue);
  }

  private ExternalIdBundle createExternalIdBundle(Map<String, String> currentRow) {
    Iterable<String> iterable = Arrays.asList(currentRow.get(SnapshotColumns.ID_BUNDLE.get()).split("\\|"));
    return ExternalIdBundle.parse(iterable);
  }

  @Override
  public Map<CurveKey, CurveSnapshot> readCurves() {
    return _curves;
  }

  @Override
  public UnstructuredMarketDataSnapshot readGlobalValues() {
    return _global;
  }

  @Override
  public Map<VolatilitySurfaceKey, VolatilitySurfaceSnapshot> readVolatilitySurfaces() {
    return _surface;
  }

  @Override
  public Map<YieldCurveKey, YieldCurveSnapshot> readYieldCurves() {
    return _yieldCurve;
  }

  @Override
  public void close() {
    _sheetReader.close();
  }

  @Override
  public String getName() {
    return _name;
  }

  @Override
  public String getBasisViewName() {
    return _basisName;
  }
}
TOP

Related Classes of com.opengamma.integration.copier.snapshot.reader.FileSnapshotReader

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.