/// <summary> /// Attempts a calibration through <see cref="PelsserCappletOptimizationProblem"/> /// using caps matrices. /// </summary> /// <param name="data">The data to be used in order to perform the calibration.</param> /// <param name="settings">The parameter is not used.</param> /// <param name="controller">The controller which may be used to cancel the process.</param> /// <returns>The results of the calibration.</returns> public EstimationResult Estimate(List <object> data, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null) { InterestRateMarketData dataset = data[0] as InterestRateMarketData; MatrixMarketData normalVol = null; if (data.Count > 1) { normalVol = (MatrixMarketData)data[1]; } EstimationResult result; if ((dataset.ZRMarket == null) || (dataset.CapVolatility == null)) { result = new EstimationResult(); result.ErrorMessage = "Not enough data to calibrate.\n" + "The estimator needs a ZRMarket and a CapVolatility " + "defined inside InterestRateMarketData"; return(result); } // Backup the dates DateTime effectiveDate = DateTime.Now.Date; DateTime valuationDate = DateTime.Now.Date; if (Document.ActiveDocument != null) { effectiveDate = Document.ActiveDocument.ContractDate; valuationDate = Document.ActiveDocument.SimulationStartDate; } // Creates the Context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); Function zr = new PFunction(null); zr.VarName = "zr"; // Load the zr. double[,] zrvalue = (double[, ])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; prj.Symbols.Add(zr); var bm = BlackModelFactory(zr); if (bm is BachelierNormalModel) { (bm as BachelierNormalModel).Tenor = dataset.CapTenor; } double deltak = dataset.CapTenor; Matrix capVol = normalVol != null ? normalVol.Values:dataset.CapVolatility; Vector capMat = normalVol != null ? normalVol.RowValues: dataset.CapMaturity; Vector capK = normalVol != null ? normalVol.ColumnValues: dataset.CapRate; var preferences = settings as Fairmat.Calibration.CapVolatilityFiltering; // Matrix calculated with black. var blackCaps = new Matrix(capMat.Length, capK.Length); for (int m = 0; m < capMat.Length; m++) { for (int s = 0; s < capK.Length; s++) { bool skip = false; if (preferences != null) { if (capK[s] < preferences.MinCapRate || capK[s] > preferences.MaxCapRate || capMat[m] < preferences.MinCapMaturity || capMat[m] > preferences.MaxCapMaturity) { skip = true; } } if (capVol[m, s] == 0 || skip) { blackCaps[m, s] = 0; } else { blackCaps[m, s] = bm.Cap(capK[s], capVol[m, s], deltak, capMat[m]); } } } if (blackCaps.IsNaN()) { Console.WriteLine("Black caps matrix has non real values:"); Console.WriteLine(blackCaps); throw new Exception("Cannot calculate Black caps"); } // Maturity goes from 0 to the last item with step deltaK. Vector maturity = new Vector((int)(1.0 + capMat[capMat.Length - 1] / deltak)); for (int l = 0; l < maturity.Length; l++) { maturity[l] = deltak * l; } Vector fwd = new Vector(maturity.Length - 1); for (int i = 0; i < fwd.Length; i++) { fwd[i] = bm.Fk(maturity[i + 1], deltak); } // Creates a default Pelsser model. Pelsser.SquaredGaussianModel model = new Pelsser.SquaredGaussianModel(); model.a1 = (ModelParameter)0.014; model.sigma1 = (ModelParameter)0.001; model.zr = (ModelParameter)"@zr"; StochasticProcessExtendible iex = new StochasticProcessExtendible(prj, model); prj.Processes.AddProcess(iex); prj.Parse(); DateTime t0 = DateTime.Now; Caplet cp = new Caplet(); PelsserCappletOptimizationProblem problem = new PelsserCappletOptimizationProblem(prj, cp, maturity, fwd, capK, deltak, capMat, blackCaps); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 35; o.TargetCost = 0.0025; o.MaxIter = 10; o.Verbosity = Math.Max(1, Engine.Verbose); o.controller = controller; // Parallel evaluation is not supported for this calibration. o.Parallel = false; o.Debug = true; SolutionInfo solution = null; Vector x0 = (Vector) new double[] { 0.1, 0.1 }; solution = solver.Minimize(problem, o, x0); if (solution.errors) { return(new EstimationResult(solution.message)); } o.epsilon = 10e-7; o.h = 10e-7; o.MaxIter = 1000; o.Debug = true; o.Verbosity = Math.Max(1, Engine.Verbose); if (solution != null) { solution = solver2.Minimize(problem, o, solution.x); } else { solution = solver2.Minimize(problem, o, x0); } if (solution.errors) { return(new EstimationResult(solution.message)); } Console.WriteLine(solution); string[] names = new string[] { "alpha1", "sigma1" }; result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); result.Objects = new object[1]; result.Objects[0] = solution.obj; //result.Fit = solution.obj;//Uncomment in 1.6 // Restore the dates if (Document.ActiveDocument != null) { Document.ActiveDocument.ContractDate = effectiveDate; Document.ActiveDocument.SimulationStartDate = valuationDate; } return(result); }
/// <summary> /// Attempts a calibration through <see cref="PelsserCappletOptimizationProblem"/> /// using caps matrices. /// </summary> /// <param name="data">The data to be used in order to perform the calibration.</param> /// <param name="settings">The parameter is not used.</param> /// <param name="controller">The controller which may be used to cancel the process.</param> /// <returns>The results of the calibration.</returns> public EstimationResult Estimate(List<object> data, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null) { InterestRateMarketData dataset = data[0] as InterestRateMarketData; EstimationResult result; if ((dataset.ZRMarket == null) || (dataset.CapVolatility == null)) { result = new EstimationResult(); result.ErrorMessage = "Not enough data to calibrate.\n" + "The estimator needs a ZRMarket and a CapVolatility " + "defined inside InterestRateMarketData"; return result; } // Backup the dates DateTime effectiveDate = DateTime.Now.Date; DateTime valuationDate = DateTime.Now.Date; if (Document.ActiveDocument != null) { effectiveDate = Document.ActiveDocument.ContractDate; valuationDate = Document.ActiveDocument.SimulationStartDate; } // Creates the Context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); Function zr = new PFunction(null); zr.VarName = "zr"; // Load the zr. double[,] zrvalue = (double[,])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; prj.Symbols.Add(zr); BlackModel bm = new BlackModel(zr); double deltak = dataset.CapTenor; Matrix capVol = dataset.CapVolatility; Vector capMat = dataset.CapMaturity; Vector capK = dataset.CapRate; var preferences = settings as Fairmat.Calibration.CapVolatilityFiltering; // Matrix calculated with black. Matrix blackCaps = new Matrix(capMat.Length, capK.Length); for (int m = 0; m < capMat.Length; m++) { for (int s = 0; s < capK.Length; s++) { bool skip = false; if (preferences != null) { if (capK[s] < preferences.MinCapRate || capK[s] > preferences.MaxCapRate || capMat[m] < preferences.MinCapMaturity || capMat[m] > preferences.MaxCapMaturity) {skip = true; } } if (capVol[m, s] == 0 || skip) blackCaps[m, s] = 0; else blackCaps[m, s] = bm.Cap(capK[s], capVol[m, s], deltak, capMat[m]); } } if (blackCaps.IsNAN()) { Console.WriteLine("Black caps matrix has non real values:"); Console.WriteLine(blackCaps); throw new Exception("Cannot calculate Black caps"); } // Maturity goes from 0 to the last item with step deltaK. Vector maturity = new Vector((int)(1.0 + capMat[capMat.Length - 1] / deltak)); for (int l = 0; l < maturity.Length; l++) maturity[l] = deltak * l; Vector fwd = new Vector(maturity.Length - 1); for (int i = 0; i < fwd.Length; i++) { fwd[i] = bm.Fk(maturity[i + 1], deltak); } // Creates a default Pelsser model. Pelsser.SquaredGaussianModel model = new Pelsser.SquaredGaussianModel(); model.a1 = (ModelParameter)0.014; model.sigma1 = (ModelParameter)0.001; model.zr = (ModelParameter)"@zr"; StochasticProcessExtendible iex = new StochasticProcessExtendible(prj, model); prj.Processes.AddProcess(iex); prj.Parse(); DateTime t0 = DateTime.Now; Caplet cp = new Caplet(); PelsserCappletOptimizationProblem problem = new PelsserCappletOptimizationProblem(prj, cp, maturity, fwd, capK, deltak, capMat, blackCaps); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 35; o.TargetCost = 0.0025; o.MaxIter = 10; o.Verbosity = Math.Max(1, Engine.Verbose); o.controller = controller; // Parallel evaluation is not supported for this calibration. o.Parallel = false; o.Debug = true; SolutionInfo solution = null; Vector x0 = (Vector)new double[] { 0.1, 0.1 }; solution = solver.Minimize(problem, o, x0); if (solution.errors) return new EstimationResult(solution.message); o.epsilon = 10e-7; o.h = 10e-7; o.MaxIter = 1000; o.Debug = true; o.Verbosity = Math.Max(1, Engine.Verbose); if (solution != null) solution = solver2.Minimize(problem, o, solution.x); else solution = solver2.Minimize(problem, o, x0); if (solution.errors) return new EstimationResult(solution.message); Console.WriteLine(solution); string[] names = new string[] { "alpha1", "sigma1" }; result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); result.Objects = new object[1]; result.Objects[0] = solution.obj; //result.Fit = solution.obj;//Uncomment in 1.6 // Restore the dates if (Document.ActiveDocument != null) { Document.ActiveDocument.ContractDate = effectiveDate; Document.ActiveDocument.SimulationStartDate = valuationDate; } return result; }