protected override EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution) { string[] names = new string[] { "S0", "kappa", "theta", "sigma", "rho", "V0", "r", "q" }; Vector param = new Vector(8); param[0] = spotPrice.Value; param[Range.New(1, 5)] = solution.x[Range.New(0, 4)]; param[6] = equityCalData.zrFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity); if (impliedDividends) { param[7] = solution.x[Range.End];// equityCalData.dyFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity); } else { param[7] = DY(equityCalData); } var result = new EstimationResult(names, param); result.Fit = HestonCallOptimizationProblem.avgPricingError; Console.WriteLine(result); return(result); }
protected override EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution) { string[] names = new string[] { "S0", "kappa", "theta", "sigma", "rho", "V0", "r", "q" }; Vector param = new Vector(8); param[0] = spotPrice.Value; param[Range.New(1, 5)] = solution.x[Range.New(0, 4)]; param[6] = equityCalData.zrFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity); if (impliedDividends) param[7] = solution.x[Range.End];// equityCalData.dyFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity); else param[7] = DY(equityCalData); var result = new EstimationResult(names, param); result.Fit = HestonCallOptimizationProblem.avgPricingError; Console.WriteLine(result); return result; }
private static void AssertEstimationResultsAreEqual(EstimationResult expected, EstimationResult actual) { if (expected == null) { Assert.IsNull(actual); } else { Assert.AreEqual(expected.Count, actual.Count); foreach (var expectedItem in expected) { var actualItem = actual.Single(i => i.Key.Name == expectedItem.Key.Name); AssertObserversAreEqual(expectedItem.Key, actualItem.Key, true); Assert.AreEqual(expectedItem.Value, actualItem.Value); } } }
/// <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> /// Populate editable fields from name and value vectors /// specific to the Heston extended process. /// </summary> /// <param name="stocProcess"> /// The stochastic process which is being referenced to. /// </param> /// <param name="estimate"> /// The estimation result which contains values and names of parameters. /// It will be searched for S0, kappa, theta, sigma, V0, r, q and rho. /// </param> public void Populate(IStochasticProcess stocProcess, EstimationResult estimate) { bool found; this.S0 = new ModelParameter(PopulateHelper.GetValue("S0", estimate.Names, estimate.Values, out found), this.S0.Description); this.k = new ModelParameter(PopulateHelper.GetValue("kappa", estimate.Names, estimate.Values, out found), this.k.Description); this.theta = new ModelParameter(PopulateHelper.GetValue("theta", estimate.Names, estimate.Values, out found), this.theta.Description); this.sigma = new ModelParameter(PopulateHelper.GetValue("sigma", estimate.Names, estimate.Values, out found), this.sigma.Description); this.V0 = new ModelParameter(PopulateHelper.GetValue("V0", estimate.Names, estimate.Values, out found), this.V0.Description); this.r = new ModelParameter(PopulateHelper.GetValue("r", estimate.Names, estimate.Values, out found), this.r.Description); this.q = new ModelParameter(PopulateHelper.GetValue("q", estimate.Names, estimate.Values, out found), this.q.Description); int index = stocProcess.NoiseIndex; ProjectProcess prj = stocProcess.Context as ProjectProcess; // Updates the correlation. prj.Processes.r.Set(index, index + 1, (RightValue)PopulateHelper.GetValue("rho", estimate.Names, estimate.Values, out found)); }
/// <summary> /// Attempts to solve the Variance Gamma Optimization problem using /// <see cref="Heston.VarianceGammaOptimizationProblem"/>. /// </summary> /// <param name="data"> /// The data to be used in order to perform the optimization. /// </param> /// <param name="settings">The parameter is not used.</param> /// <returns>The results of the optimization.</returns> public EstimationResult Estimate(List<object> data, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null) { EquitySpotMarketData espmd = data[0] as EquitySpotMarketData; CallPriceMarketData cpmd = data[1] as CallPriceMarketData; DiscountingCurveMarketData dcmd = data[2] as DiscountingCurveMarketData; EquityCalibrationData ecd = new EquityCalibrationData(cpmd, dcmd); this.s0 = espmd.Price; this.r = espmd.RiskFreeRate; this.q = espmd.DividendYield; this.k = ecd.Hdata.Strike; this.m = ecd.Hdata.Maturity; this.cp = ecd.Hdata.CallPrice; Vector x0 = (Vector)new double[] { -0.1, 0.2, 0.1 }; IOptimizationAlgorithm algorithm = new QADE(); OptimizationSettings optimizationSettings = new DESettings(); // Maximum number of iteration allowed. // Positive integer values print debug info. optimizationSettings.Verbosity = 1; // Tolerance. optimizationSettings.epsilon = 10e-5; var solution = algorithm.Minimize(new VarianceGammaOptimizationProblem(this.q, this.s0, this.k, this.r, this.cp, this.m), optimizationSettings, x0); if (solution.errors) return new EstimationResult(solution.message); var er = new EstimationResult(); er.Names= new string[]{"S0","theta","sigma","nu","rate","dividend"}; er.Values = new double[] {this.s0,solution.x[0],solution.x[1],solution.x[2],this.r,this.q}; return er; }
/// <summary> /// Attempts a calibration through <see cref="CapsHW1OptimizationProblem"/> /// 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; PFunction zr = new PFunction(null); zr.VarName = "zr"; var preferences = settings as Fairmat.Calibration.CapVolatilityFiltering; // Loads ZR double[,] zrvalue = (double[, ])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; BlackModel bm = new BlackModel(zr); double deltak = dataset.CapTenor; if (dataset.CapVolatility == null) { return(new EstimationResult("Cap not available at requested date")); } Matrix capVolatility = dataset.CapVolatility; Vector capMaturity = dataset.CapMaturity; Vector capRate = dataset.CapRate; double a = 0.1; double sigma = 0.1; // Matrix calculated with Black. Matrix blackCaps = new Matrix(capMaturity.Length, capRate.Length); Matrix logic = new Matrix(capMaturity.Length, capRate.Length); for (int m = 0; m < capMaturity.Length; m++) { for (int s = 0; s < capRate.Length; s++) { blackCaps[m, s] = bm.Cap(capRate[s], capVolatility[m, s], deltak, capMaturity[m]); if (double.IsNaN(blackCaps[m, s])) { bm.Cap(capRate[s], capVolatility[m, s], deltak, capMaturity[m]); throw new Exception("Malformed black caps"); } if (blackCaps[m, s] == 0.0) { logic[m, s] = 0.0; } else { logic[m, s] = 1.0; } //filter if (preferences != null) { if (capRate[s] < preferences.MinCapRate || capRate[s] > preferences.MaxCapRate || capMaturity[m] < preferences.MinCapMaturity || capMaturity[m] > preferences.MaxCapMaturity) { logic[m, s] = 0; blackCaps[m, s] = 0; } } } } DateTime t0 = DateTime.Now; CapHW1 hw1Caps = new CapHW1(zr); Matrix caps = hw1Caps.HWMatrixCaps(capMaturity, capRate, a, sigma, deltak); for (int m = 0; m < capMaturity.Length; m++) { for (int s = 0; s < capRate.Length; s++) { caps[m, s] = logic[m, s] * caps[m, s]; } } CapsHW1OptimizationProblem problem = new CapsHW1OptimizationProblem(hw1Caps, blackCaps, capMaturity, capRate, deltak); Vector provaparam = new Vector(2); var solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 20; o.MaxIter = 10; o.Verbosity = 1; o.Parallel = false; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 0.05, 0.01 }); o.controller = controller; solution = solver.Minimize(problem, o, x0); o.epsilon = 10e-8; o.h = 10e-8; o.MaxIter = 100; solution = solver2.Minimize(problem, o, solution.x); if (solution.errors) { return(new EstimationResult(solution.message)); } Console.WriteLine("Solution:"); Console.WriteLine(solution); string[] names = new string[] { "Alpha", "Sigma" }; //solution.x[0] *= 3; EstimationResult result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); return(result); }
public static void AddCount(this StringBuilder builder, GeometryType type, EstimationResult result, string separator) { builder.Append(result.GetCount(type)); builder.Append(separator); }
/// <summary> /// Attempts a calibration through <see cref="CapsCIROptimizationProblem"/> /// 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">A controller used for the optimization 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; // Creates the context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); CapCIROptimizationProblem problem = new CapCIROptimizationProblem(dataset); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 50; o.MaxIter = 50; o.Verbosity = 1; o.Parallel = false; o.controller = controller; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 1, 0.01, 0.05 }); solution = solver.Minimize(problem, o, x0); if (solution.errors) { return(new EstimationResult(solution.message)); } o.epsilon = 10e-10; o.h = 10e-10; o.MaxIter = 1000; 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:"); Console.WriteLine(solution); string[] names = CIR.parameterNames; Vector values = new Vector(4); values[Range.New(0, 2)] = solution.x; values[3] = problem.r0; EstimationResult result = new EstimationResult(names, values); return(result); }
public override AquisitionFunctionValue GetAquistionValue(EstimationResult er) { return(new AquisitionFunctionValue(er.X, er.UpperBound - er.LowerBound)); }
/// <summary> /// Populate editable fields from name and value vectors /// specific to the CIR process. /// </summary> /// <param name="container"> /// The stochastic process which is being referenced to. /// </param> /// <param name="estimate"> /// The estimation result which contains values and names of parameters. /// </param> public void Populate(IStochasticProcess container, EstimationResult estimate) { bool found; this.parameterValues = new double[4]; for (int i = 0; i < parameterNames.Length; i++) { this.parameterValues[i] = PopulateHelper.GetValue(parameterNames[i], estimate.Names, estimate.Values, out found); Console.WriteLine("ParameterValues[{0}] = {1}\t ParameterNames[{0}] = {2}", i, this.parameterValues[i], parameterNames[i]); } SetParametersValue(); }
/* /// <summary> /// Populate editable fields from name and value vectors /// specific to HW. /// </summary> /// <param name="names"> /// An array with the names of the variable, /// will search for alpha (or a1), sigma (or sigma1). /// </param> /// <param name="values">The values associated to the parameters in names.</param> public void Populate(string[] names, double[] values) { bool found = false; this.alpha1 = new ModelParameter(PopulateHelper.GetValue("alpha", "a1", names, values, out found), alphaDescription); this.sigma1 = new ModelParameter(PopulateHelper.GetValue("sigma", "sigma1", names, values, out found), sigmaDescription); this.lambda0 = new ModelParameter(PopulateHelper.GetValue("Lambda0", "lambda0", names, values, out found), lambda0Description); } */ /// <summary> /// Populate editable fields from name and value vectors /// specific to the Heston extended process. /// </summary> /// <param name="stocProcess"> /// The stochastic process which is being referenced to. /// </param> /// <param name="estimate"> /// The estimation result which contains values and names of parameters. /// It will be searched for S0, kappa, theta, sigma, V0 and rho. /// </param> public void Populate(IStochasticProcess stocProcess, EstimationResult estimate) { bool found; this.alpha1 = new ModelParameter(PopulateHelper.GetValue("alpha", "a1", estimate.Names, estimate.Values, out found), alphaDescription); this.sigma1 = new ModelParameter(PopulateHelper.GetValue("sigma", "sigma1", estimate.Names, estimate.Values, out found), sigmaDescription); this.lambda0 = new ModelParameter(PopulateHelper.GetValue("Lambda0", "lambda0", estimate.Names, estimate.Values, out found), lambda0Description); }
public abstract AquisitionFunctionValue GetAquistionValue(EstimationResult er);
private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset) { EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve); bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2); if (hasArbitrage) { Console.WriteLine("Market data contains arbitrage opportunity"); } this.r = new DVPLDOM.PFunction(discoutingCurve.Durations, discoutingCurve.Values); this.q = HCalData.dyFunc as PFunction; //this.r.Parse(null); //this.q.Parse(null); Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C); for (int i = 0; i < Hdataset.Volatility.R; i++) { double m = Hdataset.Maturity[i]; for (int j = 0; j < Hdataset.Volatility.C; j++) { if (Hdataset.CallPrice[i, j] > 0) { var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m)); //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i]; //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]); } } } Console.WriteLine(Hdataset.Volatility); IFunction impVol = FitImplVolModel(Hdataset); Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); prj.Symbols.Add(impVol); // doc.WriteToXMLFile("impVol.fair"); int nmat = calibrationSettings.LocalVolatilityMaturities; int nstrike = calibrationSettings.LocalVolatilityStrikes; double lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End]; double lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End]; Vector locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat); Vector locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike); Matrix locVolMatrix = new Matrix(nmat, nstrike); double t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy; double d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt; Integrate integrate = new Integrate(this); for (int i = 0; i < nmat; i++) { t = locVolMat[i]; forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t)); for (int j = 0; j < nstrike; j++) { strike = locVolStr[j]; y = Math.Log(strike / forwardValue); dy = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001); // strike derivative strikep = strike * Math.Exp(dy); strikem = strike / Math.Exp(dy); w = impVol.Evaluate(t, strike); wp = impVol.Evaluate(t, strikep); wm = impVol.Evaluate(t, strikem); dwdy = (wp - wm) / (2.0 * dy); d2wdy2 = (wp - 2.0 * w + wm) / (dy * dy); // time derivative if (t == 0.0) { dt = 0.0001; strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt)); wpt = impVol.Evaluate(t + dt, strikept); // if (wpt < w) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt); dwdt = (wpt - w) / dt; } else { dt = Math.Min(0.0001, t / 2.0); strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt)); strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t)); wpt = impVol.Evaluate(t + dt, strikept); wmt = impVol.Evaluate(t + dt, strikemt); //if (wpt < w) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt); //if (w < wmt) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t); dwdt = (wpt - wmt) / (2.0 * dt); } if (dwdy == 0.0 && d2wdy2 == 0.0) { locVolMatrix[i, j] = Math.Sqrt(dwdt); } else { den1 = 1.0 - y / w * dwdy; den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy; den3 = 0.5 * d2wdy2; locVolMatrix[i, j] = dwdt / (den1 + den2 + den3); //if (locVolMatrix[i,j] < 0.0) // Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " + // "Black vol surface is not smooth enought.", strike, t); } } } // Create dupire outputs. Console.WriteLine(locVolMat); PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix); localVol.Parse(null); string[] names = new string[] { "S0" }; Vector param = new Vector(1); param[0] = Hdataset.S0; EstimationResult result = new EstimationResult(names, param); //result.Objects = new object[3]; result.Objects = new object[4]; result.Objects[0] = this.r; result.Objects[1] = this.q; result.Objects[2] = localVol; result.Objects[3] = impVol; //Console.WriteLine("r = " + HCalData.Rate.ToString()); //Console.WriteLine("q = " + HCalData.DividendYield.ToString()); return(result); }
/// <summary> /// Populate editable fields from name and value vectors /// specific to the Heston extended process. /// </summary> /// <param name="stocProcess"> /// The stochastic process which is being referenced to. /// </param> /// <param name="estimate"> /// The estimation result which contains values and names of parameters. /// It will be searched for S0, kappa, theta, sigma, V0 and rho. /// </param> public void Populate(IStochasticProcess stocProcess, EstimationResult estimate) { bool found; this.S0 = new ModelParameter(PopulateHelper.GetValue("S0", estimate.Names, estimate.Values, out found), this.S0.Description); this.k = new ModelParameter(PopulateHelper.GetValue("kappa", estimate.Names, estimate.Values, out found), this.k.Description); this.theta = new ModelParameter(PopulateHelper.GetValue("theta", estimate.Names, estimate.Values, out found), this.theta.Description); this.sigma = new ModelParameter(PopulateHelper.GetValue("sigma", estimate.Names, estimate.Values, out found), this.sigma.Description); this.V0 = new ModelParameter(PopulateHelper.GetValue("V0", estimate.Names, estimate.Values, out found), this.V0.Description); int index = stocProcess.NoiseIndex; ProjectProcess prj = stocProcess.Context as ProjectProcess; // Update the correlation matrix. prj.Processes.r.Set(index, index + 1, (RightValue)PopulateHelper.GetValue("rho", estimate.Names, estimate.Values, out found)); bool errors = RetrieveCurve(stocProcess.Context, false); if (!errors) { this.zrCurve.Expr = (estimate.Objects[0] as Matrix).ToArray(); this.dyCurve.Expr = (estimate.Objects[1] as Matrix).ToArray(); //Calibrator assumes dividend yield is a step constant function, the simulation model must be coherent with that assumption. (this.dyCurve as PFunction).m_Function.iType = DVPLUtils.EInterpolationType.ZERO_ORDER_LEFT; } }
/// <summary> /// Attempts a calibration through <see cref="SwaptionHW1OptimizationProblem"/> /// using swaption 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; PFunction zr = new PFunction(null); // Loads the zero rate. double[,] zrvalue = (double[,])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; double deltak = dataset.SwaptionTenor; var swaptionsFiltering = settings as SwaptionsFiltering; if (swaptionsFiltering == null) swaptionsFiltering = new SwaptionsFiltering();//creates a default int maturitiesCount = dataset.OptionMaturity.Count(x => x >= swaptionsFiltering.MinSwaptionMaturity && x <= swaptionsFiltering.MaxSwaptionMaturity); int durationsCount = dataset.SwapDuration.Count(x => x >= swaptionsFiltering.MinSwapDuration && x <= swaptionsFiltering.MaxSwapDuration); Console.WriteLine(string.Format("Calibrating on {0} swaptions prices [#maturiries x #durations]=[{1} x {2}]", maturitiesCount * durationsCount, maturitiesCount,durationsCount)); if (maturitiesCount * durationsCount == 0) return new EstimationResult("No swaptions satisfying criteria found, please relax filters"); Matrix swaptionsVolatility = new Matrix(maturitiesCount, durationsCount);// dataset.SwaptionsVolatility; Vector optionMaturity = new Vector(maturitiesCount);// dataset.OptionMaturity; Vector swapDuration = new Vector(durationsCount);// dataset.SwapDuration; //Build filtered matrix and vectors int fm=0; for (int m = 0; m < dataset.OptionMaturity.Length; m++) { int fd=0; if (dataset.OptionMaturity[m] >= swaptionsFiltering.MinSwaptionMaturity && dataset.OptionMaturity[m] <= swaptionsFiltering.MaxSwaptionMaturity) { for (int d = 0; d < dataset.SwapDuration.Length; d++) { if (dataset.SwapDuration[d] >= swaptionsFiltering.MinSwapDuration && dataset.SwapDuration[d] <= swaptionsFiltering.MaxSwapDuration) { swaptionsVolatility[fm, fd] = dataset.SwaptionsVolatility[m, d]; swapDuration[fd] = dataset.SwapDuration[d]; fd++; } } optionMaturity[fm] = dataset.OptionMaturity[m]; fm++; } } SwaptionsBlackModel swbm = new SwaptionsBlackModel(zr); Matrix fsr; var blackSwaptionPrice = 1000.0 * swbm.SwaptionsSurfBM(optionMaturity, swapDuration, swaptionsVolatility, deltak, out fsr); Console.WriteLine("SwaptionHWEstimator: Black model prices"); Console.WriteLine(blackSwaptionPrice); SwaptionHW1 swhw1 = new SwaptionHW1(zr); SwaptionHW1OptimizationProblem problem = new SwaptionHW1OptimizationProblem(swhw1, blackSwaptionPrice, optionMaturity, swapDuration, deltak); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 20; o.MaxIter = 5; o.Verbosity = 1; o.controller = controller; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 0.1, 0.1 }); solution = solver.Minimize(problem, o, x0); if (solution.errors) return new EstimationResult(solution.message); o.epsilon = 10e-8; o.h = 10e-8; o.MaxIter = 1000; // We can permit this, given it is fast. o.accourate_numerical_derivatives = true; 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:"); Console.WriteLine(solution); string[] names = new string[] { "Alpha", "Sigma" }; EstimationResult result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); double obj = problem.Obj(solution.x); return result; }
public EstimationResult Estimate(List<object> data, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null) { EstimationResult r = new EstimationResult(); r.Objects = new object[] { }; return r; }
public void Constructor_Null_ArgumentNullException() { // Act var result = new EstimationResult(null); }
/// <summary> /// Attempts a calibration through <see cref="CapsCIROptimizationProblem"/> /// 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">A controller used for the optimization 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; // Creates the context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); CapCIROptimizationProblem problem = new CapCIROptimizationProblem(dataset); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 50; o.MaxIter = 50; o.Verbosity = 1; o.Parallel = false; o.controller = controller; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 1, 0.01, 0.05 }); solution = solver.Minimize(problem, o, x0); if (solution.errors) return new EstimationResult(solution.message); o.epsilon = 10e-10; o.h = 10e-10; o.MaxIter = 1000; 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:"); Console.WriteLine(solution); string[] names = CIR.parameterNames; Vector values = new Vector(4); values[Range.New(0, 2)] = solution.x; values[3] = problem.r0; EstimationResult result = new EstimationResult(names, values); return result; }
/// <summary> /// Attempts a calibration through <see cref="SwaptionHW1OptimizationProblem"/> /// using swaption 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) { LambdaCalibrationSettings lsettings = (LambdaCalibrationSettings)settings; if (lsettings.Years > lsettings.BondMaturity) throw new Exception("Bond maturity has to be greater of the historical series time span."); InterestRateMarketData irmd = data[0] as InterestRateMarketData; List<object> IrmdData = new List<object>(); IrmdData.Add(irmd); SwaptionHWEstimator shwe = new SwaptionHWEstimator(); EstimationResult er1 = shwe.Estimate(IrmdData); DiscountingCurveMarketData[] dcmd = Array.ConvertAll<IMarketData, DiscountingCurveMarketData> ((IMarketData[])data[1], el => (DiscountingCurveMarketData)el); MarketPriceOfRiskCalculator mporc = new MarketPriceOfRiskCalculator(); double lambda = mporc.Calculate(dcmd, lsettings); string[] names = new string[er1.Names.Length + 1]; for (int i = 0; i < er1.Names.Length; i++) names[i] = er1.Names[i]; names[er1.Names.Length] = "Lambda0"; Vector values = new Vector(er1.Values.Length + 1); values[new Range(0, values.Length - 2)] = (Vector) er1.Values; values[Range.End] = lambda; EstimationResult result = new EstimationResult(names, values); return result; }
public EstimationResult Estimate(IDictionary <string, string> runtimeParameters, EstimationResult previousStageResult, bool optimize) { var result = new EstimationResult(previousStageResult); var optimized = Enumerable.Empty <EstimationResult.ParameterValue>(); if (optimize) { optimized = Optimize(); if (previousStageResult != null && previousStageResult.Parameters != null && previousStageResult.Parameters.Count > 0) { result.Parameters.AddRange(optimized); } else { result.Parameters = optimized.ToList(); } } foreach (var runtimeParameter in runtimeParameters) { if (!_values.ContainsKey(runtimeParameter.Key)) { _values.Add(runtimeParameter); } } result.CalculationTime = ComputeTime(previousStageResult != null ? previousStageResult.Time : 0); result.Parameters.AddRange( GetParameters().Where(p => optimized.All(op => op.Name != p.Name)). Select(p => new EstimationResult.ParameterValue { Name = p.Name, InitialValue = GetParameterValue(p.Name), NewValue = GetParameterValue(p.Name) }) ); foreach (var runtimeParameter in runtimeParameters) { _values.Remove(runtimeParameter.Key); } return(result); }
/// <summary> /// Attempts a calibration through <see cref="CapsHW1OptimizationProblem"/> /// 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; PFunction zr = new PFunction(null); zr.VarName = "zr"; var preferences = settings as Fairmat.Calibration.CapVolatilityFiltering; // Loads ZR double[,] zrvalue = (double[,])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; BlackModel bm = new BlackModel(zr); double deltak = dataset.CapTenor; if (dataset.CapVolatility == null) return new EstimationResult("Cap not available at requested date"); Matrix capVolatility = dataset.CapVolatility; Vector capMaturity = dataset.CapMaturity; Vector capRate = dataset.CapRate; double a = 0.1; double sigma = 0.1; // Matrix calculated with Black. Matrix blackCaps = new Matrix(capMaturity.Length, capRate.Length); Matrix logic = new Matrix(capMaturity.Length, capRate.Length); for (int m = 0; m < capMaturity.Length; m++) { for (int s = 0; s < capRate.Length; s++) { blackCaps[m, s] = bm.Cap(capRate[s], capVolatility[m, s], deltak, capMaturity[m]); if (double.IsNaN(blackCaps[m, s])) { bm.Cap(capRate[s], capVolatility[m, s], deltak, capMaturity[m]); throw new Exception("Malformed black caps"); } if (blackCaps[m, s] == 0.0) { logic[m, s] = 0.0; } else { logic[m, s] = 1.0; } //filter if (preferences != null) { if (capRate[s] < preferences.MinCapRate || capRate[s] > preferences.MaxCapRate || capMaturity[m]<preferences.MinCapMaturity|| capMaturity[m]>preferences.MaxCapMaturity) {logic[m, s] = 0; blackCaps[m, s] = 0;} } } } DateTime t0 = DateTime.Now; CapHW1 hw1Caps = new CapHW1(zr); Matrix caps = hw1Caps.HWMatrixCaps(capMaturity, capRate, a, sigma, deltak); for (int m = 0; m < capMaturity.Length; m++) { for (int s = 0; s < capRate.Length; s++) { caps[m, s] = logic[m, s] * caps[m, s]; } } CapsHW1OptimizationProblem problem = new CapsHW1OptimizationProblem(hw1Caps, blackCaps, capMaturity, capRate, deltak); Vector provaparam = new Vector(2); var solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 20; o.MaxIter = 10; o.Verbosity = 1; o.Parallel = false; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 0.05, 0.01 }); o.controller = controller; solution = solver.Minimize(problem, o, x0); o.epsilon = 10e-8; o.h = 10e-8; o.MaxIter = 100; solution = solver2.Minimize(problem, o, solution.x); if (solution.errors) return new EstimationResult(solution.message); Console.WriteLine("Solution:"); Console.WriteLine(solution); string[] names = new string[] { "Alpha", "Sigma" }; //solution.x[0] *= 3; EstimationResult result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); return result; }
public void Populate(IStochasticProcess container, EstimationResult estimate) { bool found; this.s0 = new ModelParameter(PopulateHelper.GetValue("S0", estimate.Names, estimate.Values, out found), this.s0.Description); bool errors = RetrieveCurve(container.Context, false); if (!errors) { PFunction rFunc = estimate.Objects[0] as PFunction; PFunction rFuncDest = this.r.fVRef() as PFunction; rFuncDest.Expr = rFunc.Expr; PFunction qFunc = estimate.Objects[1] as PFunction; PFunction qFuncDest = this.q.fVRef() as PFunction; qFuncDest.Expr = qFunc.Expr; //Calibrator assumes dividend yield is a step constant function, the simulation model must be coherent with that assumption. qFuncDest.m_Function.iType = DVPLUtils.EInterpolationType.ZERO_ORDER_LEFT; PFunction2D.PFunction2D localVolSrc = estimate.Objects[2] as PFunction2D.PFunction2D; PFunction2D.PFunction2D localVolDest = this.localVol.fVRef() as PFunction2D.PFunction2D; localVolDest.Expr = localVolSrc.Expr; localVolDest.Interpolation = localVolSrc.Interpolation; } }
/// <summary> /// Attempts a calibration through <see cref="SwaptionHW1OptimizationProblem"/> /// using swaption 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]; } PFunction zr = new PFunction(null); // Loads the zero rate. double[,] zrvalue = (double[, ])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray()); zr.Expr = zrvalue; double deltak = dataset.SwaptionTenor; Console.WriteLine("Swaption Tenor\t" + dataset.SwaptionTenor); var swaptionsFiltering = settings as SwaptionsFiltering; if (swaptionsFiltering == null) { swaptionsFiltering = new SwaptionsFiltering();//creates a default } //F stands for Full matrix var optionMaturityF = normalVol != null ? normalVol.RowValues: dataset.OptionMaturity; var swapDurationF = normalVol != null ? normalVol.ColumnValues: dataset.SwapDuration; var swaptionsVolatilityF = normalVol != null ? normalVol.Values: dataset.SwaptionsVolatility; int maturitiesCount = optionMaturityF.Count(x => x >= swaptionsFiltering.MinSwaptionMaturity && x <= swaptionsFiltering.MaxSwaptionMaturity); int durationsCount = swapDurationF.Count(x => x >= swaptionsFiltering.MinSwapDuration && x <= swaptionsFiltering.MaxSwapDuration); Console.WriteLine(string.Format("Calibrating on {0} swaptions prices [#maturiries x #durations]=[{1} x {2}]", maturitiesCount * durationsCount, maturitiesCount, durationsCount)); if (maturitiesCount * durationsCount == 0) { return(new EstimationResult("No swaptions satisfying criteria found, please relax filters")); } //reduced version var swaptionsVolatility = new Matrix(maturitiesCount, durationsCount); // dataset.SwaptionsVolatility; var optionMaturity = new Vector(maturitiesCount); // dataset.OptionMaturity; var swapDuration = new Vector(durationsCount); // dataset.SwapDuration; //Build filtered matrix and vectors int fm = 0; for (int m = 0; m < optionMaturityF.Length; m++) { int fd = 0; if (optionMaturityF[m] >= swaptionsFiltering.MinSwaptionMaturity && optionMaturityF[m] <= swaptionsFiltering.MaxSwaptionMaturity) { for (int d = 0; d < swapDurationF.Length; d++) { if (swapDurationF[d] >= swaptionsFiltering.MinSwapDuration && swapDurationF[d] <= swaptionsFiltering.MaxSwapDuration) { swaptionsVolatility[fm, fd] = swaptionsVolatilityF[m, d]; swapDuration[fd] = swapDurationF[d]; fd++; } } optionMaturity[fm] = optionMaturityF[m]; fm++; } } var swbm = new SwaptionsBlackModel(zr, BlackModelFactory(zr)); Matrix fsr; var blackSwaptionPrice = 1000.0 * swbm.SwaptionsSurfBM(optionMaturity, swapDuration, swaptionsVolatility, deltak, out fsr); Console.WriteLine("Maturities\t" + optionMaturity); Console.WriteLine("swapDuration\t" + swapDuration); Console.WriteLine("SwaptionHWEstimator: Black model prices"); Console.WriteLine(blackSwaptionPrice); SwaptionHW1 swhw1 = new SwaptionHW1(zr); SwaptionHW1OptimizationProblem problem = new SwaptionHW1OptimizationProblem(swhw1, blackSwaptionPrice, optionMaturity, swapDuration, deltak); IOptimizationAlgorithm solver = new QADE(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.NP = 20; o.MaxIter = 5; o.Verbosity = 1; o.controller = controller; SolutionInfo solution = null; Vector x0 = new Vector(new double[] { 0.1, 0.1 }); solution = solver.Minimize(problem, o, x0); if (solution.errors) { return(new EstimationResult(solution.message)); } o.epsilon = 10e-8; o.h = 10e-8; o.MaxIter = 1000; // We can permit this, given it is fast. o.accourate_numerical_derivatives = true; 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:"); Console.WriteLine(solution); string[] names = new string[] { "Alpha", "Sigma" }; Console.WriteLine("SwaptionHWEstimator: hw model prices and error"); problem.Obj(solution.x, true); EstimationResult result = new EstimationResult(names, solution.x); result.ZRX = (double[])dataset.ZRMarketDates.ToArray(); result.ZRY = (double[])dataset.ZRMarket.ToArray(); double obj = problem.Obj(solution.x); return(result); }
private EstimationResult FairmatEstimate(CurveMarketData discountingCurve, CallPriceMarketData Hdataset) { EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discountingCurve); //HCalData.Setup(Hdataset, discountingCurve); bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2); if (hasArbitrage) Console.WriteLine("Market data contains arbitrage opportunity"); this.r = new DVPLDOM.PFunction(discountingCurve.Durations,discountingCurve.Values); this.q = HCalData.dyFunc as PFunction; //this.q.Expr = (double[,])ArrayHelper.Concat(HCalData.MaturityDY.ToArray(), HCalData.DividendYield.ToArray()); this.r.Parse(null); this.q.Parse(null); Vector locVolMat, locVolStr; //IFunction fittedSurface = FitImplVolModel(Hdataset); //Matrix locVolMatrix = LocVolMatrixFromImpliedVol(Hdataset, fittedSurface, out locVolMat, out locVolStr); CallPriceSurface fittedSurface = CallPriceSurface.NoArbitrageSurface(HCalData); Matrix locVolMatrix = LocVolMatrixFromCallPrices(Hdataset, fittedSurface, out locVolMat, out locVolStr); Console.WriteLine(locVolMatrix); // Create dupire outputs. PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix); localVol.Parse(null); string[] names = new string[] { "S0" }; Vector param = new Vector(1); param[0] = Hdataset.S0; EstimationResult result = new EstimationResult(names, param); //result.Objects = new object[3]; result.Objects = new object[4]; result.Objects[0] = this.r; result.Objects[1] = this.q; result.Objects[2] = localVol; result.Objects[3] = fittedSurface; //Console.WriteLine("r = " + HCalData.Rate.ToString()); //Console.WriteLine("q = " + HCalData.DividendYield.ToString()); return result; }
public EstimationResult Estimate(IDictionary<string, string> runtimeParameters, EstimationResult previousStageResult, bool optimize) { var result = new EstimationResult(previousStageResult); var optimized = Enumerable.Empty<EstimationResult.ParameterValue>(); if (optimize) { optimized = Optimize(); if (previousStageResult != null && previousStageResult.Parameters != null && previousStageResult.Parameters.Count > 0) { result.Parameters.AddRange(optimized); } else { result.Parameters = optimized.ToList(); } } foreach (var runtimeParameter in runtimeParameters) { if (!_values.ContainsKey(runtimeParameter.Key)) { _values.Add(runtimeParameter); } } result.CalculationTime = ComputeTime(previousStageResult != null ? previousStageResult.Time : 0); result.Parameters.AddRange( GetParameters().Where(p => optimized.All(op => op.Name != p.Name)). Select(p => new EstimationResult.ParameterValue { Name = p.Name, InitialValue = GetParameterValue(p.Name), NewValue = GetParameterValue(p.Name) }) ); foreach (var runtimeParameter in runtimeParameters) { _values.Remove(runtimeParameter.Key); } 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; }
private static Vector Test(int nm, int nk, double q, double s0, double r, double t, double theta, double sigma, double nu) { // Simulate synthetic data. Vector m = new Vector(nm); Vector k = new Vector(nk); Matrix cp = new Matrix(nm, nk); Random rand = new Random(); for (int i = 0; i < nm; i++) { m[i] = 0.01 + rand.NextDouble() * 0.99; } for (int i = 0; i < nk; i++) { k[i] = 60 + rand.NextDouble() * 90; } for (int i = 0; i < nm; i++) { for (int j = 0; j < nk; j++) { cp[i, j] = VarianceGammaOptionsCalibration.VGCall(theta, sigma, nu, m[i], k[j], q, s0, r); } } Console.WriteLine("Benchmark value"); Console.WriteLine(new Vector() { theta, sigma, nu }); Console.WriteLine("Call prices"); Console.WriteLine(cp); // VGDiff at optimum. double fopt = VarianceGammaOptimizationProblem.VGDiff(new Vector() { theta, sigma, nu }, q, s0, k, r, cp, m); Console.WriteLine("fopt"); Console.WriteLine(fopt); VarianceGammaOptionsCalibration c = new VarianceGammaOptionsCalibration(); List <object> marketData = new List <object>(); var espmd = new EquitySpotMarketData(); espmd.Price = s0; espmd.RiskFreeRate = r; espmd.DividendYield = q; var cpmd = new CallPriceMarketData(); cpmd.Strike = k; cpmd.Maturity = m; cpmd.CallPrice = cp; var dc = new DiscountingCurveMarketData(); dc.Durations = new Vector() { 0 }; dc.Values = new Vector() { r }; marketData.Add(espmd); marketData.Add(cpmd); marketData.Add(dc); EstimationResult res = c.Estimate(marketData, null); return((Vector)res.Values); }
private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset) { EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve); bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2); if (hasArbitrage) Console.WriteLine("Market data contains arbitrage opportunity"); this.r = new DVPLDOM.PFunction(discoutingCurve.Durations,discoutingCurve.Values); this.q = HCalData.dyFunc as PFunction; //this.r.Parse(null); //this.q.Parse(null); Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C); for (int i = 0; i < Hdataset.Volatility.R; i++) { double m=Hdataset.Maturity[i]; for (int j = 0; j < Hdataset.Volatility.C; j++) { if (Hdataset.CallPrice[i, j] > 0) { var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m)); //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i]; //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]); } } } Console.WriteLine(Hdataset.Volatility); IFunction impVol = FitImplVolModel(Hdataset); Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); prj.Symbols.Add(impVol); // doc.WriteToXMLFile("impVol.fair"); int nmat = calibrationSettings.LocalVolatilityMaturities; int nstrike = calibrationSettings.LocalVolatilityStrikes; double lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End]; double lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End]; Vector locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat); Vector locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike); Matrix locVolMatrix = new Matrix(nmat, nstrike); double t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy; double d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt; Integrate integrate = new Integrate(this); for (int i = 0; i < nmat; i++) { t = locVolMat[i]; forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t)); for (int j = 0; j < nstrike; j++) { strike = locVolStr[j]; y = Math.Log(strike / forwardValue); dy = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001); // strike derivative strikep = strike * Math.Exp(dy); strikem = strike / Math.Exp(dy); w = impVol.Evaluate(t, strike); wp = impVol.Evaluate(t, strikep); wm = impVol.Evaluate(t, strikem); dwdy = (wp - wm) / (2.0 * dy); d2wdy2 = (wp - 2.0 * w + wm) / (dy * dy); // time derivative if (t == 0.0) { dt = 0.0001; strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt)); wpt = impVol.Evaluate(t + dt, strikept); // if (wpt < w) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt); dwdt = (wpt - w) / dt; } else { dt = Math.Min(0.0001, t / 2.0); strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt)); strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t)); wpt = impVol.Evaluate(t + dt, strikept); wmt = impVol.Evaluate(t + dt, strikemt); //if (wpt < w) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt); //if (w < wmt) // Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t); dwdt = (wpt - wmt) / (2.0 * dt); } if (dwdy == 0.0 && d2wdy2 == 0.0) locVolMatrix[i, j] = Math.Sqrt(dwdt); else { den1 = 1.0 - y / w * dwdy; den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy; den3 = 0.5 * d2wdy2; locVolMatrix[i, j] = dwdt / (den1 + den2 + den3); //if (locVolMatrix[i,j] < 0.0) // Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " + // "Black vol surface is not smooth enought.", strike, t); } } } // Create dupire outputs. Console.WriteLine(locVolMat); PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix); localVol.Parse(null); string[] names = new string[] { "S0" }; Vector param = new Vector(1); param[0] = Hdataset.S0; EstimationResult result = new EstimationResult(names, param); //result.Objects = new object[3]; result.Objects = new object[4]; result.Objects[0] = this.r; result.Objects[1] = this.q; result.Objects[2] = localVol; result.Objects[3] = impVol; //Console.WriteLine("r = " + HCalData.Rate.ToString()); //Console.WriteLine("q = " + HCalData.DividendYield.ToString()); return result; }
public void TestCalibration() { InterestRateMarketData IData = InterestRateMarketData.FromFile("../../TestData/IRMD-sample.xml"); CallPriceMarketData HData = CallPriceMarketData.FromFile("../../TestData/CallData-sample.xml"); //InterestRateMarketData IData = InterestRateMarketData.FromFile("../../../EquityModels.Tests/TestData/IRMD-EU-30102012-close.xml"); //CallPriceMarketData HData = CallPriceMarketData.FromFile("../../../EquityModels.Tests/TestData/30102012-SX5E_Index-HestonData.xml"); //CallPriceMarketData HData = ObjectSerialization.ReadFromXMLFile("../../../EquityModels.Tests/TestData/FTSE.xml") as CallPriceMarketData; List <object> l = new List <object>(); l.Add(IData.DiscountingCurve); l.Add(HData); DupireEstimator DE = new DupireEstimator(); DupireCalibrationSettings settings = new DupireCalibrationSettings(); settings.LocalVolatilityCalculation = LocalVolatilityCalculation.Method1; //settings.LocalVolatilityCalculation = LocalVolatilityCalculation.QuantLib; EstimationResult res = DE.Estimate(l, settings); //int nmat = HData.Maturity.Length; //int nstrike = HData.Strike.Length; int i = 5; // Maturity. int j = 4; // Strike. Engine.MultiThread = true; Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); doc.DefaultProject.NMethods.m_UseAntiteticPaths = true; int n_sim = 10000; int n_steps = 500; double strike = HData.Strike[j]; //double volatility = HData.Volatility[i, j]; /* * PFunction2D.PFunction2D impvolfunc = new PFunction2D.PFunction2D(rov); * impvolfunc = res.Objects[3] as PFunction2D.PFunction2D; * impvolfunc.VarName = "impvol"; * rov.Symbols.Add(impvolfunc); * double volatility = impvolfunc.Evaluate(HData.Maturity[i], HData.Strike[j]); */ double volatility = 0.2; double maturity = HData.Maturity[i]; ModelParameter Pstrike = new ModelParameter(strike, string.Empty, "strike"); rov.Symbols.Add(Pstrike); AFunction payoff = new AFunction(rov); payoff.VarName = "payoff"; payoff.m_IndependentVariables = 1; payoff.m_Value = (RightValue)("max(x1 - strike ; 0)"); rov.Symbols.Add(payoff); bool found; double S0 = PopulateHelper.GetValue("S0", res.Names, res.Values, out found); ModelParameter PS0 = new ModelParameter(S0, string.Empty, "S0"); rov.Symbols.Add(PS0); PFunction rfunc = new PFunction(rov); rfunc = res.Objects[0] as PFunction; rfunc.VarName = "r"; rov.Symbols.Add(rfunc); PFunction qfunc = new PFunction(rov); qfunc = res.Objects[1] as PFunction; qfunc.VarName = "q"; rov.Symbols.Add(qfunc); PFunction2D.PFunction2D volfunc = new PFunction2D.PFunction2D(rov); volfunc = res.Objects[2] as PFunction2D.PFunction2D; volfunc.VarName = "localvol"; rov.Symbols.Add(volfunc); DupireProcess process = new DupireProcess(); process.s0 = (ModelParameter)"S0"; process.r = (ModelParameter)"@r"; process.q = (ModelParameter)"@q"; process.localVol = (ModelParameter)"@localvol"; double rate = rfunc.Evaluate(maturity); double dy = qfunc.Evaluate(maturity); StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.RiskFree; rfi.m_deterministicRF = rate; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "payoff(v1)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturity; op.PayoffInfo.European = true; rov.Map.Root = op; rov.NMethods.Technology = ETechType.T_SIMULATION; rov.NMethods.PathsNumber = n_sim; rov.NMethods.SimulationSteps = n_steps; ROVSolver solver = new ROVSolver(); solver.BindToProject(rov); solver.DoValuation(-1); if (rov.HasErrors) { rov.DisplayErrors(); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; double samplePrice = price.value; double sampleDevSt = price.stdDev / Math.Sqrt((double)n_sim); Console.WriteLine("Surf = " + volfunc.Expr); // Calculation of the theoretical value of the call. double theoreticalPrice = BlackScholes.Call(rate, S0, strike, volatility, maturity, dy); Console.WriteLine("Theoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; doc.WriteToXMLFile("Dupire.fair"); Assert.LessOrEqual(Math.Abs(theoreticalPrice - samplePrice), tol); }
protected virtual EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution) { string[] names = new string[] { "S0", "kappa", "theta", "sigma", "rho", "V0" }; Vector param = new Vector(6); param[0] = spotPrice.Value; param[Range.New(1, 5)] = solution.x; var result = new EstimationResult(names, param); // In the following the two function describing the ZR and dividend yields are created //Matrix zerorate = new Matrix(interestDataSet.Durations.Length, 2); //zerorate[Range.All, 0] = interestDataSet.Durations; //zerorate[Range.All, 1] = interestDataSet.Values; //Matrix dividendYield = new Matrix(equityCalData.MaturityDY.Length, 2); //dividendYield[Range.All, 0] = equityCalData.MaturityDY; //dividendYield[Range.All, 1] = equityCalData.DividendYield; Matrix zerorate = new Matrix((equityCalData.zrFunc as PFunction).Expr); //Matrix dividendYield = new Matrix((equityCalData.dyFunc as PFunction).Expr); Matrix dividendYield = ToMatrix(IstantaneousDividendYield(equityCalData)); result.Objects = new object[2]; result.Objects[0] = zerorate; result.Objects[1] = dividendYield; result.Fit = solution.obj; Console.WriteLine(result); return result; }