protected Cube sabrCalibration(Cube marketVolCube) { List <double> optionTimes = marketVolCube.optionTimes(); List <double> swapLengths = marketVolCube.swapLengths(); List <Date> optionDates = marketVolCube.optionDates(); List <Period> swapTenors = marketVolCube.swapTenors(); Matrix alphas = new Matrix(optionTimes.Count, swapLengths.Count, 0.0); Matrix betas = new Matrix(alphas); Matrix nus = new Matrix(alphas); Matrix rhos = new Matrix(alphas); Matrix forwards = new Matrix(alphas); Matrix errors = new Matrix(alphas); Matrix maxErrors = new Matrix(alphas); Matrix endCriteria = new Matrix(alphas); List <Matrix> tmpMarketVolCube = marketVolCube.points(); List <double> strikes = new InitializedList <double>(strikeSpreads_.Count); List <double> volatilities = new InitializedList <double>(strikeSpreads_.Count); for (int j = 0; j < optionTimes.Count; j++) { for (int k = 0; k < swapLengths.Count; k++) { double atmForward = atmStrike(optionDates[j], swapTenors[k]); double shiftTmp = atmVol_.link.shift(optionTimes[j], swapLengths[k]); strikes.Clear(); volatilities.Clear(); for (int i = 0; i < nStrikes_; i++) { double strike = atmForward + strikeSpreads_[i]; if (strike + shiftTmp >= cutoffStrike_) { strikes.Add(strike); Matrix matrix = tmpMarketVolCube[i]; volatilities.Add(matrix[j, k]); } } List <double> guess = parametersGuess_.value(optionTimes[j], swapLengths[k]); SABRInterpolation sabrInterpolation = new SABRInterpolation(strikes, strikes.Count, volatilities, optionTimes[j], atmForward, guess[0], guess[1], guess[2], guess[3], isParameterFixed_[0], isParameterFixed_[1], isParameterFixed_[2], isParameterFixed_[3], vegaWeightedSmileFit_, endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_, shiftTmp, volatilityType());// shiftTmp sabrInterpolation.update(); double rmsError = sabrInterpolation.rmsError(); double maxError = sabrInterpolation.maxError(); alphas [j, k] = sabrInterpolation.alpha(); betas [j, k] = sabrInterpolation.beta(); nus [j, k] = sabrInterpolation.nu(); rhos [j, k] = sabrInterpolation.rho(); forwards [j, k] = atmForward; errors [j, k] = rmsError; maxErrors [j, k] = maxError; endCriteria[j, k] = (double)sabrInterpolation.endCriteria(); Utils.QL_REQUIRE(endCriteria[j, k].IsNotEqual((double)EndCriteria.Type.MaxIterations), () => "global swaptions calibration failed: " + "MaxIterations reached: " + "\n" + "option maturity = " + optionDates[j] + ", \n" + "swap tenor = " + swapTenors[k] + ", \n" + "error = " + (errors[j, k]) + ", \n" + "max error = " + (maxErrors[j, k]) + ", \n" + " alpha = " + alphas[j, k] + "n" + " beta = " + betas[j, k] + "\n" + " nu = " + nus[j, k] + "\n" + " rho = " + rhos[j, k] + "\n" ); Utils.QL_REQUIRE(useMaxError_ ? maxError > 0 : rmsError < maxErrorTolerance_, () => "global swaptions calibration failed: " + "option tenor " + optionDates[j] + ", swap tenor " + swapTenors[k] + (useMaxError_ ? ": max error " : ": error") + (useMaxError_ ? maxError : rmsError) + " alpha = " + alphas[j, k] + "\n" + " beta = " + betas[j, k] + "\n" + " nu = " + nus[j, k] + "\n" + " rho = " + rhos[j, k] + "\n" + (useMaxError_ ? ": error" : ": max error ") + (useMaxError_ ? rmsError : maxError) ); } } Cube sabrParametersCube = new Cube(optionDates, swapTenors, optionTimes, swapLengths, 8, true, backwardFlat_); sabrParametersCube.setLayer(0, alphas); sabrParametersCube.setLayer(1, betas); sabrParametersCube.setLayer(2, nus); sabrParametersCube.setLayer(3, rhos); sabrParametersCube.setLayer(4, forwards); sabrParametersCube.setLayer(5, errors); sabrParametersCube.setLayer(6, maxErrors); sabrParametersCube.setLayer(7, endCriteria); return(sabrParametersCube); }
public double maxError() { calculate(); return(sabrInterpolation_.maxError()); }
public void sabrCalibrationSection(Cube marketVolCube, Cube parametersCube, Period swapTenor) { List <double> optionTimes = marketVolCube.optionTimes(); List <double> swapLengths = marketVolCube.swapLengths(); List <Date> optionDates = marketVolCube.optionDates(); List <Period> swapTenors = marketVolCube.swapTenors(); int k = swapTenors.IndexOf(swapTenors.First(x => x == swapTenor)); Utils.QL_REQUIRE(k != swapTenors.Count, () => "swap tenor not found"); List <double> calibrationResult = new InitializedList <double>(8, 0.0); List <Matrix> tmpMarketVolCube = marketVolCube.points(); List <double> strikes = new List <double>(strikeSpreads_.Count); List <double> volatilities = new List <double>(strikeSpreads_.Count); for (int j = 0; j < optionTimes.Count; j++) { double atmForward = atmStrike(optionDates[j], swapTenors[k]); double shiftTmp = atmVol_.link.shift(optionTimes[j], swapLengths[k]); strikes.Clear(); volatilities.Clear(); for (int i = 0; i < nStrikes_; i++) { double strike = atmForward + strikeSpreads_[i]; if (strike + shiftTmp >= cutoffStrike_) { strikes.Add(strike); volatilities.Add(tmpMarketVolCube[i][j, k]); } } List <double> guess = parametersGuess_.value(optionTimes[j], swapLengths[k]); var sabrInterpolation = new SABRInterpolation(strikes, strikes.Count, volatilities, optionTimes[j], atmForward, guess[0], guess[1], guess[2], guess[3], isParameterFixed_[0], isParameterFixed_[1], isParameterFixed_[2], isParameterFixed_[3], vegaWeightedSmileFit_, endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_, shiftTmp, volatilityType());//shiftTmp sabrInterpolation.update(); double interpolationError = sabrInterpolation.rmsError(); calibrationResult[0] = sabrInterpolation.alpha(); calibrationResult[1] = sabrInterpolation.beta(); calibrationResult[2] = sabrInterpolation.nu(); calibrationResult[3] = sabrInterpolation.rho(); calibrationResult[4] = atmForward; calibrationResult[5] = interpolationError; calibrationResult[6] = sabrInterpolation.maxError(); calibrationResult[7] = (double)sabrInterpolation.endCriteria(); Utils.QL_REQUIRE(calibrationResult[7].IsNotEqual((double)EndCriteria.Type.MaxIterations), () => "section calibration failed: " + "option tenor " + optionDates[j] + ", swap tenor " + swapTenors[k] + ": max iteration (" + endCriteria_.maxIterations() + ")" + ", alpha " + calibrationResult[0] + ", beta " + calibrationResult[1] + ", nu " + calibrationResult[2] + ", rho " + calibrationResult[3] + ", max error " + calibrationResult[6] + ", error " + calibrationResult[5] ); Utils.QL_REQUIRE(useMaxError_ ? calibrationResult[6] > 0 : calibrationResult[5] < maxErrorTolerance_, () => "section calibration failed: " + "option tenor " + optionDates[j] + ", swap tenor " + swapTenors[k] + (useMaxError_ ? ": max error " : ": error ") + (useMaxError_ ? calibrationResult[6] : calibrationResult[5]) + ", alpha " + calibrationResult[0] + ", beta " + calibrationResult[1] + ", nu " + calibrationResult[2] + ", rho " + calibrationResult[3] + (useMaxError_ ? ": error" : ": max error ") + (useMaxError_ ? calibrationResult[5] : calibrationResult[6]) ); parametersCube.setPoint(optionDates[j], swapTenors[k], optionTimes[j], swapLengths[k], calibrationResult); parametersCube.updateInterpolators(); } }