/// <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 void Test() { ProjectROV r = HullAndWhite1("bond(t;2;@V1)", 1, 1, .05); r.Container.NMethods.Technology = ETechType.T_SIMULATION; r.Container.NMethods.m_UseRepeatableSequence = true; r.Initialize(); AnalysisValuation valuator = new AnalysisValuation(); valuator.BindToProject(r); valuator.RunAnalysis(-1); if (r.HasErrors) { r.DisplayErrors(); } Assert.IsFalse(r.HasErrors); double v = r.m_ResultList[0].value; Console.WriteLine("v = " + v.ToString()); Assert.AreEqual(0.9134, v, 0.0001); }
public static void Calculate(double t1, double t2, double simEnd, int numSim, int numSteps, out double val, out double stDev) { Engine.MultiThread = true; Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)0.05; rov.Symbols.Add(zerorate); // To be changed to 350000. int n_sim = numSim; int n_steps = numSteps; SquaredGaussianModel process = new SquaredGaussianModel(); process.a1 = (ModelParameter)0.1; process.sigma1 = (ModelParameter)0.01; process.zr = (ModelParameter)"@zr"; 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 = 0.0; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "bond(" + t1.ToString() + ";" + t2.ToString() + ";@v1)"; // Here we put the simulation maturity. op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)simEnd; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } ResultItem price = rov.m_ResultList[0] as ResultItem; val = price.value; stDev = price.stdDev / Math.Sqrt((double)numSim); }
/// <summary> /// Constructor for the Pelsser Calibration Problem based on caps matrices. /// </summary> /// <param name="project">The project where this calibration is being done.</param> /// <param name="caplet">The Pelsser Caplet object to use.</param> /// <param name="capMaturity">Vector of cap maturities.</param> /// <param name="fwd">Forward with the deltaK step.</param> /// <param name="capK">The caplet strike vector (columns).</param> /// <param name="deltaK">Interval between caplets expressed in year.</param> /// <param name="capMat">The caplet maturities.</param> /// <param name="blackCaps">A Blacks caps matrix to use.</param> internal PelsserCappletOptimizationProblem(ProjectROV project, Caplet caplet, Vector capMaturity, Vector fwd, Vector capK, double deltaK, Vector capMat, Matrix blackCaps) { this.project = project; this.caplet = caplet; this.capMaturity = capMaturity; this.fwd = fwd; this.capK = capK; this.deltaK = deltaK; this.capMat = capMat; this.blackCaps = blackCaps; Console.WriteLine("Pelsser Caps problem on " + this.capMaturity.Length + " x " + this.capK.Length + " elements"); }
public void Test() { Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)"0.05"; rov.Symbols.Add(zerorate); int n_sim = 5000; int n_steps = 900; SquaredGaussianModel process = new SquaredGaussianModel(); process.a1 = (ModelParameter)0.0704877770928728; process.sigma1 = (ModelParameter)0.116251516678772; process.zr = (ModelParameter)"@zr"; StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "bond(t;10;@v1)"; // Set the simulation maturity. op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)2.0; 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); }
private static ProjectROV HullAndWhite1(string payoff, double maturity, double a1, double sigma1) { Document doc = new Document(); ProjectROV rov1 = new ProjectROV(doc); doc.Part.Add(rov1); // Create the zero rate curve double a = 0.08; double b = 0.05; double c = -0.18; string zr = string.Format("{0} - {1}*exp({2}*x1)", a, b, c); AFunction zero_rate = new AFunction(rov1); zero_rate.VarName = "ZeroRate"; zero_rate.m_IndependentVariables = 1; zero_rate.m_Value = new RightValueExpression(zr); // Add to the project the created zero rate curve. rov1.Symbols.Add(zero_rate); RiskFreeInfo rfi = rov1.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.ZeroCoupond; rfi.m_deterministicRF.m_Value = (RightValue)"exp( -ZeroRate(t)*t)"; // Create the short rate process. HW1 hw1 = new HW1(a1, sigma1, "@ZeroRate"); StochasticProcessExtendible hw = new StochasticProcessExtendible(rov1, hw1); rov1.Processes.AddProcess(hw); OptionTree ot = new OptionTree(rov1); ot.European = true; ot.PayoffInfo.PayoffExpression = payoff; ot.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturity; rov1.Map.Root = ot; return(rov1); }
private static ProjectROV HullAndWhite1(string payoff, double maturity, double a1, double sigma1) { Document doc = new Document(); ProjectROV rov1 = new ProjectROV(doc); doc.Part.Add(rov1); // Create the zero rate curve double a = 0.08; double b = 0.05; double c = -0.18; string zr = string.Format("{0} - {1}*exp({2}*x1)", a, b, c); AFunction zero_rate = new AFunction(rov1); zero_rate.VarName = "ZeroRate"; zero_rate.m_IndependentVariables = 1; zero_rate.m_Value = new RightValueExpression(zr); // Add to the project the created zero rate curve. rov1.Symbols.Add(zero_rate); RiskFreeInfo rfi = rov1.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.ZeroCoupond; rfi.m_deterministicRF.m_Value = (RightValue)"exp( -ZeroRate(t)*t)"; // Create the short rate process. HW1 hw1 = new HW1(a1, sigma1, "@ZeroRate"); StochasticProcessExtendible hw = new StochasticProcessExtendible(rov1, hw1); rov1.Processes.AddProcess(hw); OptionTree ot = new OptionTree(rov1); ot.European = true; ot.PayoffInfo.PayoffExpression = payoff; ot.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturity; rov1.Map.Root = ot; return rov1; }
/// <summary> /// Assigns new trial values for x in order to use it /// for the evaluation of the constraints and the objective function. /// </summary> /// <param name="project">The project where to evaluate.</param> /// <param name="x">The vector of x values.</param> /// <returns>A <see cref="SquaredGaussianModel"/> set with the values.</returns> internal static SquaredGaussianModel Assign(ProjectROV project, Vector x) { Engine.Parser.NewContext(); SquaredGaussianModel model = project.Processes[0].Plugin as SquaredGaussianModel; // Assign the new values. ModelParameter a1 = model.a1 as ModelParameter; ModelParameter s1 = model.sigma1 as ModelParameter; a1.m_Value = (RightValue)x[0]; s1.m_Value = (RightValue)x[1]; bool errors = model.Parse(null); if (errors) { throw new Exception("Cannot Assing model"); } return(model); }
public void Test() { Engine.MultiThread = true; Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)0.05; rov.Symbols.Add(zerorate); int n_sim = 5000; int n_steps = 900; SquaredGaussianModel process = new SquaredGaussianModel(); process.a1 = (ModelParameter)0.1; process.sigma1 = (ModelParameter)0.01; process.zr = (ModelParameter)"@zr"; 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 = 0.0; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "bond(t;10;@v1)"; // Set the simulation maturity. op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)2.0; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; Console.WriteLine("Bond Test Value = " + price.value.ToString()); Assert.LessOrEqual(Math.Abs(0.6702 - price.value), .01); // Try to do some simple tests and check the results. double b0_10 = process.Bond(DynamicParam(0, process), process.CacheDates, 0, 0, 10); Console.WriteLine("Bond(0,10) = " + b0_10); Assert.LessOrEqual(Math.Abs(b0_10 - 0.606513), .001); double b7_10 = process.Bond(DynamicParam(0.00427631, process), process.CacheDates, 0, 7, 10); Console.WriteLine("Bond(7,10) = " + b7_10); Assert.LessOrEqual(Math.Abs(b7_10 - 0.856374), .001); double b7_30 = process.Bond(DynamicParam(0.00427631, process), process.CacheDates, 0, 7, 30); }
/// <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); }
public void Test() { 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 = 512; double a = 0.2; double DR = 0.02; double r0 = 0.015; double a1 = 1.0; double sigma1 = 0.01; double a2 = 0.1; double sigma2 = 0.0165; double correlation = 0.6; double maturityOpt = 5.0; double strike = 0.927; double tau = 2.0; ModelParameter PT = new ModelParameter(maturityOpt, "TT"); PT.VarName = "TT"; rov.Symbols.Add(PT); ModelParameter Ptau = new ModelParameter(tau, "tau"); Ptau.VarName = "tau"; rov.Symbols.Add(Ptau); ModelParameter Pa = new ModelParameter(a, "a"); Pa.VarName = "a"; rov.Symbols.Add(Pa); ModelParameter PDR = new ModelParameter(DR, "PDR"); PDR.VarName = "DR"; rov.Symbols.Add(PDR); ModelParameter Pr0 = new ModelParameter(r0, "r0"); Pr0.VarName = "r0"; rov.Symbols.Add(Pr0); ModelParameter Pstrike = new ModelParameter(strike, "strike"); Pstrike.VarName = "strike"; rov.Symbols.Add(Pstrike); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)("(1-exp(-a*x1))*DR + r0"); rov.Symbols.Add(zerorate); HW2ProcessType pt = new HW2ProcessType(); // Set the short rate process. pt = HW2ProcessType.ShortRate; StocasticProcessHW2 process1 = new StocasticProcessHW2(rov, pt); process1.zero_rate_curve = "@zr"; process1._a = (ModelParameter)a1; process1._b = (ModelParameter)sigma1; rov.Processes.AddProcess(process1); // Set the mean reversion process. pt = HW2ProcessType.Unobservable; StocasticProcessHW2 process2 = new StocasticProcessHW2(rov, pt); process2._a = (ModelParameter)a2; process2._b = (ModelParameter)sigma2; rov.Processes.AddProcess(process2); // Set the correlation. rov.Processes.r[0, 1] = (RightValue)correlation; // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.Stochastic; rfi.m_deterministicRF = (ModelParameter)"@v1"; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "max(bond(TT;TT+tau;@v1)-strike;0)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturityOpt; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; double sampleMean = price.value; double sampleDevSt = price.stdDev / Math.Sqrt((double)n_sim); double theoreticalPrice = HW2BondCall(zerorate, maturityOpt, maturityOpt + tau, strike, a1, sigma1, a2, sigma2, correlation); Console.WriteLine("\nTheoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + sampleMean.ToString()); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); bool result; double fact = 4.0; result = (Math.Abs(sampleMean - theoreticalPrice) < fact * sampleDevSt); Assert.IsTrue(result); }
/// <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 void Test() { double nu = 0.6; double theta = -0.2; double sigma = 0.2; double rate = 0.02; double dy = 0.01; double s0 = 1; double maturity = 2.0; double strike = 1.2; Vector mat = new Vector(1) + maturity; Vector k = new Vector(1) + strike; // Calculates the theoretical value of the call. double theoreticalPrice = VarianceGammaOptionsCalibration.VGCall(theta, sigma, nu, maturity, strike, dy, s0, rate); 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 = 50000; int n_steps = 512; ModelParameter paramStrike = new ModelParameter(strike, "strike"); paramStrike.VarName = "strike"; rov.Symbols.Add(paramStrike); ModelParameter paramRate = new ModelParameter(rate, "rfrate"); paramRate.VarName = "rfrate"; rov.Symbols.Add(paramRate); AFunction payoff = new AFunction(rov); payoff.VarName = "payoff"; payoff.m_IndependentVariables = 1; payoff.m_Value = (RightValue)("max(x1 - strike ; 0)"); rov.Symbols.Add(payoff); VarianceGamma process = new VarianceGamma(s0, theta, sigma, nu, rate, dy); 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("Theoretical Price = " + theoreticalPrice); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol); }
public void Test() { 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 = 20000; int n_steps = 1024; double a = 0.2; double DR = 0.02; double r0 = 0.015; double a1 = 0.02; double sigma1 = 0.01; double maturityOpt = 5.0; double strike = 0.005; double tau = 0.5; double strike2 = 1.0 / (1.0 + strike * tau); ModelParameter PT = new ModelParameter(maturityOpt, "TT"); PT.VarName = "TT"; rov.Symbols.Add(PT); ModelParameter Ptau = new ModelParameter(tau, "tau"); Ptau.VarName = "tau"; rov.Symbols.Add(Ptau); ModelParameter Pa = new ModelParameter(a, "a"); Pa.VarName = "a"; rov.Symbols.Add(Pa); ModelParameter PDR = new ModelParameter(DR, "PDR"); PDR.VarName = "DR"; rov.Symbols.Add(PDR); ModelParameter Pr0 = new ModelParameter(r0, "r0"); Pr0.VarName = "r0"; rov.Symbols.Add(Pr0); ModelParameter Pstrike = new ModelParameter(strike, "strike"); Pstrike.VarName = "strike"; rov.Symbols.Add(Pstrike); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)("(1-exp(-a*x1))*DR + r0"); rov.Symbols.Add(zerorate); HW1 process = new HW1(a1, sigma1, "@zr"); StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.Stochastic; rfi.m_deterministicRF = (ModelParameter)"@V1"; OptionTree op = new OptionTree(rov); // 1) RATE FUNCTION, with this the price is higher than the theoretical one // op.PayoffInfo.PayoffExpression = "tau*max(rate(TT;tau;@v1) - strike; 0)"; // 2) OBTAIN RATE FROM bond = exp(-rate*t), // with this the price is higher than the theoretical one but it's more near than 1) // op.PayoffInfo.PayoffExpression = "tau*max(-ln(bond(TT;TT+tau;@v1))/tau - strike; 0)"; // 3) CONVERT RATE from discrete to continuous through (1+r_d) = exp(r_c) // In this way the price is the same as the theoretical one. op.PayoffInfo.PayoffExpression = "tau*max(ln(1+rate(TT;tau;@v1)) - strike; 0)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturityOpt; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; double samplePrice = price.value; double sampleDevSt = price.stdDev / Math.Sqrt(2.0 * (double)n_sim); // Calculation of the theoretical value of the caplet. CapHW1 cap = new CapHW1(zerorate); double theoreticalPrice = cap.HWCaplet(a1, sigma1, maturityOpt, maturityOpt + tau, strike2); Console.WriteLine("Theoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol); }
/// <summary> /// Attempts to solve the Heston optimization problem using /// <see cref="Heston.HestonOptimizationProblem"/>. /// </summary> /// <param name="marketData">Data to be used in order to perform the optimization.</param> /// <param name="settings">The parameter is not used.</param> /// <param name="controller">IController.</param> /// <returns>The results of the optimization.</returns> public EstimationResult Estimate(List<object> marketData, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null) { DateTime t0 = DateTime.Now; var interestDataSet = (CurveMarketData)marketData[0]; CallPriceMarketData callDataSet = (CallPriceMarketData)marketData[1]; EquityCalibrationData equityCalData = new EquityCalibrationData(callDataSet, interestDataSet); var spotPrice = (DVPLI.MarketDataTypes.Scalar)marketData[2]; Setup(equityCalData, settings); var calSettings = settings as HestonCalibrationSettings; // Creates the context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); // Optimization problem instance. Vector matBound = new Vector(2); Vector strikeBound = new Vector(2); if (calSettings != null) { matBound[0] = calSettings.MinMaturity; matBound[1] = calSettings.MaxMaturity; strikeBound[0] = calSettings.MinStrike; strikeBound[1] = calSettings.MaxStrike; } else { //use defaults matBound[0] = 1.0 / 12;// .25; matBound[1] = 6;// 10; //Up to 6Y maturities strikeBound[0] = 0.4; strikeBound[1] = 1.6; } Console.WriteLine(callDataSet); /* //CBA TEST matBound[0] = 1;// .25; matBound[1] = 3.5;// 10; //Up to 6Y maturities strikeBound[0] = 0.5;// 0.5; strikeBound[1] = 2;//1.5; */ HestonCallOptimizationProblem problem = NewOptimizationProblem(equityCalData, matBound, strikeBound); int totalOpts = problem.numCall + problem.numPut; Console.WriteLine("Calibration based on "+totalOpts+ " options. (" + problem.numCall + " call options and "+problem.numPut+" put options)."); IOptimizationAlgorithm solver = new QADE(); //IOptimizationAlgorithm solver = new MultiLevelSingleLinkage(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.controller = controller; // If true the optimization algorithm will operate in parallel. o.Parallel = Engine.MultiThread; o.h = 10e-8; o.epsilon = 10e-8; SolutionInfo solution = null; double minObj=double.MaxValue; Vector minX= null; int Z = 1; //if (problem.GetType() == typeof(Heston.HestonCallSimulationOptimizationProblem)) // Z = 2; for(int z=0;z<Z;z++) { if (solver.GetType() == typeof(MultiLevelSingleLinkage)) { o.NP = 50; o.MaxIter = 25; o.MaxGamma = 6; } else { o.NP = 60; o.MaxIter = 35; } o.Verbosity = 1; Vector x0 = null;// new Vector(new double[] { 0.5, 0.5, 0.8, -0.5, 0.05 }); // GA solution = solver.Minimize(problem, o, x0); if (solution.errors) return null; o.options = "qn"; o.MaxIter = 500;// 1000; if (solution != null) solution = solver2.Minimize(problem, o, solution.x); else { solution = solver2.Minimize(problem, o, x0); } if (solution.errors) return null; if (solution.obj < minObj) { minObj = solution.obj; minX = solution.x.Clone(); } } solution.obj = minObj; solution.x = minX; //Displays pricing error structure HestonCallOptimizationProblem.displayObjInfo = true; problem.Obj(solution.x); HestonCallOptimizationProblem.displayObjInfo = false; Console.WriteLine("Calibration Time (s)\t" + (DateTime.Now - t0).TotalSeconds); return BuildEstimate(spotPrice,interestDataSet, callDataSet, equityCalData, solution); }
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> /// 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; }
/// <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="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 void Test() { // Tests HW1 dynamics comparing the price of a call option on a bond // calculated through simulation and the theoretical one. 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 = 20000; int n_steps = 1024; double a = 0.2; double DR = 0.02; double r0 = 0.015; double a1 = 0.02; double sigma1 = 0.01; double maturityOpt = 5.0; double strike = 0.98192; double tau = 1.0; ModelParameter PT = new ModelParameter(maturityOpt, "TT"); PT.VarName = "TT"; rov.Symbols.Add(PT); ModelParameter Ptau = new ModelParameter(tau, "tau"); Ptau.VarName = "tau"; rov.Symbols.Add(Ptau); ModelParameter Pa = new ModelParameter(a, "a"); Pa.VarName = "a"; rov.Symbols.Add(Pa); ModelParameter PDR = new ModelParameter(DR, "PDR"); PDR.VarName = "DR"; rov.Symbols.Add(PDR); ModelParameter Pr0 = new ModelParameter(r0, "r0"); Pr0.VarName = "r0"; rov.Symbols.Add(Pr0); ModelParameter Pstrike = new ModelParameter(strike, "strike"); Pstrike.VarName = "strike"; rov.Symbols.Add(Pstrike); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)("(1-exp(-a*x1))*DR + r0"); rov.Symbols.Add(zerorate); HW1 process = new HW1(a1, sigma1, "@zr"); StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.Stochastic; rfi.m_deterministicRF = (ModelParameter)"@V1"; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "Max(bond(TT;TT+tau;@v1)-strike;0)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturityOpt; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } 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); // Calculation of the theoretical value of the call. CapHW1 cap = new CapHW1(zerorate); double d1 = cap.D1(a1, sigma1, maturityOpt, maturityOpt + tau, strike); double d2 = cap.D2(a1, sigma1, maturityOpt, maturityOpt + tau, strike); double theoreticalPrice = ZCB(zerorate, maturityOpt + tau) * SpecialFunctions.NormCdf(d1) - strike * ZCB(zerorate, maturityOpt) * SpecialFunctions.NormCdf(d2); Console.WriteLine("Theoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol); }
public void Test() { Engine.MultiThread = true; Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)0.05; rov.Symbols.Add(zerorate); int n_sim = 4000; double maturityOpt = 6.5; // Simulation steps for a year. With stepPerYear = 150 the test will be passed. // But notice that the price calculated through Monte Carlo is unstable when // changing this value, even till 1000 steps per year. int stepsPerYear = 150; int n_steps = stepsPerYear * ((int)maturityOpt); double strike = 0.01; double tau = 0.5; SquaredGaussianModel process = new SquaredGaussianModel(); process.a1 = (ModelParameter)0.1; process.sigma1 = (ModelParameter)0.01; process.zr = (ModelParameter)"@zr"; StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); ModelParameter PT = new ModelParameter(maturityOpt, "TT"); PT.VarName = "TT"; rov.Symbols.Add(PT); ModelParameter Ptau = new ModelParameter(tau, "tau"); Ptau.VarName = "tau"; rov.Symbols.Add(Ptau); ModelParameter Pstrike = new ModelParameter(strike, "strike"); Pstrike.VarName = "strike"; rov.Symbols.Add(Pstrike); // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.Stochastic; rfi.m_deterministicRF = (ModelParameter)"@V1"; // Set the payoff. OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "tau*max(rate(TT;tau;@v1) - strike; 0)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)(maturityOpt + tau); 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 mcPrice = price.value; double mcDevST = price.stdDev / Math.Sqrt((double)n_sim); Caplet cplt = new Caplet(); Vector Mat, fwd, Rk; Vector capMatV; double delta_k; double capMat; delta_k = 0.5; capMat = maturityOpt + tau; int nmat = 2 * ((int)capMat) + 1; Mat = new Vector(nmat); fwd = new Vector(nmat); Mat[0] = 0; fwd[0] = zerorate.Evaluate(0); for (int k = 1; k < nmat; k++) { Mat[k] = tau * ((double)k); fwd[k] = zerorate.Evaluate(Mat[k]) * Mat[k] - zerorate.Evaluate(Mat[k - 1]) * Mat[k - 1]; } fwd = fwd / tau; Rk = new Vector(1); Rk[0] = strike; capMatV = new Vector(2); capMatV[0] = maturityOpt; capMatV[1] = maturityOpt + tau; Matrix caplet = cplt.PGSMCaplets(process, Mat, fwd, Rk, delta_k, capMatV); double theoreticalPrice = caplet[1, 0] - caplet[0, 0]; Console.WriteLine("\nTheoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + mcPrice); Console.WriteLine("Standard Deviation = " + mcDevST); double tol = 4.0 * mcDevST; Assert.Less(Math.Abs(theoreticalPrice - mcPrice), tol); }
/// <summary> /// /// </summary> /// <param name="p_VarCov">input Covariance Matrix</param> /// <param name="p_kappa"> input mean reverting coefficient</param> /// <param name="p_mean_series">Historical Mean vector</param> /// <param name="p_log">true if the component is a log mean reverting</param> /// <param name="p_deltat">vector of deltaT</param> /// <param name="p_ProbTreshold">p in the report</param> /// <param name="p_AUM">let to false</param> /// <param name="p_MCR">number of children when montecarlo (Z in the Report)</param> /// <param name="p_seed"></param> public MultivariateTree(ProjectROV project) { this.prj = project; }
public void TestSimulation() { 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 = 512; double strike = 90.0; double maturity = 2.0; double rate = 0.1; double dy = 0.05; double volatility = 0.2; double S0 = 100; ModelParameter Pstrike = new ModelParameter(strike, string.Empty, "strike"); rov.Symbols.Add(Pstrike); ModelParameter PS0 = new ModelParameter(S0, string.Empty, "S0"); rov.Symbols.Add(PS0); AFunction payoff = new AFunction(rov); payoff.VarName = "payoff"; payoff.m_IndependentVariables = 1; payoff.m_Value = (RightValue)("max(x1 - strike ; 0)"); rov.Symbols.Add(payoff); AFunction rfunc = new AFunction(rov); rfunc.VarName = "r"; rfunc.m_IndependentVariables = 1; rfunc.m_Value = (RightValue)rate; rov.Symbols.Add(rfunc); AFunction qfunc = new AFunction(rov); qfunc.VarName = "q"; qfunc.m_IndependentVariables = 1; qfunc.m_Value = (RightValue)dy; rov.Symbols.Add(qfunc); AFunction volfunc = new AFunction(rov); volfunc.VarName = "localvol"; volfunc.m_IndependentVariables = 2; volfunc.m_Value = (RightValue)volatility; rov.Symbols.Add(volfunc); DupireProcess process = new DupireProcess(); process.s0 = (ModelParameter)"S0"; process.r = (ModelParameter)"@r"; process.q = (ModelParameter)"@q"; process.localVol = (ModelParameter)"@localvol"; 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); // 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; Assert.LessOrEqual(Math.Abs(theoreticalPrice - samplePrice), tol); }
/// <summary> /// Attempts to solve the Heston optimization problem using /// <see cref="Heston.HestonOptimizationProblem"/>. /// </summary> /// <param name="marketData">Data to be used in order to perform the optimization.</param> /// <param name="settings">The parameter is not used.</param> /// <param name="controller">IController.</param> /// <returns>The results of the optimization.</returns> public EstimationResult Estimate(List <object> marketData, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null) { DateTime t0 = DateTime.Now; var interestDataSet = (CurveMarketData)marketData[0]; CallPriceMarketData callDataSet = (CallPriceMarketData)marketData[1]; EquityCalibrationData equityCalData = new EquityCalibrationData(callDataSet, interestDataSet); var spotPrice = (DVPLI.MarketDataTypes.Scalar)marketData[2]; Setup(equityCalData, settings); var calSettings = settings as HestonCalibrationSettings; // Creates the context. Document doc = new Document(); ProjectROV prj = new ProjectROV(doc); doc.Part.Add(prj); // Optimization problem instance. Vector matBound = new Vector(2); Vector strikeBound = new Vector(2); if (calSettings != null) { matBound[0] = calSettings.MinMaturity; matBound[1] = calSettings.MaxMaturity; strikeBound[0] = calSettings.MinStrike; strikeBound[1] = calSettings.MaxStrike; } else { //use defaults matBound[0] = 1.0 / 12; // .25; matBound[1] = 6; // 10; //Up to 6Y maturities strikeBound[0] = 0.4; strikeBound[1] = 1.6; } Console.WriteLine(callDataSet); /* * //CBA TEST * matBound[0] = 1;// .25; * matBound[1] = 3.5;// 10; //Up to 6Y maturities * strikeBound[0] = 0.5;// 0.5; * strikeBound[1] = 2;//1.5; */ HestonCallOptimizationProblem problem = NewOptimizationProblem(equityCalData, matBound, strikeBound); int totalOpts = problem.numCall + problem.numPut; Console.WriteLine("Calibration based on " + totalOpts + " options. (" + problem.numCall + " call options and " + problem.numPut + " put options)."); IOptimizationAlgorithm solver = new QADE(); //IOptimizationAlgorithm solver = new MultiLevelSingleLinkage(); IOptimizationAlgorithm solver2 = new SteepestDescent(); DESettings o = new DESettings(); o.controller = controller; // If true the optimization algorithm will operate in parallel. o.Parallel = Engine.MultiThread; o.h = 10e-8; o.epsilon = 10e-8; SolutionInfo solution = null; double minObj = double.MaxValue; Vector minX = null; int Z = 1; //if (problem.GetType() == typeof(Heston.HestonCallSimulationOptimizationProblem)) // Z = 2; for (int z = 0; z < Z; z++) { if (solver.GetType() == typeof(MultiLevelSingleLinkage)) { o.NP = 50; o.MaxIter = 25; o.MaxGamma = 6; } else { o.NP = 60; o.MaxIter = 35; } o.Verbosity = 1; Vector x0 = null;// new Vector(new double[] { 0.5, 0.5, 0.8, -0.5, 0.05 }); // GA solution = solver.Minimize(problem, o, x0); if (solution.errors) { return(null); } o.options = "qn"; o.MaxIter = 500;// 1000; if (solution != null) { solution = solver2.Minimize(problem, o, solution.x); } else { solution = solver2.Minimize(problem, o, x0); } if (solution.errors) { return(null); } if (solution.obj < minObj) { minObj = solution.obj; minX = solution.x.Clone(); } } solution.obj = minObj; solution.x = minX; //Displays pricing error structure HestonCallOptimizationProblem.displayObjInfo = true; problem.Obj(solution.x); HestonCallOptimizationProblem.displayObjInfo = false; Console.WriteLine("Calibration Time (s)\t" + (DateTime.Now - t0).TotalSeconds); return(BuildEstimate(spotPrice, interestDataSet, callDataSet, equityCalData, solution)); }
public void Test() { 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 = 50000; int n_steps = 512; double strike = 100.0; double tau = 5.0; double rate = 0.1; double dy = 0.07; ModelParameter pStrike = new ModelParameter(strike, "strike"); pStrike.VarName = "strike"; rov.Symbols.Add(pStrike); ModelParameter pRate = new ModelParameter(rate, "rfrate"); pRate.VarName = "rfrate"; rov.Symbols.Add(pRate); AFunction payoff = new AFunction(rov); payoff.VarName = "payoff"; payoff.m_IndependentVariables = 1; payoff.m_Value = (RightValue)("max(x1 - strike ; 0)"); rov.Symbols.Add(payoff); HestonProcess process = new HestonProcess(); process.r = (ModelParameter)rate; process.q = (ModelParameter)dy; process.k = (ModelParameter)2.5; process.theta = (ModelParameter)0.4; process.sigma = (ModelParameter)0.2; process.S0 = (ModelParameter)100.0; process.V0 = (ModelParameter)0.3; 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(v1a)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)tau; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } 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); // Calculates the theoretical value of the call. Vector param = new Vector(5); param[0] = process.k.V(); param[1] = process.theta.V(); param[2] = process.sigma.V(); param[3] = 0.0; param[4] = process.V0.V(); HestonCall hestonCall = new HestonCall(); double thPrice = hestonCall.HestonCallPrice(param, process.S0.V(), tau, strike, rate, dy); Console.WriteLine("Theoretical Price = " + thPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; Assert.Less(Math.Abs(thPrice - samplePrice), tol); }
/// <summary> /// Assigns new trial values for x in order to use it /// for the evaluation of the constraints and the objective function. /// </summary> /// <param name="project">The project where to evaluate.</param> /// <param name="x">The vector of x values.</param> /// <returns>A <see cref="SquaredGaussianModel"/> set with the values.</returns> internal static SquaredGaussianModel Assign(ProjectROV project, Vector x) { Engine.Parser.NewContext(); SquaredGaussianModel model = project.Processes[0].Plugin as SquaredGaussianModel; // Assign the new values. ModelParameter a1 = model.a1 as ModelParameter; ModelParameter s1 = model.sigma1 as ModelParameter; a1.m_Value = (RightValue)x[0]; s1.m_Value = (RightValue)x[1]; bool errors=model.Parse(null); if (errors) throw new Exception("Cannot Assing model"); return model; }
public void Test() { Engine.MultiThread = true; Document doc = new Document(); ProjectROV rov = new ProjectROV(doc); doc.Part.Add(rov); AFunction zerorate = new AFunction(rov); zerorate.VarName = "zr"; zerorate.m_IndependentVariables = 1; zerorate.m_Value = (RightValue)0.05; rov.Symbols.Add(zerorate); int n_sim = 10000; double maturityOpt = 6.5; // Simulation steps for a year. With stepPerYear = 150 the test will be passed. // But notice that the price calculated through Monte Carlo is unstable when // changing this value, even till 1000 steps per year. int stepsPerYear = 500; int n_steps = stepsPerYear * ((int)maturityOpt); double strike = 100.0; double tau = 0.5; SquaredGaussianModel process = new SquaredGaussianModel(); process.a1 = (ModelParameter)0.1; process.sigma1 = (ModelParameter)0.01; process.zr = (ModelParameter)"@zr"; StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process); rov.Processes.AddProcess(s); ModelParameter PT = new ModelParameter(maturityOpt, "TT"); PT.VarName = "TT"; rov.Symbols.Add(PT); ModelParameter Ptau = new ModelParameter(tau, "tau"); Ptau.VarName = "tau"; rov.Symbols.Add(Ptau); ModelParameter Pstrike = new ModelParameter(strike, "strike"); Pstrike.VarName = "strike"; rov.Symbols.Add(Pstrike); // Set the discounting. RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo; rfi.ActualizationType = EActualizationType.Stochastic; rfi.m_deterministicRF = (ModelParameter)"@V1"; // Set the payoff. OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "max(strike - Bond(TT;TT+tau;@v1); 0)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturityOpt; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; double mcPrice = price.value; double mcDevST = price.stdDev / Math.Sqrt(2.0 * ((double)n_sim)); Caplet cplt = new Caplet(); Vector Mat; Vector fwd; Vector Rk; Vector capMatV; double deltaK; double capMat; deltaK = 0.5; capMat = maturityOpt + tau; int nmat = 2 * ((int)capMat) + 1; Mat = new Vector(nmat); fwd = new Vector(nmat); Mat[0] = 0; fwd[0] = zerorate.Evaluate(0); for (int k = 1; k < nmat; k++) { Mat[k] = tau * ((double)k); fwd[k] = zerorate.Evaluate(Mat[k]) * Mat[k] - zerorate.Evaluate(Mat[k - 1]) * Mat[k - 1]; } fwd = fwd / tau; Rk = new Vector(1); Rk[0] = (1 / strike - 1.0) / tau; capMatV = new Vector(2); capMatV[0] = maturityOpt; capMatV[1] = maturityOpt + tau; Matrix caplet = cplt.PGSMCaplets(process, Mat, fwd, Rk, deltaK, capMatV); Console.WriteLine("rows = " + caplet.R); Console.WriteLine("columns = " + caplet.C); double theoreticalPrice = caplet[1, 0] - caplet[0, 0]; Console.WriteLine("\nTheoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + mcPrice); Console.WriteLine("Standard Deviation = " + mcDevST); double tol = 4.0 * mcDevST; Assert.Less(Math.Abs(theoreticalPrice - mcPrice), tol); }
public void Test() { 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 = 100000; int n_steps = 256; double strike = 90.0; double tau = 2.0; double rate = 0.1; double dy = 0.07; ModelParameter pStrike = new ModelParameter(strike, "strike"); pStrike.VarName = "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); AFunction zrfunc = new AFunction(rov); zrfunc.VarName = "zr"; zrfunc.m_IndependentVariables = 1; zrfunc.m_Value = (RightValue)rate; rov.Symbols.Add(zrfunc); AFunction dyfunc = new AFunction(rov); dyfunc.VarName = "dy"; dyfunc.m_IndependentVariables = 1; dyfunc.m_Value = (RightValue)dy; rov.Symbols.Add(dyfunc); HestonExtendedProcess process = new HestonExtendedProcess(); process.k = (ModelParameter)2.5; process.theta = (ModelParameter)0.4; process.sigma = (ModelParameter)0.2; process.S0 = (ModelParameter)100.0; process.V0 = (ModelParameter)0.3; process.zrReference = (ModelParameter)"@zr"; process.dyReference = (ModelParameter)"@dy"; double discount = Math.Exp(-rate * tau); 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 = 0.0; OptionTree op = new OptionTree(rov); op.PayoffInfo.PayoffExpression = "payoff(v1a)"; op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)tau; 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) { Console.WriteLine(rov.m_RuntimeErrorList[0]); } Assert.IsFalse(rov.HasErrors); ResultItem price = rov.m_ResultList[0] as ResultItem; double samplePrice = discount * price.value; double sampleDevSt = price.stdDev / Math.Sqrt((double)n_sim); // Calculates the theoretical value of the call. Vector param = new Vector(5); param[0] = process.k.V(); param[1] = process.theta.V(); param[2] = process.sigma.V(); param[3] = 0.0; param[4] = process.V0.V(); HestonCall hestonCall = new HestonCall(); double theoreticalPrice = hestonCall.HestonCallPrice(param, process.S0.V(), tau, strike, rate, dy); Console.WriteLine("Theoretical Price = " + theoreticalPrice.ToString()); Console.WriteLine("Monte Carlo Price = " + samplePrice); Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString()); double tol = 4.0 * sampleDevSt; Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol); }
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); }
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); }