/// <summary> /// Caplet prices calculated as a put on a zero coupon bond. /// </summary> /// <param name="model">The model to use to execute the calculation.</param> /// <param name="mat"> /// Caplet maturity. This vector starts from zero and increases /// of step DeltaK each element till the last one. /// </param> /// <param name="fwd">Forward with the deltaK step.</param> /// <param name="rk">Strike vector (columns).</param> /// <param name="deltaK">Amount to use as increase factor.</param> /// <param name="tOss">The Maturities.</param> /// <returns>A <see cref="Matrix"/> with the caplet prices.</returns> public Matrix PGSMCaplets(SquaredGaussianModel model, Vector mat, Vector fwd, Vector rk, double deltaK, Vector tOss) { double s = model.sigma1.fV(); int col = rk.Length; int NP = (int)(1 + tOss[tOss.Length - 1] * 252); double[] dates = new double[NP]; double step = mat[mat.Length - 1] / (NP - 1); for (int z = 0; z < NP; z++) dates[z] = step * z; DateTime t0 = DateTime.Now; model.Setup(dates); DateTime t1 = DateTime.Now; Vector K = 1.0 / (1 + rk * deltaK); double cCost = model.C(deltaK); Vector sigma0s = Math.Pow(s, 2) * CtT(model, 0, mat); Matrix caplets = new Matrix(mat.Length - 1, rk.Length); Matrix caps = new Matrix(tOss.Length, rk.Length); // Pre-calculate values. Vector logK = Vector.Log(K); // Parallel version. List<Task> tl = new List<Task>(); Context context = new Context(); context.Model = model; context.Mat = mat; context.Fwd = fwd; context.RK = rk; context.DeltaK = deltaK; context.TOss = tOss; context.K = K; context.LogK = logK; context.Caplets = caplets; context.Sigma0s = sigma0s; context.CCost = cCost; context.RowStart = 0; context.RowEnd = (mat.Length - 2) / 2; tl.Add(Task.Factory.StartNew(Context.CalculateRowP, context)); context = new Context(); context.Model = model; context.Mat = mat; context.Fwd = fwd; context.RK = rk; context.DeltaK = deltaK; context.TOss = tOss; context.K = K; context.LogK = logK; context.Caplets = caplets; context.Sigma0s = sigma0s; context.CCost = cCost; context.RowStart = (mat.Length - 2) / 2 + 1; context.RowEnd = mat.Length - 2 - 1; tl.Add(Task.Factory.StartNew(Context.CalculateRowP, context)); tsScheduler.WaitTaskList(tl); // Sequential version. /* Context Context = new Context(); Context.Model = Model; Context.Mat = Mat; Context.Fwd = Fwd; Context.RK = RK; Context.DeltaK = DeltaK; Context.TOss = TOss; Context.K = K; Context.LogK = LogK; Context.Caplets = Caplets; Context.Sigma0s = Sigma0s; Context.CCost = CCost; for (int r = 0; r < Mat.Length - 2; r++) Context.CalculateRow(r); */ // Calculate the caps from the caplets. for (int r = 0; r < tOss.Length; r++) { for (int c = 0; c < rk.Length; c++) { double current = 0; for (int ci = 0; ci < (int)(tOss[r] / deltaK) - 1; ci++) current += caplets[ci, c]; caps[r, c] = current; } } return caps; }
/// <summary> /// Calculates the integral C(t, T) function with T taking /// every element of the parameter mat. /// </summary> /// <param name="model">The model instance.</param> /// <param name="t">The starting point of the integral.</param> /// <param name="mat">The vector of ending interval points T.</param> /// <returns>The vector of pre-calculated C(t,T).</returns> private Vector CtT(SquaredGaussianModel model, double t, Vector mat) { Vector C = new Vector(mat.Length); for (int i = 0; i < mat.Length; i++) C[i] = model.C(mat[i] - t); return C; }