public void Go() { _initialGuess = new DenseVector(_p.NumberOfExpiries * _p.NumberOfTenors); double initialGuess = _p.AverageSwaptionImpliedVolatility; if (initialGuess == 0) { initialGuess = _p.AverageCapletImpliedVolatility; } if (initialGuess == 0) { throw new Exception("The selected time range does not include any calibration targets."); } if (_objective.ExpForm) { for (var i = 0; i < _initialGuess.Count; i++) { _initialGuess[i] = Math.Log(initialGuess) / 20; } } else { for (var i = 0; i < _initialGuess.Count; i++) { _initialGuess[i] = initialGuess; } } var sw = new StopWatch(); _objective.StartOtherThreads(); var solution = BfgsSolver.Solve(_initialGuess, _f, _g); _objective.Finished = true; sw.Stop(); TimeSpan ts = sw.GetElapsedTime(); Pedersen.Write($" Value x: {solution[0]}\n", "cal"); _objective.OutputResult(solution); Pedersen.Write($" Process Time: {ts.Hours:d2}:{ts.Minutes:d2}:{ts.Seconds:d2}:{ts.Milliseconds:d3}\n", "cal"); }
/// <summary> /// Main calibration method. /// </summary> /// <param name="timeGrid">Time discretisation</param> /// <param name="discount">Quarterly discount factors</param> /// <param name="shift">Quarterly shift values</param> /// <param name="correlation">Correlation matrix, corresponding the tenor time discretisation</param> /// <param name="targets">Caplet and swaption implied vols</param> /// <param name="parameters">Calibration settings</param> /// <param name="factors">Factors used</param> /// <param name="useCascade">Whether to apply cascade algorithm post-calibration</param> /// <param name="output"></param> /// <returns></returns> public static InterestRateVolatilities Calibrate(PedersenTimeGrid timeGrid, QuarterlyDiscounts discount, QuarterlyShifts shift, DenseMatrix correlation, CalibrationTargets targets, CalibrationSettings parameters, int factors, bool useCascade, ref string output) { #region Initialisations targets.AdjustImpliedVolsForShift(discount, shift); var swaptionWeights = new SwaptionWeights(timeGrid.MaxExpiry, timeGrid.MaxTenor); swaptionWeights.Populate(discount, shift); var volatilities = new InterestRateVolatilities(timeGrid, factors, swaptionWeights, correlation); var objective = new CalibrationObjective(targets, timeGrid, volatilities, parameters); Func <Vector <double>, double> f = objective.ObjFun; Func <Vector <double>, Vector <double> > g = objective.ObjGrad; var initialGuess = new DenseVector(timeGrid.ExpiryCount * timeGrid.TenorCount); double guessValue = targets.AverageImpliedVol(); if (guessValue == 0) { throw new Exception("The selected time range does not include any calibration targets."); } if (parameters.ExponentialForm) { for (var i = 0; i < initialGuess.Count; i++) { initialGuess[i] = Math.Log(guessValue) / 20; } } else { for (var i = 0; i < initialGuess.Count; i++) { initialGuess[i] = guessValue; } } Trace.WriteLine(String.Format("Calibration Starting...")); objective.StartOtherThreads(); var solution = BfgsSolver.Solve(initialGuess, f, g); objective.Finished = true; Trace.WriteLine($"Value at extremum: {solution}"); objective.PopulateVol(solution); objective.AverageAbsVol(); #endregion #region Cascade if (useCascade) { Trace.WriteLine(String.Format("Applying Cascade Algorithm...")); var cascade = new CascadeAlgorithm(volatilities, timeGrid, swaptionWeights, targets, parameters.CascadeParam, factors); cascade.ApplyCascade(); } #endregion #region Output output = objective.AverageAbsVol(); return(objective.ReturnVol(solution)); #endregion }
private static void CheckRosenbrock(double a, double b, double expectedMin) { var x = BfgsSolver.Solve(new DenseVector(new[] { a, b }), RosenbrockFunction.Value, RosenbrockFunction.Gradient); Numerics.Precision.AlmostEqual(expectedMin, RosenbrockFunction.Value(x), Precision); }