/** * 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 com.opengamma.analytics.financial.model.volatility.surface.BlackVolatilitySurfaceMoneyness; 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 BlackVolatilitySurfaceMoneynessConverter implements ResultConverter<BlackVolatilitySurfaceMoneyness> { private static final DecimalFormat LABEL_FORMAT = new DecimalFormat("##.##"); @Override public Object convertForDisplay(ResultConverterCache context, ValueSpecification valueSpec, BlackVolatilitySurfaceMoneyness 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] = LABEL_FORMAT.format(uniqueX.get(i)); for (int j = 0; j < uniqueY.size(); j++) { if (i == 0) { yLabels[j] = LABEL_FORMAT.format(uniqueY.get(j)); } 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", xLabels); result.put("ys", yLabels); result.put("surface", surface); result.put("missingValues", missingValues); } } else if (value.getSurface() instanceof FunctionalDoublesSurface) { FunctionalDoublesSurface functional = (FunctionalDoublesSurface) value.getSurface(); result.put("xCount", 20); result.put("yCount", 20); if (mode == ConversionMode.FULL) { String[] xLabels = new String[20]; String[] yLabels = new String[20]; double[][] surface = new double[20][20]; boolean[][] missingValues = new boolean[20][20]; double[] expiries = {0.1, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3., 4., 5., 6., 7., 8., 9., 10., 12., 15., 20., 30.}; for (int i = 0; i < 20; i++) { double t = expiries[i]; xLabels[i] = LABEL_FORMAT.format(t); double m = .1; for (int j = 0; j < 20; j++) { if (i == 0) { yLabels[j] = LABEL_FORMAT.format(m); } surface[j][i] = 100 * functional.getZValue(t, m); m += 0.1; } } result.put("xs", xLabels); result.put("ys", yLabels); result.put("surface", surface); result.put("missingValues", missingValues); } } result.put("axesLabel", "Strike/Fwd \\ Expiry (yr)"); return result; } @Override public Object convertForHistory(ResultConverterCache context, ValueSpecification valueSpec, BlackVolatilitySurfaceMoneyness value) { return null; } @Override public String convertToText(ResultConverterCache context, ValueSpecification valueSpec, BlackVolatilitySurfaceMoneyness value) { return "Black Volatility Surface Moneyness"; } @Override public String getFormatterName() { return "SURFACE_DATA"; } }