/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.server.conversion; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import com.opengamma.analytics.financial.model.volatility.local.LocalVolatilitySurfaceMoneyness; import com.opengamma.analytics.math.MathException; import com.opengamma.analytics.math.surface.FunctionalDoublesSurface; import com.opengamma.analytics.math.surface.InterpolatedDoublesSurface; import com.opengamma.engine.value.ValueSpecification; /** * */ public class LocalVolatilitySurfaceMoneynessConverter implements ResultConverter<LocalVolatilitySurfaceMoneyness> { private static final DecimalFormat LABEL_FORMAT = new DecimalFormat("##.##"); @Override public Object convertForDisplay(ResultConverterCache context, ValueSpecification valueSpec, LocalVolatilitySurfaceMoneyness value, ConversionMode mode) { Map<String, Object> result = new HashMap<String, Object>(); if (value.getSurface() instanceof InterpolatedDoublesSurface) { InterpolatedDoublesSurface interpolated = (InterpolatedDoublesSurface) value.getSurface(); result.put("xCount", interpolated.getXData().length); result.put("yCount", interpolated.getYData().length); if (mode == ConversionMode.FULL) { Double[] xs = interpolated.getXData(); Double[] ys = interpolated.getYData(); List<Double> uniqueX = new ArrayList<Double>(); List<Double> uniqueY = new ArrayList<Double>(); for (Double x : xs) { if (!uniqueX.contains(x)) { uniqueX.add(x); } } for (Double y : ys) { if (!uniqueY.contains(y)) { uniqueY.add(y); } } Collections.sort(uniqueX); Collections.sort(uniqueY); Object[] xLabels = new Object[uniqueX.size()]; Object[] yLabels = new Object[uniqueY.size()]; double[][] surface = new double[xs.length][ys.length]; boolean[][] missingValues = new boolean[xs.length][ys.length]; for (int i = 0; i < uniqueX.size(); i++) { xLabels[i] = uniqueX.get(i).toString(); for (int j = 0; j < uniqueY.size(); j++) { if (i == 0) { yLabels[j] = uniqueY.get(j).toString(); } try { surface[i][j] = interpolated.getZValue(uniqueX.get(i), uniqueY.get(i)); } catch (MathException e) { surface[i][j] = Double.MAX_VALUE; missingValues[i][j] = true; } } } result.put("xs", uniqueX.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); result.put("ys", uniqueY.toArray(ArrayUtils.EMPTY_STRING_ARRAY)); result.put("surface", surface); result.put("missingValues", missingValues); } } else if (value.getSurface() instanceof FunctionalDoublesSurface) { FunctionalDoublesSurface functional = (FunctionalDoublesSurface) value.getSurface(); final double[] expiries = {0.1, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 2.5, 3., 4., 5.}; final int nX = expiries.length; result.put("xCount", nX); result.put("yCount", 21); if (mode == ConversionMode.FULL) { String[] xLabels = new String[nX]; String[] yLabels = new String[21]; double[][] surface = new double[21][nX]; boolean[][] missingValues = new boolean[21][nX]; for (int i = 0; i < nX; i++) { double x = expiries[i]; xLabels[i] = LABEL_FORMAT.format(x); double y = .45; // Moneyness from 0.5 to 2.0 for (int j = 0; j < 21; j++) { y += 0.05; if (i == 0) { yLabels[j] = LABEL_FORMAT.format(y); } surface[j][i] = 100 * functional.getZValue(x, y); } } result.put("xs", xLabels); result.put("ys", yLabels); result.put("surface", surface); result.put("missingValues", missingValues); } } return result; } @Override public Object convertForHistory(ResultConverterCache context, ValueSpecification valueSpec, LocalVolatilitySurfaceMoneyness value) { return null; } @Override public String convertToText(ResultConverterCache context, ValueSpecification valueSpec, LocalVolatilitySurfaceMoneyness value) { return "Local Volatility Surface Moneyness"; } @Override public String getFormatterName() { return "SURFACE_DATA"; } }