/** * Fit all the caps. Since there is some inconsistency in our data between ATM cap quotes and * those at absolute strikes (cap 'smiles' show the ATM quotes lying off a smooth curve through * the absolute strikes), we fit ATM quotes with an error of 1bps and everything else with an * error of 10bps. However, the resultant caplet volatility surface is less smooth (in the strike * direction) than that made excluding ATM. */ @Test(description = "Demo of infering a caplet volatility surface") public void globalVolFitDemo() { final double lambdaT = 0.01; // this is chosen to give a chi2/DoF of around 1 final double lambdaK = 0.0002; final List<CapFloor> allCaps = getAllCaps(); System.out.println("number of caps :" + allCaps.size()); final List<CapFloor> atmCaps = getATMCaps(); final MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(allCaps, getYieldCurves()); final CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambdaK, lambdaT); final double[] capVols = getAllCapVols(); final int n = capVols.length; final double[] errors = new double[n]; Arrays.fill(errors, 1e-3); // 10bps final int nATM = atmCaps.size(); for (int i = 0; i < nATM; i++) { final int index = allCaps.indexOf(atmCaps.get(i)); errors[index] = 1e-4; // 1bps } final DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), 0.7); final CapletStrippingResult res = stripper.solve(capVols, MarketDataType.VOL, errors, guess); System.out.println("chi2 per cap: " + res.getChiSqr() / allCaps.size()); System.out.println(res); res.printSurface(System.out, 101, 101); // res.printCapletVols(System.out); }
@Test(description = "Demo to show number of (phantom) caplets") public void sizeDemo() { final MultiCapFloorPricer pricer1 = new MultiCapFloorPricer(getAllCapsExATM(), getYieldCurves()); System.out.println("number of caplet ex ATM " + pricer1.getNumCaplets()); final MultiCapFloorPricerGrid pricer2 = new MultiCapFloorPricerGrid(getAllCaps(), getYieldCurves()); System.out.println( "number of caplet " + pricer2.getNumCaplets() + "\t" + pricer2.getGridSize()); }
/** * Fit the ATM caps only. Since there are only 7 such caps (in our data set), the resultant * 'surface' is close to a flat plane; this recovers the & cap vols and satisfies the curvature * penalties */ @Test(description = "Demo of infering a caplet volatility surface") public void atmCapsOnlyDemo() { final double lambda = 0.7; // this is chosen to give a chi2/DoF of around 1 final MultiCapFloorPricerGrid pricer = new MultiCapFloorPricerGrid(getATMCaps(), getYieldCurves()); final CapletStripperDirect stripper = new CapletStripperDirect(pricer, lambda); final double[] capVols = getATMCapVols(); final int n = capVols.length; final double[] errors = new double[n]; Arrays.fill(errors, 1e-4); // 1bps final DoubleMatrix1D guess = new DoubleMatrix1D(pricer.getGridSize(), 0.7); final CapletStrippingResult res = stripper.solve(capVols, MarketDataType.VOL, errors, guess); System.out.println(res); System.out.println("Caplet volatility surface"); res.printSurface(System.out, 101, 101); }