/** * 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; } } }