/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.fixedincome; import java.util.List; import com.bethecoder.table.AsciiTableInstance; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.opengamma.util.money.CurrencyAmount; /** * Helper class for formatting cashflow results. */ public final class CashFlowFormatter { private static final ImmutableList<String> FIXED_HEADERS = ImmutableList.of( "currency", "start accrual date", "end accrual date", "df", "payment date", "payment amount", "present value", "notional", "fixed rate"); private static final ImmutableList<String> FLOAT_HEADERS = ImmutableList.of( "currency", "start accrual date", "end accrual date", "fixing year fraction", "df", "payment date", "payment amount", "present value", "notional", "rate"); private static final String N_A = "n/a"; private final Formatter _formatter; private CashFlowFormatter(Formatter formatter) { _formatter = formatter; } /** * A formatter which formats results as a CSV. * * @return a csv result formatter */ public static CashFlowFormatter csvFormatter() { return new CashFlowFormatter(new CsvTableFormatter()); } /** * A formatter which formats results as an ascii table. * * @return an ascii table result formatter */ public static CashFlowFormatter asciiFormatter() { return new CashFlowFormatter(new AsciiTableFormatter()); } /** * Output trade cashflows as an ascii table (1 table per set of cashflows) * * @param results sequence of cashflows * @return the formatted cashflows */ public String formatSwapCashflows(Iterable<SwapLegCashFlows> results) { StringBuilder sb = new StringBuilder(); for (SwapLegCashFlows value : results) { if (value instanceof FixedLegCashFlows) { FixedLegCashFlows fixedLegCashFlows = (FixedLegCashFlows) value; List<List<String>> rows = Lists.newArrayList(); for (int k = 0; k < fixedLegCashFlows.getNumberOfCashFlows(); k++) { FixedCashFlowDetails flowDetails = fixedLegCashFlows.getCashFlowDetails().get(k); String df = String.valueOf(flowDetails.getDf() != null ? flowDetails.getDf() : N_A); String rate = String.valueOf(flowDetails.getRate() != null ? flowDetails.getRate() : N_A); List<String> row = ImmutableList.of(flowDetails.getNotional().getCurrency().toString(), flowDetails.getAccrualStartDate().toString(), flowDetails.getAccrualEndDate().toString(), df, flowDetails.getPaymentDate().toString(), caToString(flowDetails.getProjectedAmount()), caToString(flowDetails.getPresentValue()), caToString(flowDetails.getNotional()), rate); rows.add(row); } sb.append(_formatter.format(FIXED_HEADERS, rows)); } else if (value instanceof FloatingLegCashFlows) { FloatingLegCashFlows legCashFlows = (FloatingLegCashFlows) value; List<List<String>> rows = Lists.newArrayList(); for (int k = 0; k < legCashFlows.getNumberOfCashFlows(); k++) { FloatingCashFlowDetails flowDetails = legCashFlows.getCashFlowDetails().get(k); // rate can be missing if for instance we have a compounded period containing multiple sub periods String rate = String.valueOf(flowDetails.getFixedRate() != null ? flowDetails.getFixedRate() : flowDetails.getForwardRate() != null ? flowDetails.getForwardRate() : N_A); String df = String.valueOf(flowDetails.getDf() != null ? flowDetails.getDf() : N_A); rows.add(ImmutableList.of(flowDetails.getNotional().getCurrency().toString(), flowDetails.getAccrualStartDate().toString(), flowDetails.getAccrualEndDate().toString(), String.valueOf(flowDetails.getFixingYearFrac()), df, flowDetails.getPaymentDate().toString(), caToString(flowDetails.getProjectedAmount()), caToString(flowDetails.getPresentValue()), caToString(flowDetails.getNotional()), rate)); } sb.append(_formatter.format(FLOAT_HEADERS, rows)); } } return sb.toString(); } private interface Formatter { String format(List<String> headers, List<List<String>> rows); } private static class AsciiTableFormatter implements Formatter { @Override public String format(List<String> headers, List<List<String>> rows) { String[][] arrayTable = new String[rows.size()][]; for (int i = 0; i < rows.size(); i++) { arrayTable[i] = rows.get(i).toArray(new String[headers.size()]); } return AsciiTableInstance.get().getTable(headers.toArray(new String[headers.size()]), arrayTable); } } private static class CsvTableFormatter implements Formatter { @Override public String format(List<String> headers, List<List<String>> rows) { List<String> outputRows = Lists.newArrayList(); outputRows.add(Joiner.on(",").join(headers)); for (List<String> row : rows) { outputRows.add(Joiner.on(",").join(row)); } return Joiner.on("\n").join(outputRows) + "\n"; } } private String caToString(CurrencyAmount ca) { if (ca == null) { return N_A; } return Double.toString(ca.getAmount()); } }