protected void fillVolatilityCube() { SwaptionVolatilityDiscrete atmVolStructure = atmVol_.currentLink() as SwaptionVolatilityDiscrete; List <double> atmOptionTimes = new List <double>(atmVolStructure.optionTimes()); List <double> optionTimes = new List <double>(volCubeAtmCalibrated_.optionTimes()); atmOptionTimes.InsertRange(atmOptionTimes.Count, optionTimes); atmOptionTimes.Sort(); atmOptionTimes = atmOptionTimes.Distinct().ToList <double>(); List <double> atmSwapLengths = new List <double>(atmVolStructure.swapLengths()); List <double> swapLengths = new List <double>(volCubeAtmCalibrated_.swapLengths()); atmSwapLengths.InsertRange(atmSwapLengths.Count, swapLengths); atmSwapLengths.Sort(); atmSwapLengths = atmSwapLengths.Distinct().ToList <double>(); List <Date> atmOptionDates = new List <Date>(atmVolStructure.optionDates()); List <Date> optionDates = new List <Date>(volCubeAtmCalibrated_.optionDates()); atmOptionDates.InsertRange(atmOptionDates.Count, optionDates); atmOptionDates.Sort(); atmOptionDates = atmOptionDates.Distinct().ToList <Date>(); List <Period> atmSwapTenors = new List <Period>(atmVolStructure.swapTenors()); List <Period> swapTenors = new List <Period>(volCubeAtmCalibrated_.swapTenors()); atmSwapTenors.InsertRange(atmSwapTenors.Count, swapTenors); atmSwapTenors.Sort(); atmSwapTenors = atmSwapTenors.Distinct().ToList <Period>(); createSparseSmiles(); for (int j = 0; j < atmOptionTimes.Count; j++) { for (int k = 0; k < atmSwapLengths.Count; k++) { bool expandOptionTimes = !optionTimes.Exists(x => x.IsEqual(atmOptionTimes[j])); bool expandSwapLengths = !swapLengths.Exists(x => x.IsEqual(atmSwapLengths[k])); if (expandOptionTimes || expandSwapLengths) { double atmForward = atmStrike(atmOptionDates[j], atmSwapTenors[k]); double atmVol = atmVol_.link.volatility(atmOptionDates[j], atmSwapTenors[k], atmForward); List <double> spreadVols = spreadVolInterpolation(atmOptionDates[j], atmSwapTenors[k]); List <double> volAtmCalibrated = new List <double>(nStrikes_); for (int i = 0; i < nStrikes_; i++) { volAtmCalibrated.Add(atmVol + spreadVols[i]); } volCubeAtmCalibrated_.setPoint(atmOptionDates[j], atmSwapTenors[k], atmOptionTimes[j], atmSwapLengths[k], volAtmCalibrated); } } } volCubeAtmCalibrated_.updateInterpolators(); }
public void makeCoherenceTest( string description, SwaptionVolatilityDiscrete vol) { for (int i=0; i<atm.tenors.options.Count; ++i) { Date optionDate = vol.optionDateFromTenor(atm.tenors.options[i]); if (optionDate!=vol.optionDates()[i]) Assert.Fail( "optionDateFromTenor failure for " + description+ ":"+ "\n option tenor: " + atm.tenors.options[i] + "\nactual option date : " + optionDate + "\n exp. option date : " + vol.optionDates()[i]); double optionTime = vol.timeFromReference(optionDate); if (optionTime!=vol.optionTimes()[i]) Assert.Fail( "timeFromReference failure for " + description + ":"+ "\n option tenor: " +atm.tenors.options[i] + "\n option date : " + optionDate + "\nactual option time : " + optionTime + "\n exp. option time : " +vol.optionTimes()[i]); } BlackSwaptionEngine engine=new BlackSwaptionEngine( termStructure, new Handle<SwaptionVolatilityStructure>(vol)); for (int j=0; j<atm.tenors.swaps.Count; j++) { double swapLength = vol.swapLength(atm.tenors.swaps[j]); if (swapLength!= atm.tenors.swaps[j].length()) Assert.Fail("convertSwapTenor failure for " + description + ":"+ "\n swap tenor : " + atm.tenors.swaps[j] + "\n actual swap length: " + swapLength + "\n exp. swap length: " + atm.tenors.swaps[j].length()); SwapIndex swapIndex = new EuriborSwapIsdaFixA(atm.tenors.swaps[j], termStructure); for (int i=0; i<atm.tenors.options.Count; ++i) { double error, tolerance = 1.0e-16; double actVol, expVol = atm.vols[i,j]; actVol = vol.volatility(atm.tenors.options[i], atm.tenors.swaps[j], 0.05, true); error = Math.Abs(expVol-actVol); if (error>tolerance) Assert.Fail( "recovery of atm vols failed for " + description + ":"+ "\noption tenor = " + atm.tenors.options[i] + "\n swap length = " + atm.tenors.swaps[j] + "\nexpected vol = " + expVol + "\n actual vol = " + actVol + "\n error = " + error + "\n tolerance = " + tolerance); Date optionDate = vol.optionDateFromTenor(atm.tenors.options[i]); actVol = vol.volatility(optionDate, atm.tenors.swaps[j], 0.05, true); error = Math.Abs(expVol-actVol); if (error>tolerance) Assert.Fail( "recovery of atm vols failed for " + description + ":"+ "\noption tenor: " + atm.tenors.options[i] + "\noption date : " + optionDate + "\n swap tenor: " + atm.tenors.swaps[j] + "\n exp. vol: " + expVol + "\n actual vol: " + actVol + "\n error: " + error + "\n tolerance: " + tolerance); double optionTime = vol.timeFromReference(optionDate); actVol = vol.volatility(optionTime, swapLength, 0.05, true); error = Math.Abs(expVol-actVol); if (error>tolerance) Assert.Fail( "recovery of atm vols failed for " + description + ":"+ "\noption tenor: " + atm.tenors.options[i] + "\noption time : " + optionTime + "\n swap tenor: " + atm.tenors.swaps[j] + "\n swap length: " + swapLength + "\n exp. vol: " + expVol + "\n actual vol: " + actVol + "\n error: " + error + "\n tolerance: " + tolerance); // ATM swaption Swaption swaption = new MakeSwaption( swapIndex, atm.tenors.options[i]) .withPricingEngine(engine) .value(); ; Date exerciseDate = swaption.exercise().dates().First(); if (exerciseDate!=vol.optionDates()[i]) Assert.Fail( "optionDateFromTenor mismatch for " + description + ":"+ "\n option tenor: " + atm.tenors.options[i] + "\nactual option date: " + exerciseDate + "\n exp. option date: " + vol.optionDates()[i]); Date start = swaption.underlyingSwap().startDate(); Date end = swaption.underlyingSwap().maturityDate(); double swapLength2 = vol.swapLength(start, end); if (swapLength2!=swapLength) Assert.Fail( "swapLength failure for " + description + ":"+ "\n swap tenor : " + atm.tenors.swaps[j] + "\n actual swap length: " + swapLength2 + "\n exp. swap length: " + swapLength); double npv = swaption.NPV(); actVol = swaption.impliedVolatility(npv, termStructure, expVol*0.98, 1e-6); error = Math.Abs(expVol-actVol); double tolerance2 = 0.000001; if (error > tolerance2 & i != 0)//NOK for i=0 -> to debug Assert.Fail( "recovery of atm vols through BlackSwaptionEngine failed for " + description + ":"+ "\noption tenor: " + atm.tenors.options[i] + "\noption time : " + optionTime + "\n swap tenor: " + atm.tenors.swaps[j] + "\n swap length: " + swapLength + "\n exp. vol: " + expVol + "\n actual vol: " + actVol + "\n error: " + error + "\n tolerance: " + tolerance2); } } }