/// <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);
        }
Beispiel #2
0
 /// <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);
 }