public void makeVolSpreadsTest(SwaptionVolatilityCube volCube, double tolerance) { for (int i = 0; i < cube.tenors.options.Count; i++) { for (int j = 0; j < cube.tenors.swaps.Count; j++) { for (int k = 0; k < cube.strikeSpreads.Count; k++) { double atmStrike = volCube.atmStrike(cube.tenors.options[i], cube.tenors.swaps[j]); double atmVol = atmVolMatrix.link.volatility(cube.tenors.options[i], cube.tenors.swaps[j], atmStrike, true); double vol = volCube.volatility(cube.tenors.options[i], cube.tenors.swaps[j], atmStrike + cube.strikeSpreads[k], true); double spread = vol - atmVol; double expVolSpread = cube.volSpreads[i * cube.tenors.swaps.Count + j, k]; double error = Math.Abs(expVolSpread - spread); if (error > tolerance) { QAssert.Fail("\nrecovery of smile vol spreads failed:" + "\n option tenor = " + cube.tenors.options[i] + "\n swap tenor = " + cube.tenors.swaps[j] + "\n atm strike = " + atmStrike + "\n strike spread = " + cube.strikeSpreads[k] + "\n atm vol = " + atmVol + "\n smiled vol = " + vol + "\n vol spread = " + spread + "\n exp. vol spread = " + expVolSpread + "\n error = " + error + "\n tolerance = " + tolerance); } } } } }
// cleanup //public SavedSettings backup = new SavedSettings(); // utilities public void makeAtmVolTest(SwaptionVolatilityCube volCube, double tolerance) { for (int i = 0; i < atm.tenors.options.Count; i++) { for (int j = 0; j < atm.tenors.swaps.Count; j++) { double strike = volCube.atmStrike(atm.tenors.options[i], atm.tenors.swaps[j]); double expVol = atmVolMatrix.link.volatility(atm.tenors.options[i], atm.tenors.swaps[j], strike, true); double actVol = volCube.volatility(atm.tenors.options[i], atm.tenors.swaps[j], strike, true); double error = Math.Abs(expVol - actVol); if (error > tolerance) { QAssert.Fail("recovery of atm vols failed:" + "\nexpiry time = " + atm.tenors.options[i] + "\nswap length = " + atm.tenors.swaps[j] + "\n atm strike = " + strike + "\n exp. vol = " + expVol + "\n actual vol = " + actVol + "\n error = " + error + "\n tolerance = " + tolerance); } } } }