com.opengamma.strata.pricer.impl.credit.isda.IsdaModelDatasetsSheetReader.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.strata.pricer.impl.credit.isda.IsdaModelDatasetsSheetReader.java

Source

/**
 * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.strata.pricer.impl.credit.isda;

import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.io.CsvFile;
import com.opengamma.strata.collect.io.CsvRow;

/**
 * Simple class to read in a csv file with ISDA inputs load them into a test harness
 *
 * Could extend in a more generic way but left simple for now.
 */
public class IsdaModelDatasetsSheetReader extends IsdaModelDatasets {

    private static final String SHEET_LOCATION = "isda_comparison_sheets/";
    private final List<ISDA_Results> results = new ArrayList<>(100); // ~100 rows nominally
    private CsvFile csvFile;
    private String[] headers;

    // header fields we expect in the file (lowercased when loaded)
    private static final String TODAY_HEADER = "today";
    @SuppressWarnings("unused")
    private static final String CURVE_INSTRUMENT_START_DATE = "curve instrument start date";
    private static final String START_DATE_HEADER = "start date";
    private static final String END_DATE_HEADER = "end date";
    private static final String SPREAD_HEADER = "spread";
    @SuppressWarnings("unused")
    private static final String CLEAN_PRICE_HEADER = "clean price";
    @SuppressWarnings("unused")
    private static final String CLEAN_PRICE_NOACC_HEADER = "clean price (no acc on default)";
    @SuppressWarnings("unused")
    private static final String DIRTY_PRICE_NOACC_HEADER = "dirty price (no acc on default)";
    private static final String PREMIUM_LEG_HEADER = "premium leg";
    private static final String PROTECTION_LEG_HEADER = "protection leg";
    private static final String DEFAULT_ACC_HEADER = "default acc";
    private static final String ACC_PREMIUM_HEADER = "accrued premium";
    private static final String ACC_DAYS_HEADER = "accrued days";

    private static final DateTimeFormatter DATE_TIME_PARSER = DateTimeFormatter.ofPattern("dd-MMM-uu",
            Locale.ENGLISH);

    // component parts of the resultant ISDA_Results instances
    private LocalDate[] _parSpreadDates; // assume in ascending order
    private ZonedDateTime[] _curveTenors;

    /**
     * Load specified sheet.
     *
     * @param sheetName the sheet name
     *  @param recoveryRate the recovery rate 
     * @return at set of ISDA results
     */
    public static ISDA_Results[] loadSheet(final String sheetName, final double recoveryRate) {
        return new IsdaModelDatasetsSheetReader(sheetName, recoveryRate).getResults();
    }

    /**
     * Load specified sheet.
     *
     * @param sheetName the sheet name
     * @param recoveryRate the recovery rate 
     */
    public IsdaModelDatasetsSheetReader(final String sheetName, final double recoveryRate) {
        ArgChecker.notEmpty(sheetName, "filename");

        // Set up CSV reader
        String sheetFilePath = SHEET_LOCATION + sheetName;
        URL resource = IsdaModelDatasetsSheetReader.class.getClassLoader().getResource(sheetFilePath);
        if (resource == null) {
            throw new IllegalArgumentException(sheetFilePath + ": does not exist");
        }
        csvFile = CsvFile.of(Resources.asCharSource(resource, StandardCharsets.UTF_8), true);

        // Set columns
        headers = readHeaderRow();

        for (CsvRow row : csvFile.rows()) {
            ISDA_Results temp = getResult(parseRow(row));
            temp.recoveryRate = recoveryRate;
            results.add(temp);
        }
    }

