HWCompactSimulator f = new HWCompactSimulator();// { a = x[0], sigma = x[1], zr = hw1Caps.zeroRateCurve }; /// <summary> /// Calibration objective function: /// squared difference between black caps and hw caps. /// </summary> /// <param name='x'> /// The tested [alpha, sigma] vector. /// </param> /// <returns> /// A double containing the squared difference between /// black Caps and the HW Caps. /// </returns> public double Obj(DVPLI.Vector x) { Matrix hwCapsMatrix = this.hw1Caps.HWMatrixCaps(this.capMaturity, this.capRate, x[0], x[1], this.deltaK); double sum = 0; for (int r = 0; r < hwCapsMatrix.R; r++) { for (int c = 0; c < hwCapsMatrix.C; c++) { if (this.blackCaps[r, c] != 0.0) { sum += Math.Pow(hwCapsMatrix[r, c] - this.blackCaps[r, c], 2); } } } double bias = 0; /* * f.zr = hw1Caps.zeroRateCurve; * f.a = x[0]; * f.sigma = x[1]; * List<double> simDates, fR, avgR; * f.Simulate(40, out simDates, out fR, out avgR); * //double bias=f.ExpectedAverageRate(50) - hw1Caps.zeroRateCurve.Evaluate(50); * * for (int z = 0; z < simDates.Count; z++) * bias += Math.Abs(avgR[z] - hw1Caps.zeroRateCurve.Evaluate(simDates[z])); * Console.WriteLine(bias); */ double k = 25000; return(Math.Sqrt(sum) + k * bias); }
/// <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)); } }
/// <summary> /// Creates a representation of the Pelsser constraints. /// </summary> /// <remarks> /// The method is static in order to be used by other classes. /// </remarks> /// <param name="project">The project where to evaluate the constraints.</param> /// <param name="x">The vector of x values.</param> /// <param name="maturity">The cap maturity to use to evaluate the constraints.</param> /// <returns> /// A vector with the representation of the Pelsser constraints. /// </returns> public static DVPLI.Vector PelsserConstraint(ProjectROV project, DVPLI.Vector x, double maturity) { // This is modeled as a one-dimensional bound. SquaredGaussianModel model = Assign(project, x); Vector res = new Vector(1); double dt = 1.0 / (252); for (double t = 0; t <= maturity; t += dt) { res[0] += Math.Max(0, -model.F2(t, dt)); // The square of F. } /* * dt = .1317; * for (double t = 0; t <= 2; t += dt) * res[0] +=Math.Max(0,-model.F2(t, dt)); // The square of F. * * * dt = .25; * for (double t = 0; t <= 2; t += dt) * res[0] +=Math.Max(0,-model.F2(t, dt)); // The square of F. */ return(res); }
public ZeroRateFunction(DateTime refDate, DVPLI.Vector x, DVPLI.Vector y) : base(new ActualActual()) { this.date = new Date(refDate); DVPLDOM.PFunction pf = new PFunction(null); double[,] zrvalue = (double[, ])ArrayHelper.Concat(x.ToArray(), y.ToArray()); pf.Expr = zrvalue; this.function = pf; this.maxT = x.Max() + 130;// add years in order to handle date approximations }
/// <summary> /// Calibration objective function: /// squared difference between black caps and Cox-Ingersoll-Ross caps. /// </summary> /// <param name='x'> /// The tested [kappa, theta, sigma] vector. /// </param> /// <returns> /// The distance (using the L2 norm) between /// black Caps and the Cox-Ingersoll-Ross Caps. /// </returns> public double Obj(DVPLI.Vector x) { Matrix cirCapMatrix = CIRCap.CIRCapMatrix(this.capMaturity, this.capRate, this.tau, this.r0, x); double sum = 0; for (int r = 0; r < cirCapMatrix.R; r++) { for (int c = 0; c < cirCapMatrix.C; c++) { if (this.blackCaps[r, c] != 0.0) { sum += Math.Pow(cirCapMatrix[r, c] - this.blackCaps[r, c], 2); } } } return(Math.Sqrt(sum)); }
/// <summary> /// This method is unused but part of the interface. /// </summary> /// <param name="x">The parameter is not used.</param> /// <returns>Nothing the function always throws a NotImplementedException.</returns> public DVPLI.Vector G(DVPLI.Vector x) { throw new NotImplementedException(); }
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); }
/// <summary> /// Calibration objective function. /// </summary> /// <param name='x'> /// The vector of parameters. /// </param> /// <returns> /// Objective function value. /// </returns> public virtual double Obj(DVPLI.Vector x) { double sum = 0; if (Engine.MultiThread && !displayObjInfo) { // Instantiate parallel computation if enabled. List <Task> tl = new List <Task>(); // Context contains both input parameters and outputs. List <HestonCall> context = new List <HestonCall>(); for (int r = 0; r < this.callMarketPrice.R; r++) { if (this.maturity[r] >= this.matBound[0]) { HestonCall hc = new HestonCall(this, x, this.s0); context.Add(hc); hc.T = this.maturity[r]; hc.rate = this.rate[r]; if (HestonConstantDriftEstimator.impliedDividends) { hc.dividend = x[Range.End]; } else { hc.dividend = this.dividendYield[r]; } hc.row = r; tl.Add(Task.Factory.StartNew(this.CalculateSingleRow, hc)); } } tsScheduler.WaitTaskList(tl); for (int r = 0; r < tl.Count; r++) { sum += context[r].sum; } } else { // Sequential version of the code, used when parallel computation is disabled. HestonCall hc = new HestonCall(this, x, this.s0); for (int r = 0; r < this.callMarketPrice.R; r++) { if (this.maturity[r] >= this.matBound[0]) { hc.T = this.maturity[r]; hc.rate = this.rate[r]; if (HestonConstantDriftEstimator.impliedDividends) { hc.dividend = x[Range.End]; } else { hc.dividend = this.dividendYield[r]; } hc.row = r; hc.sum = 0; this.CalculateSingleRow(hc); sum += hc.sum; } } var pricingErrors = hc.hestonCallPrice - this.callMarketPrice; if (displayObjInfo) { avgPricingError = 0; for (int r = 0; r < this.callMarketPrice.R; r++) { if (this.maturity[r] >= this.matBound[0]) { for (int c = 0; c < this.callMarketPrice.C; c++) { if (this.callMarketPrice[r, c] > s0 * optionThreshold && this.cpmd.CallVolume[r, c] > 0) { avgPricingError += Math.Abs(pricingErrors[r, c]); } //if (this.cpmd.PutPrice[r, c] > s0 * optionThreshold && this.cpmd.PutVolume[r, c] > 0) // avgPricingError += Math.Abs(pricingErrors[r, c]); } } } avgPricingError /= numCall; int RR = Math.Min(12, this.callMarketPrice.R - 1); int CC = Math.Min(12, this.callMarketPrice.C - 1); Console.WriteLine("Mkt Price"); Console.WriteLine(this.callMarketPrice[Range.New(0, RR), Range.New(0, CC)]); Console.WriteLine("Pricing Errors"); Console.WriteLine(pricingErrors[Range.New(0, RR), Range.New(0, CC)]); } objCount++; } //Calculate average distance... sum = Math.Sqrt(sum / this.totalVolume); if (this.useBoundPenalty) { sum += this.BoundPenalty(x); } if (this.useFellerPenalty) { sum += this.FellerPenalty(x); } return(sum); }
/// <summary> /// This method is unused but part of the interface. /// </summary> /// <param name="x">The parameter is not used.</param> /// <returns>Null as it's unused.</returns> public DVPLI.Vector G(DVPLI.Vector x) { return(null); }