/// <summary> /// Calibration objective function: /// squared difference between black caps and Pelsser caps. /// </summary> /// <param name='x'> /// The tested [alpha, sigma] vector. /// </param> /// <returns> /// A scalar containing the sum of squared differences between /// black Caps and the Pelsser Caps. /// </returns> public double Obj(DVPLI.Vector x) { SquaredGaussianModel model = Assign(this.project, x); try { Matrix caps = this.caplet.PGSMCaplets(model, this.capMaturity, this.fwd, this.capK, this.deltaK, this.capMat); double sum = 0; for (int r = 0; r < caps.R; r++) { for (int c = 0; c < caps.C; c++) { if (this.blackCaps[r, c] != 0.0) { sum += Math.Pow(caps[r, c] - this.blackCaps[r, c], 2); } } } double penalty = 100 * PelsserConstraint(this.project, x, 50).Norm(); return(Math.Sqrt(sum / (caps.R * caps.C)) + penalty); } catch (Exception) { return(1000 * x.Norm(NormType.L2)); } }
public override double Obj(DVPLI.Vector x) { double kappa = x[0]; double theta = x[1]; double sigma = x[2]; double rho = x[3]; double v0 = x[4]; if (displayObjInfo) { Console.WriteLine("."); } var paths = SimulateScenariosMT(s0, v0, kappa, theta, sigma, rho, Math.Min(this.matBound[1], this.cpmd.Maturity[Range.End])); if (displayObjInfo) { Console.WriteLine("Average Underlying Scenario"); int Z = paths.Length; // number of time steps int J = paths[0].Length; //number of realizations. //display average path for (int z = 0; z < Z; z++) { double avg = 0; for (int j = 0; j < J; j++) { avg += paths[z][j]; } avg /= J; Console.WriteLine((z * dt) + "\t" + avg); } } double sum = 0; int count = 0; for (int i = 0; i < this.cpmd.Maturity.Length; i++) { double maturity = this.cpmd.Maturity[i]; if (maturity < matBound[0] || maturity > matBound[1]) { continue; } for (int j = 0; j < this.cpmd.Strike.Length; j++) { double strike = this.cpmd.Strike[j]; if (strike < strikeBound[0] * s0 || strike > strikeBound[1] * s0) { continue; } if (calibrateOnCallOptions) { if (this.cpmd.CallPrice[i, j] > s0 * optionThreshold) { if (cpmd.CallVolume[i, j] > 0) { double call = CallPrice(paths, strike, maturity); sum += this.callWeight[i, j] * System.Math.Pow(this.cpmd.CallPrice[i, j] - call, 2.0); count++; } } } if (calibrateOnPutOptions) { if (cpmd.PutPrice != null) { if (cpmd.PutPrice[i, j] > s0 * optionThreshold) { if (cpmd.PutVolume[i, j] > 0) { double put = PutPrice(paths, strike, maturity); sum += this.putWeight[i, j] * System.Math.Pow(cpmd.PutPrice[i, j] - put, 2.0); count++; } } } } } } double p = 0; //Frees memory for (int i = 0; i < paths.Length; i++) { paths[i].Dispose(); } if (this.useFellerPenalty) { p += this.FellerPenalty(x); } if (double.IsNaN(sum) || double.IsInfinity(sum)) { return(p + 10e5 * x.Norm()); } return(p + Math.Sqrt(sum / this.totalVolume) / s0 * 100); }