예제 #1
0
        public LfmHullWhiteParameterization(
            LiborForwardModelProcess process,
            OptionletVolatilityStructure capletVol,
            Matrix correlation, int factors)
            : base(process.size(), factors)
        {
            diffusion_   = new Matrix(size_ - 1, factors_);
            fixingTimes_ = process.fixingTimes();

            Matrix sqrtCorr = new Matrix(size_ - 1, factors_, 1.0);

            if (correlation.empty())
            {
                Utils.QL_REQUIRE(factors_ == 1, () => "correlation matrix must be given for multi factor models");
            }
            else
            {
                Utils.QL_REQUIRE(correlation.rows() == size_ - 1 &&
                                 correlation.rows() == correlation.columns(), () => "wrong dimesion of the correlation matrix");

                Utils.QL_REQUIRE(factors_ <= size_ - 1, () => "too many factors for given LFM process");

                Matrix tmpSqrtCorr = MatrixUtilitites.pseudoSqrt(correlation,
                                                                 MatrixUtilitites.SalvagingAlgorithm.Spectral);

                // reduce to n factor model
                // "Reconstructing a valid correlation matrix from invalid data"
                // (<http://www.quarchome.org/correlationmatrix.pdf>)
                for (int i = 0; i < size_ - 1; ++i)
                {
                    double d = 0;
                    tmpSqrtCorr.row(i).GetRange(0, factors_).ForEach((ii, vv) => d += vv * tmpSqrtCorr.row(i)[ii]);
                    for (int k = 0; k < factors_; ++k)
                    {
                        sqrtCorr[i, k] = tmpSqrtCorr.row(i).GetRange(0, factors_)[k] / Math.Sqrt(d);
                    }
                }
            }
            List <double> lambda      = new List <double>();
            DayCounter    dayCounter  = process.index().dayCounter();
            List <double> fixingTimes = process.fixingTimes();
            List <Date>   fixingDates = process.fixingDates();

            for (int i = 1; i < size_; ++i)
            {
                double cumVar = 0.0;
                for (int j = 1; j < i; ++j)
                {
                    cumVar += lambda[i - j - 1] * lambda[i - j - 1]
                              * (fixingTimes[j + 1] - fixingTimes[j]);
                }

                double vol = capletVol.volatility(fixingDates[i], 0.0, false);
                double var = vol * vol
                             * capletVol.dayCounter().yearFraction(fixingDates[0],
                                                                   fixingDates[i]);
                lambda.Add(Math.Sqrt((var - cumVar)
                                     / (fixingTimes[1] - fixingTimes[0])));
                for (int q = 0; q < factors_; ++q)
                {
                    diffusion_[i - 1, q] = sqrtCorr[i - 1, q] * lambda.Last();
                }
            }
            covariance_ = diffusion_ * Matrix.transpose(diffusion_);
        }
예제 #2
0
        // calculating swaption volatility matrix using
        // Rebonatos approx. formula. Be aware that this
        // matrix is valid only for regular fixings and
        // assumes that the fix and floating leg have the
        // same frequency
        public SwaptionVolatilityMatrix getSwaptionVolatilityMatrix()
        {
            if (swaptionVola != null)
            {
                return(swaptionVola);
            }

            IborIndex index = process_.index();
            Date      today = process_.fixingDates()[0];

            int    size         = process_.size() / 2;
            Matrix volatilities = new Matrix(size, size);

            List <Date> exercises = new InitializedList <Date>(size);

            for (int i = 0; i < size; ++i)
            {
                exercises[i] = process_.fixingDates()[i + 1];
            }

            List <Period> lengths = new InitializedList <Period>(size);

            for (int i = 0; i < size; ++i)
            {
                lengths[i] = (i + 1) * index.tenor();
            }

            Vector f = process_.initialValues();

            for (int k = 0; k < size; ++k)
            {
                int    alpha   = k;
                double t_alpha = process_.fixingTimes()[alpha + 1];

                Matrix var = new Matrix(size, size);
                for (int i = alpha + 1; i <= k + size; ++i)
                {
                    for (int j = i; j <= k + size; ++j)
                    {
                        var[i - alpha - 1, j - alpha - 1] = var[j - alpha - 1, i - alpha - 1] =
                            covarProxy_.integratedCovariance(i, j, t_alpha, null);
                    }
                }

                for (int l = 1; l <= size; ++l)
                {
                    int    beta = l + k;
                    Vector w    = w_0(alpha, beta);

                    double sum = 0.0;
                    for (int i = alpha + 1; i <= beta; ++i)
                    {
                        for (int j = alpha + 1; j <= beta; ++j)
                        {
                            sum += w[i] * w[j] * f[i] * f[j] * var[i - alpha - 1, j - alpha - 1];
                        }
                    }
                    volatilities[k, l - 1] =
                        Math.Sqrt(sum / t_alpha) / S_0(alpha, beta);
                }
            }

            return(swaptionVola = new SwaptionVolatilityMatrix(today, exercises, lengths,
                                                               volatilities, index.dayCounter()));
        }