/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.capletstripping.demo; import java.util.Arrays; import java.util.List; import org.testng.annotations.Test; import com.opengamma.analytics.financial.interestrate.capletstripping.CapFloor; import com.opengamma.analytics.financial.interestrate.capletstripping.CapletStrippingBootstrap; import com.opengamma.analytics.financial.interestrate.capletstripping.CapletStrippingSetup; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurface; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.math.function.Function2D; import com.opengamma.analytics.math.surface.FunctionalDoublesSurface; /** * In this demo, we fit caps at each absolute strike in turn using a bootstrap. * These separate solutions are joined together to form a volatility surface; the output is this surface * sampled on a grid (101 by 101), such that it can be plotted as an Excel surface plot (or imported into some other * visualisation tool). */ public class CapletStrippingBootstrapDemo extends CapletStrippingSetup { @Test(description = "Demo of infering a caplet volatility surface by seperate bootstapping of absolute strike quotes") public void test() { final int nSamples = 101; final MulticurveProviderDiscount yieldCurve = getYieldCurves(); final int n = getNumberOfStrikes(); final double[][] curve = new double[nSamples][n]; for (int i = 0; i < n; i++) { final List<CapFloor> caps = getCaps(i); final double[] capVols = getCapVols(i); final CapletStrippingBootstrap bootstrap = new CapletStrippingBootstrap(caps, yieldCurve); final double[] capletVols = bootstrap.capletVolsFromCapVols(capVols); final VolatilitySurface volCurve = getPiecewise(capletVols, bootstrap.getEndTimes()); for (int index = 0; index < nSamples; index++) { final double t = index * 10.0 / (nSamples - 1); curve[index][i] = volCurve.getVolatility(t, getStrikes()[i]); } } System.out.print("\n"); final double[] strikes = getStrikes(); for (int i = 0; i < n; i++) { System.out.print("\t" + strikes[i]); } System.out.print("\n"); for (int index = 0; index < nSamples; index++) { final double t = index * 10.0 / (nSamples - 1); System.out.print(t); for (int i = 0; i < n; i++) { System.out.print("\t" + curve[index][i]); } System.out.print("\n"); } } private VolatilitySurface getPiecewise(final double[] capletVols, final double[] endTimes) { final int n = capletVols.length; final Function2D<Double, Double> func = new Function2D<Double, Double>() { @Override public Double evaluate(final Double t, final Double k) { final int index = Arrays.binarySearch(endTimes, t); if (index >= 0) { if (index >= (n - 1)) { return capletVols[n - 1]; } return capletVols[index + 1]; } else if (index == -(n + 1)) { return capletVols[n - 1]; } else { return capletVols[-index - 1]; } } }; return new VolatilitySurface(FunctionalDoublesSurface.from(func)); } }