/// <summary> /// Constructor for the HW1 Calibration Problem based on caps matrices. /// </summary> /// <param name="hw1Caps"> /// A <see cref="HullAndWhiteOneFactor.CapHW1"/> object to use. /// </param> /// <param name="blackCaps">A Blacks caps matrix to use.</param> /// <param name="capMaturity">Vector of cap maturities.</param> /// <param name="capRate">Vector of cap strikes.</param> /// <param name="deltaK">Interval between caplets expressed in year.</param> internal CapsHW1OptimizationProblem(CapHW1 hw1Caps, Matrix blackCaps, Vector capMaturity, Vector capRate, double deltaK) { this.hw1Caps = hw1Caps; this.blackCaps = blackCaps; this.capMaturity = capMaturity; this.capRate = capRate; this.deltaK = deltaK; }
public void Test() { double[,] values = { { .5, .015 }, { 1, .0165 }, { 2, .0168 }, { 3, .0172 }, { 5, .0182 }, { 8, .0210 }, { 10, .025 }, { 15, .031 }, { 20, .035 }, { 30, .037 }, { 40, .038 }, }; Function zeroratecurve = new PFunction(null); zeroratecurve.Expr = values; (zeroratecurve as PFunction).m_Function.iType = EInterpolationType.LINEAR; // Execute the test. CapHW1 hwc = new CapHW1(zeroratecurve); // CAP and FLOOR Tests. double[] results = new double[2]; results[0] = hwc.HWCap(0.14, 0.02, 0.02, 0.5, 1); results[1] = hwc.HWCap(0.14, 0.02, 0.02, 0.5, 2); Console.WriteLine("CAP 2 col 1 row:" + results[0]); Console.WriteLine("CAP 2 col 2 row:" + results[1]); // Check the results with previously manually calculated values. double[] targets = { 0.00214717607719883, 0.0084939015243779 }; double eps = 10e-6; for (int r = 0; r < results.Length; r++) { Assert.LessOrEqual(Math.Abs(targets[r] - results[r]), eps); } }
/// <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; }
/// <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 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); }
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); }