    private ISDA_Results getResult(Map<String, String> fields) {
        final ISDA_Results result = new ISDA_Results();

        result.today = getLocalDate(TODAY_HEADER, fields);
        result.startDate = getLocalDate(START_DATE_HEADER, fields);
        result.endDate = getLocalDate(END_DATE_HEADER, fields);
        result.protectionLeg = getDouble(PROTECTION_LEG_HEADER, fields);
        result.premiumLeg = getDouble(PREMIUM_LEG_HEADER, fields);
        result.defaultAcc = getDouble(DEFAULT_ACC_HEADER, fields);
        result.accruedPremium = getDouble(ACC_PREMIUM_HEADER, fields);
        result.accruedDays = new Double(getDouble(ACC_DAYS_HEADER, fields)).intValue();
        result.fracSpread = getDouble(SPREAD_HEADER, fields) / 10000;

        result.creditCurve = getCreditCurve(fields, result.today);

        return result;

    }

    private double getDouble(final String field, final Map<String, String> fields) {
        if (fields.containsKey(field)) {
            return Double.valueOf(fields.get(field));
        }
        throw new IllegalArgumentException(field + " not present in sheet row, got " + fields);
    }

    private LocalDate getLocalDate(final String field, final Map<String, String> fields) {
        if (fields.containsKey(field)) {
            return LocalDate.parse(fields.get(field), DATE_TIME_PARSER);
        }
        throw new IllegalArgumentException(field + " not present in sheet row, got " + fields);
    }

    private IsdaCompliantDateCreditCurve getCreditCurve(final Map<String, String> fields, final LocalDate today) {
        // load the curve dates from the inputs
        final int nCurvePoints = _parSpreadDates.length;
        final double[] negLogP = new double[nCurvePoints];
        for (int i = 0; i < nCurvePoints; i++) {
            negLogP[i] = getDouble(_parSpreadDates[i].format(DATE_TIME_PARSER), fields);
        }

        final double[] t = new double[nCurvePoints];
        final double[] r = new double[nCurvePoints];
        for (int j = 0; j < nCurvePoints; j++) {
            t[j] = ACT365.yearFraction(today, _parSpreadDates[j]);
            r[j] = negLogP[j] / t[j];
        }
        return new IsdaCompliantDateCreditCurve(today, _parSpreadDates, r, ACT365);
    }

    public ISDA_Results[] getResults() {
        return results.toArray(new ISDA_Results[results.size()]);
    }

    private String[] readHeaderRow() {
        // Read in the header row
        ImmutableList<String> rawRow = csvFile.headers();
        final List<LocalDate> parSpreadDates = new ArrayList<>();

        // Normalise read-in headers (to lower case) and set as columns
        String[] columns = new String[rawRow.size()];
        for (int i = 0; i < rawRow.size(); i++) {
            columns[i] = rawRow.get(i).trim();

            // if a date add to list of spread dates
            try {
                final LocalDate date = LocalDate.parse(columns[i], DATE_TIME_PARSER);
                parSpreadDates.add(date);
                continue;
            } catch (Exception ex) {
                columns[i] = columns[i].toLowerCase(Locale.ENGLISH); // lowercase non dates
            }
        }
        _parSpreadDates = parSpreadDates.toArray(new LocalDate[parSpreadDates.size()]);
        _curveTenors = new ZonedDateTime[_parSpreadDates.length];
        for (int j = 0; j < _parSpreadDates.length; j++) {
            _curveTenors[j] = ZonedDateTime.of(_parSpreadDates[j], LOCAL_TIME, TIME_ZONE);
        }
        ArgChecker.notEmpty(_parSpreadDates, "par spread dates");
        ArgChecker.notEmpty(_curveTenors, "curve tenors");
        return columns;
    }

    // map row onto expected columns
    private Map<String, String> parseRow(CsvRow rawRow) {
        Map<String, String> result = new HashMap<>();
        for (int i = 0; i < headers.length; i++) {
            if (i >= rawRow.fieldCount()) {
                break;
            }
            if (rawRow.field(i) != null && rawRow.field(i).trim().length() > 0) {
                result.put(headers[i], rawRow.field(i));
            }
        }
        return result;
    }

}