/// <summary> /// Produce a vector of curves where the element at index i is a realization of a simulation at /// simulationDates i. If you require the rates directly use <see cref="GetSimulatedRates(Date[])"/> /// </summary> /// <param name="simulationDates">Dates on which the simulation is run. Must all be greater than the /// anchor date.</param> /// <returns></returns> public ICurve[] GetSimulatedCurves(Date[] simulationDates, Currency curveCcy = null) { if (curveCcy == null) { curveCcy = Currency.ANY; } var results = new ICurve[simulationDates.Length]; var dist = new Normal(); var previousDate = anchorDate; var previousRates = initialRates.Clone() as double[]; var currentRates = new double[initialRates.Length]; // Iterate through the simulation dates for (var simCounter = 0; simCounter < simulationDates.Length; simCounter++) { var currentDate = simulationDates[simCounter]; var dt = (currentDate - previousDate) / 365.0; var sdt = Math.Sqrt(dt); var curveDates = new Date[initialRates.Length]; // Random realizations to be used in simulation. var eps1 = dist.Sample(); var eps2 = dist.Sample(); var eps3 = dist.Sample(); // Iterate thrrough the dates on the curve for (var i = 0; i < initialRates.Length; i++) { curveDates[i] = simulationDates[simCounter].AddTenor(tenors[i]); if (useRelative) { //TODO: add mean correction. var exponent = components[0, i] * vols[0] * sdt * eps1 + components[1, i] * vols[1] * sdt * eps2 + components[2, i] * vols[2] * sdt * eps3; currentRates[i] = previousRates[i] * Math.Exp(exponent); } else { var change = components[0, i] * vols[0] * sdt * eps1 + components[1, i] * vols[1] * sdt * eps2 + components[2, i] * vols[2] * sdt * eps3; currentRates[i] = previousRates[i] + change; if (floorAtZero) { currentRates[i] = Math.Max(0.0, currentRates[i]); } } } currentRates = currentRates.Multiply(multiplier); results[simCounter] = new DatesAndRates(curveCcy, simulationDates[simCounter], curveDates, currentRates, simulationDates[simCounter].AddMonths(360)); previousRates = currentRates.Clone() as double[]; previousDate = new Date(currentDate); } return(results); }
/// <summary> /// Create a curve that linearly interpolates the provided forward rates. Rates are not used to get discount factors. /// </summary> /// <remarks> /// If you want to obtain discount factors from the provided rates rather use: <see cref="DatesAndRates"/></remarks> /// <param name="anchorDate"></param> /// <param name="index"></param> /// <param name="dates"></param> /// <param name="rates"></param> /// <param name="maximumDate"></param> public ForecastCurve(Date anchorDate, FloatingIndex index, Date[] dates, double[] rates, Date maximumDate = null) { this.index = index; dateAndRates = new DatesAndRates(Currency.ANY, anchorDate, dates, rates, maximumDate); }