/// <summary> /// Simulate a realization of the stochastic process driven by the noise matrix noise. /// </summary> /// <remarks> /// This function is called once for realization. /// </remarks> /// <param name="dates"> /// The dates (in years fractions) at which the process must be simulated. /// </param> /// <param name="noise">The matrix of IID normal realizations.</param> /// <param name="outDynamic">Where the dynamic should be written.</param> public void Simulate(double[] dates, IReadOnlyMatrixSlice noise, IMatrixSlice outDynamic) { switch (OperatingMode) { case OperatingMode.TranslateHistoricalRealizationsForward: for (int i = 0; i < dates.Length; i++) { int dateIndex; if (!this.simulationDateIndexes.TryGetValue(dates[i], out dateIndex)) { dateIndex = 0; } Tuple <DateTime, Vector> value = this.fileContent[dateIndex]; for (int j = 0; j < value.Item2.Length - 1; j++) { outDynamic[i, j] = value.Item2[j]; } } break; case OperatingMode.Bootstrap: this.bootstrap.Simulate(dates, outDynamic); break; } }
/// <summary> /// Calculates the value of a Bond under the Pelsser model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variables must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variables must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns>The value of the bound at index i using the Pelsser model.</returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { // Handles special case. if (t == s) { return(1); } // Get the value of the short rate. double y = Math.Sqrt(dynamic[i, 0]) - this.alphaT0[i]; PelsserKey k = new PelsserKey(t, s); PelsserCache cachedValue = null; lock (this.cache) { if (this.cache.ContainsKey(k)) { cachedValue = this.cache[k]; } else { cachedValue = new PelsserCache(t, s, this); // Insert the value in the cache. this.cache.Add(k, cachedValue); } } double v = Math.Exp(cachedValue.A - y * cachedValue.B - (y * y) * cachedValue.CtT0); return(v); }
public void Simulate(double[] Dates, IReadOnlyMatrixSlice Noise, IMatrixSlice OutDynamic) { OutDynamic[0, 0] = spot.fV(); for (int i = 1; i < Dates.Length; i++) { OutDynamic[i, 0] = a * OutDynamic[i - 1, 0] + b + c * Noise[i - 1, 0]; } }
/// <summary> /// Calculates the value of a Bond under the Hull and White model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variable must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variable must be sampled. /// </param> /// <param name='T'> /// The maturity of the bond. /// </param> /// <returns>The value of the bound at index i using the HW model.</returns> public virtual double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double T) { #if TFORWARDFORMULATION double y = dynamic[i, 0] - this.alphaT[i]; return(Math.Exp(A(t, T, this.alpha1Temp, this.sigma1Temp, this.zeroRateCurve) - y * B(T - t, this.alpha1Temp))); #else throw new NotImplementedException(); #endif }
/// <summary> /// Calculates the value of a Bond under the Cox-Ingersoll-Ross model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variable must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variable must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns> /// The value of the bound at index i using the Cox-Ingersoll-Ross model. /// </returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { double r = dynamic[i, 0]; double T = s - t; double den = (this.alphaTemp + this.d) * (Math.Exp(this.d * T) - 1.0) + 2.0 * this.d; double A = Math.Pow(2.0 * this.d * Math.Exp(0.5 * (this.alphaTemp + this.d) * T) / den, this.nu); double B = 2.0 * (Math.Exp(this.d * T) - 1.0) / den; return(A * Math.Exp(-r * B)); }
public void Simulate(double[] Dates, IReadOnlyMatrixSlice Noise, IMatrixSlice OutDynamic) { OutDynamic[0, 0] = x0[0]; for (int i = 1; i < Dates.Length; i++) { double dt = Dates[i] - Dates[i - 1]; double rdt = Math.Sqrt(dt); double th = theta(Dates[i], dt); OutDynamic[i, 0] = OutDynamic[i - 1, 0] + (th - alpha1Temp * OutDynamic[i - 1, 0]) * dt + sigma1Temp * Noise[i - 1, 0] * rdt; } }
/// <summary> /// Manage the simulation of the variance gamma process /// </summary> /// <param name="Dates">Simulation dates</param> /// <param name="Noise">Gaussian noise for a single path</param> /// <param name="OutDynamic">Single path process realization</param> public void Simulate(double[] Dates, IReadOnlyMatrixSlice Noise, IMatrixSlice OutDynamic) { int steps = OutDynamic.R; double GammaNoise, dt; OutDynamic[0, 0] = this.s0.fV(); for (int i = 1; i < steps; i++) { dt = Dates[i] - Dates[i - 1]; this.gamma = new Fairmat.Statistics.Gamma(dt / this.nu.fV(), 1.0 / this.nu.fV()); GammaNoise = this.gamma.Draw(Engine.Generator); OutDynamic[i, 0] = OutDynamic[i - 1, 0] * Math.Exp(this.drift * dt + this.theta.fV() * GammaNoise + this.sigma.fV() * Math.Sqrt(GammaNoise) * Noise[i - 1, 0]); } }
/// <summary> /// Calculates the value of a Bond under the Hull and White Two factors model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variables must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variables must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns>The value of the bond at index i using the HW2 model.</returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { double R = dynamic[i, 0]; double U = dynamic[i, 1]; double dt = this.context.timeDiscretization.dt(i); double Ps = ZCB(s); double Pt = ZCB(t); double Pdt = ZCB(t + dt); if (Engine.Log) { if (SolverContext.SimulationRealization == 0) { Log.Write(string.Format("BOND i={0} Ps={1} Pt={2}", i, Ps, Pt)); } } return(BondHW2(this.context, this.cache, this, R, U, Ps, Pt, Pdt, s, t, dt)); }
/// <summary> /// Calculates the probability of a default at date t (conditional /// of being in a given state (realization) of process s1, s2), /// being on period s = dates[j]. /// </summary> /// <param name="dynamic">The underlying's realizations.</param> /// <param name="dates">The corresponding underlying's dates.</param> /// <param name="j">The wanted date index.</param> /// <param name="t">The date at which we want to estimate the default prob.</param> /// <returns>The default probability estimation.</returns> public double CDSDefaultP(IReadOnlyMatrixSlice dynamic, double[] dates, int j, double t) { double tau = t - dates[j]; double RRate = 0.4; double s1 = dynamic[j, 0]; double s2 = dynamic[j, 1]; double final = t; double ZR = GetZR(final); // PTau. double discf = Math.Exp(-ZR * tau); double num_A1 = 2 * this.gamma1 * Math.Exp((this.k1.fV() + this.gamma1) * tau / 2.0); double num_A2 = 2 * this.gamma2 * Math.Exp((this.k2.fV() + this.gamma2) * tau / 2.0); double eg1 = Math.Exp(this.gamma1 * tau) - 1; double eg2 = Math.Exp(this.gamma2 * tau) - 1; double den_A1 = (this.k1.fV() + this.gamma1) * eg1 + 2 * this.gamma1; double den_A2 = (this.k2.fV() + this.gamma2) * eg2 + 2 * this.gamma2; double A1 = Math.Pow(num_A1 / den_A1, (2 * this.k1.fV() * this.theta1.fV()) / this.sigma12); double A2 = Math.Pow(num_A2 / den_A2, (2 * this.k2.fV() * this.theta2.fV()) / this.sigma22); double B1 = 2.0 * eg1 / den_A1; double B2 = 2.0 * eg2 / den_A2; double gg = discf * A1 * Math.Exp(-B1 * s1) * A2 * Math.Exp(-B2 * s2); double gd = RRate * discf + (1 - RRate) * gg; double y = -(1.0 / tau) * Math.Log(gd); double sd = y - ZR; double pdcum = (1 - Math.Exp(-sd * tau)) / (1.0 - RRate); return(pdcum); }
/// <summary> /// Calculates the value of a Bond under the Pelsser model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variables must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variables must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns>The value of the bound at index i using the Pelsser model.</returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { // Handles special case. if (t == s) return 1; // Get the value of the short rate. double y = Math.Sqrt(dynamic[i, 0]) - this.alphaT0[i]; PelsserKey k = new PelsserKey(t, s); PelsserCache cachedValue = null; lock (this.cache) { if (this.cache.ContainsKey(k)) cachedValue = this.cache[k]; else { cachedValue = new PelsserCache(t, s, this); // Insert the value in the cache. this.cache.Add(k, cachedValue); } } double v = Math.Exp(cachedValue.A - y * cachedValue.B - (y * y) * cachedValue.CtT0); return v; }
/// <summary> /// Calculates the probability of a default at date t (conditional /// of being in a given state (realization) of process s1, s2), /// being on period s = dates[j]. /// </summary> /// <param name="dynamic">The underlying's realizations.</param> /// <param name="dates">The corresponding underlying's dates.</param> /// <param name="j">The wanted date index.</param> /// <param name="t">The date at which we want to estimate the default prob.</param> /// <returns>The default probability estimation.</returns> public double CDSDefaultP(IReadOnlyMatrixSlice dynamic, double[] dates, int j, double t) { double tau = t - dates[j]; double RRate = 0.4; double s1 = dynamic[j, 0]; double s2 = dynamic[j, 1]; double final = t; double ZR = GetZR(final); // PTau. double discf = Math.Exp(-ZR * tau); double num_A1 = 2 * this.gamma1 * Math.Exp((this.k1.fV() + this.gamma1) * tau / 2.0); double num_A2 = 2 * this.gamma2 * Math.Exp((this.k2.fV() + this.gamma2) * tau / 2.0); double eg1 = Math.Exp(this.gamma1 * tau) - 1; double eg2 = Math.Exp(this.gamma2 * tau) - 1; double den_A1 = (this.k1.fV() + this.gamma1) * eg1 + 2 * this.gamma1; double den_A2 = (this.k2.fV() + this.gamma2) * eg2 + 2 * this.gamma2; double A1 = Math.Pow(num_A1 / den_A1, (2 * this.k1.fV() * this.theta1.fV()) / this.sigma12); double A2 = Math.Pow(num_A2 / den_A2, (2 * this.k2.fV() * this.theta2.fV()) / this.sigma22); double B1 = 2.0 * eg1 / den_A1; double B2 = 2.0 * eg2 / den_A2; double gg = discf * A1 * Math.Exp(-B1 * s1) * A2 * Math.Exp(-B2 * s2); double gd = RRate * discf + (1 - RRate) * gg; double y = -(1.0 / tau) * Math.Log(gd); double sd = y - ZR; double pdcum = (1 - Math.Exp(-sd * tau)) / (1.0 - RRate); return pdcum; }
public void Simulate(double[] Dates, IReadOnlyMatrixSlice Noise, IMatrixSlice OutDynamic) { OutDynamic[0, 0] = x0[0]; for (int i = 1; i < Dates.Length; i++) { double dt= Dates[i]-Dates[i-1]; double rdt=Math.Sqrt(dt); double th = theta(Dates[i], dt); OutDynamic[i, 0] = OutDynamic[i-1, 0]+(th - alpha1Temp * OutDynamic[i - 1, 0]) * dt + sigma1Temp * Noise[i - 1, 0] * rdt; } }
/// <summary> /// Calculates the value of a Bond under the Hull and White model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variable must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variable must be sampled. /// </param> /// <param name='T'> /// The maturity of the bond. /// </param> /// <returns>The value of the bound at index i using the HW model.</returns> public virtual double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double T) { #if TFORWARDFORMULATION double y = dynamic[i, 0] - this.alphaT[i]; return Math.Exp(A(t, T, this.alpha1Temp, this.sigma1Temp, this.zeroRateCurve) - y * B(T - t, this.alpha1Temp)); #else throw new NotImplementedException(); #endif }
/// <summary> /// Calculates the value of a Bond under the Cox-Ingersoll-Ross model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variable must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variable must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns> /// The value of the bound at index i using the Cox-Ingersoll-Ross model. /// </returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { double r = dynamic[i, 0]; double T = s - t; double den = (this.alphaTemp + this.d) * (Math.Exp(this.d * T) - 1.0) + 2.0 * this.d; double A = Math.Pow(2.0 * this.d * Math.Exp(0.5 * (this.alphaTemp + this.d) * T) / den, this.nu); double B = 2.0 * (Math.Exp(this.d * T) - 1.0) / den; return A * Math.Exp(-r * B); }
/// <summary> /// Simulate a realization of the stochastic process driven by the noise matrix noise. /// </summary> /// <remarks> /// This function is called once for realization. /// </remarks> /// <param name="dates"> /// The dates (in years fractions) at which the process must be simulated. /// </param> /// <param name="noise">The matrix of IID normal realizations.</param> /// <param name="outDynamic">Where the dynamic should be written.</param> public void Simulate(double[] dates, IReadOnlyMatrixSlice noise, IMatrixSlice outDynamic) { switch (OperatingMode) { case OperatingMode.TranslateHistoricalRealizationsForward: for (int i = 0; i < dates.Length; i++) { int dateIndex; if (!this.simulationDateIndexes.TryGetValue(dates[i], out dateIndex)) dateIndex = 0; Tuple<DateTime, Vector> value = this.fileContent[dateIndex]; for (int j = 0; j < value.Item2.Length - 1; j++) { outDynamic[i, j] = value.Item2[j]; } } break; case OperatingMode.Bootstrap: this.bootstrap.Simulate(dates, outDynamic); break; } }
/// <summary> /// Calculates the value of a Bond under the Hull and White Two factors model. /// </summary> /// <param name='dynamic'> /// The simulated process. /// </param> /// <param name='dates'> /// The vector of reference dates. /// </param> /// <param name='i'> /// The index at which the state variables must be sampled. /// </param> /// <param name='t'> /// The date in years/fractions at at which the state variables must be sampled. /// </param> /// <param name='s'> /// The maturity of the bond. /// </param> /// <returns>The value of the bond at index i using the HW2 model.</returns> public double Bond(IReadOnlyMatrixSlice dynamic, double[] dates, int i, double t, double s) { double R = dynamic[i, 0]; double U = dynamic[i, 1]; double dt = this.context.timeDiscretization.dt(i); double Ps = ZCB(s); double Pt = ZCB(t); double Pdt = ZCB(t + dt); if (Engine.Log) if (SolverContext.SimulationRealization == 0) Log.Write(string.Format("BOND i={0} Ps={1} Pt={2}", i, Ps, Pt)); return BondHW2(this.context, this.cache, this, R, U, Ps, Pt, Pdt, s, t, dt); }