コード例 #1
0
        /// <summary>
        /// More general Constructor
        /// </summary>
        /// <param name="yieldCurve"></param>
        /// <param name="correlation"></param>
        /// <param name="volatility"></param>
        /// <param name="tenorStructure"></param>
        /// <param name="randomSeed"></param>
        public LiborMarketModel(YieldCurve yieldCurve,
                                Matrix <double> correlation,
                                Func <double, double>[] volatility,
                                DateTime[] tenorStructure,
                                int randomSeed = 42)
        {
            YieldCurve = yieldCurve;

            RandomGenerator = new MersenneTwister(randomSeed);

            Correlation = correlation;
            Volatility  = volatility;
            SettleDate  = yieldCurve.SettleDate;
            // Use continuous time in units of years for tenor structure
            T = Vector <double> .Build
                .DenseOfEnumerable(Utilities.ConvertToDayCountFraction(SettleDate, tenorStructure));

            // Initial discount factors: T[i] :-> B(0, T[i]) i =0, ..., n = length(T)-1
            InitialDiscountFactor = yieldCurve.GetDiscountFactors(tenorStructure);

            #region Tenors

            // tenors (day-count fraction) in units of [years]
            // Alpha[i] = T[i]-T[i+1], i = 0,...,n - 1
            Alpha = Vector <double> .Build.DenseOfEnumerable(T.Skip(1)) - Vector <double> .Build.DenseOfEnumerable(T.Take(T.Count - 1));

            // Choose terminal measure, can be an value between 0,..., n = length(T)-1
            NumeraireIndex = T.Count - 1;

            #endregion Tenors

            #region Initial Forward rate

            NumRates = T.Count - 1;

            // B[i]
            var zeroBond0 = Vector <double> .Build
                            .DenseOfEnumerable(InitialDiscountFactor.Take(NumRates));

            // B[i+1]
            var zeroBond1 = Vector <double> .Build
                            .DenseOfEnumerable(InitialDiscountFactor.Skip(1));

            // Initial forward LIBOR rate
            // L[i] = L(0, T[i],T[i+1]) = 1/alpha[i] * (B[i]/B[i+1] - 1); i = 0,..., n - 1
            // L[i](t) : 0 <= t <= T[i]
            InitialForwardRate = (zeroBond0.PointwiseDivide(zeroBond1).Subtract(1)).PointwiseDivide(Alpha);

            #endregion Initial Forward rate

            // Delta for smile
            Delta = Vector <double> .Build.Dense(NumRates);
        }
コード例 #2
0
        /// <summary>
        /// Simulate forward rates and corresponding zero rates on the
        /// interval [settleDate, tmax]
        /// step in [months]
        /// </summary>
        public LiborMarketModelPath SimulateForwardRates(DateTime maxDate, int step = 3)
        {
            #region Numeraire

            // Numeraire at time 0: N(0) = B(0, T[k])
            var intialNumeraire = InitialDiscountFactor[NumeraireIndex];

            #endregion Numeraire

            #region Time discertization

            // Initialize rates
            //t = linspace(0, length(model.T(end-1)), 100);

            // Use 3 Month time step
            var dates = Utilities.TenorStructure(SettleDate, maxDate, step);

            // Convert to continous time in units of [years]
            var t = Utilities.ConvertToDayCountFraction(SettleDate, dates);

            #endregion Time discertization

            #region Forward rate

            // Initialize forward rate with its at time t = 0 value;
            var forwaredRates = Matrix <double> .Build.Dense(NumRates, t.Length);

            forwaredRates.SetColumn(0, InitialForwardRate);

            // Propagate forward rates
            for (var j = 0; j < t.Length - 1; j++)
            {
                var dt = t[j + 1] - t[j];

                var forwardrate = PropagteForwardRate(t[j], forwaredRates.Column(j), NumeraireIndex, dt);

                forwaredRates.SetColumn(j + 1, forwardrate);
            }

            #endregion Forward rate

            #region Numeraire adjusted discount factor

            // Initialize numeraire-adjusted-discount factor with its at time t = 0 value;
            // D[i] = B[i]/B[k], where B[k] is the numeraire , i = 0, ..., n = length(T)-1
            // D[i]: 0 <= t <= min(T[i], T[k])
            // numeraireAdjustedDiscountFactors
            var discountFactors = Matrix <double> .Build.Dense(T.Count, t.Length);

            discountFactors.SetColumn(0, InitialDiscountFactor.Divide(intialNumeraire));

            // Numeraire-adjusted discount factors
            for (var j = 1; j < t.Length; j++)
            {
                // forward rate for time t[j]
                var forwardRate    = forwaredRates.Column(j);
                var discountFactor = Vector <double> .Build.Dense(T.Count);

                for (var i = 0; i < discountFactor.Count; i++)
                {
                    #region Check time

                    // Discount factor is not defined
                    if (t[j] > Math.Min(T[i], T[NumeraireIndex]))
                    {
                        discountFactor[i] = double.NaN;
                        continue;
                    }

                    #endregion Check time

                    #region Compute numeraire adjusted discount factors from forward rate
                    if (i == NumeraireIndex)
                    {
                        discountFactor[i] = 1;
                    }
                    else if (i < NumeraireIndex)
                    {
                        var prod = 1.0;
                        for (var k = i; k <= NumeraireIndex - 1; k++)
                        {
                            prod *= 1 + Alpha[k] * forwardRate[k];
                        }
                        discountFactor[i] = prod;
                    }
                    else if (i > NumeraireIndex)
                    {
                        var prod = 1.0;
                        for (var k = NumeraireIndex; k <= i - 1; k++)
                        {
                            prod *= 1 + Alpha[k] * forwardRate[k];
                        }
                        discountFactor[i] = 1.0 / prod;
                    }
                    #endregion Compute numeraire adjusted discount factors from forward rate
                }
                discountFactors.SetColumn(j, discountFactor);
            }

            #endregion Numeraire adjusted discount factor

            #region Result

            return(new LiborMarketModelPath
            {
                SettleDate = SettleDate,
                Dates = dates,
                Tenors = Alpha,
                TenorStructure = Utilities.ConvertFromDayCountFraction(SettleDate, T.ToArray()),
                ForwardRates = forwaredRates,
                NumeraireAdjustedDiscountFactors = discountFactors,
                InitialNumeraire = intialNumeraire
            });

            #endregion Result
        }