/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.examples.marketdata.credit.markit;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.CharSource;
import com.opengamma.strata.basics.date.Tenor;
import com.opengamma.strata.collect.io.CsvFile;
import com.opengamma.strata.collect.io.CsvRow;
import com.opengamma.strata.market.curve.CurveName;
import com.opengamma.strata.pricer.credit.IsdaYieldCurveInputs;
import com.opengamma.strata.pricer.credit.IsdaYieldCurveInputsId;
import com.opengamma.strata.pricer.credit.IsdaYieldCurveUnderlyingType;
import com.opengamma.strata.product.credit.type.IsdaYieldCurveConvention;
/**
* Parser to load daily yield curve information provided by Markit.
* <p>
* The columns are defined as
* {@code Valuation Date,Tenor,Instrument Type,Rate,Curve Convention}.
*/
public class MarkitYieldCurveDataParser {
private static final String DATE = "Valuation Date";
private static final String TENOR = "Tenor";
private static final String INSTRUMENT = "Instrument Type";
private static final String RATE = "Rate";
private static final String CONVENTION = "Curve Convention";
/**
* Parses the specified source.
*
* @param source the source to parse
* @return the map of parsed yield curve par rates
*/
public static Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> parse(CharSource source) {
// parse the curve data
Map<IsdaYieldCurveConvention, List<Point>> curveData = Maps.newHashMap();
CsvFile csv = CsvFile.of(source, true);
for (CsvRow row : csv.rows()) {
String dateText = row.getField(DATE);
String tenorText = row.getField(TENOR);
String instrumentText = row.getField(INSTRUMENT);
String rateText = row.getField(RATE);
String conventionText = row.getField(CONVENTION);
Point point = new Point(
Tenor.parse(tenorText),
LocalDate.parse(dateText, DateTimeFormatter.ISO_LOCAL_DATE),
mapUnderlyingType(instrumentText),
Double.parseDouble(rateText));
IsdaYieldCurveConvention convention = IsdaYieldCurveConvention.of(conventionText);
List<Point> points = curveData.get(convention);
if (points == null) {
points = Lists.newArrayList();
curveData.put(convention, points);
}
points.add(point);
}
// convert the curve data into the result map
Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> result = Maps.newHashMap();
for (IsdaYieldCurveConvention convention : curveData.keySet()) {
List<Point> points = curveData.get(convention);
result.put(IsdaYieldCurveInputsId.of(convention.getCurrency()),
IsdaYieldCurveInputs.of(
CurveName.of(convention.getName()),
points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new),
points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new),
points.stream().map(s -> s.getInstrumentType()).toArray(IsdaYieldCurveUnderlyingType[]::new),
points.stream().mapToDouble(s -> s.getRate()).toArray(),
convention));
}
return result;
}
// parse the M/S instrument type flag
private static IsdaYieldCurveUnderlyingType mapUnderlyingType(String type) {
switch (type) {
case "M":
return IsdaYieldCurveUnderlyingType.ISDA_MONEY_MARKET;
case "S":
return IsdaYieldCurveUnderlyingType.ISDA_SWAP;
default:
throw new IllegalStateException("Unknown underlying type, only M or S allowed: " + type);
}
}
//-------------------------------------------------------------------------
/**
* Stores the parsed data points.
*/
private static final class Point {
private final Tenor tenor;
private final LocalDate date;
private final IsdaYieldCurveUnderlyingType instrumentType;
private final double rate;
private Point(Tenor tenor, LocalDate baseDate, IsdaYieldCurveUnderlyingType instrumentType, double rate) {
this.tenor = tenor;
this.date = baseDate.plus(tenor.getPeriod());
this.instrumentType = instrumentType;
this.rate = rate;
}
public Tenor getTenor() {
return tenor;
}
public LocalDate getDate() {
return date;
}
public IsdaYieldCurveUnderlyingType getInstrumentType() {
return instrumentType;
}
public double getRate() {
return rate;
}
}
}