Exemple #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="timeGrid">Time discretisation used.</param>
 /// <param name="factors">Number of factors in the model.</param>
 /// <param name="weights">Precomputed swaption weights.</param>
 /// <param name="correlation">A homogeneous forward correlation matrix.</param>
 public InterestRateVolatilities(PedersenTimeGrid timeGrid, int factors, SwaptionWeights weights, DenseMatrix correlation)
 {
     _volFixed    = false;
     _timeGrid    = timeGrid;
     _factors     = factors;
     _weights     = weights;
     _correlation = correlation;
     _volatility  = new Matrix[_timeGrid.MaxExpiry];
     for (int i = 0; i < _timeGrid.MaxExpiry; i++)
     {
         _volatility[i] = new Matrix(_timeGrid.MaxTenor, _factors);
     }
     _storedImpliedVol     = new double[_timeGrid.MaxExpiry][];
     _storedImpliedVolSq   = new double[_timeGrid.MaxExpiry][];
     _storedImpliedVolTerm = new double[_timeGrid.MaxExpiry][][];
     for (int i = 0; i < _timeGrid.MaxExpiry; i++)
     {
         _storedImpliedVol[i]     = new double[_timeGrid.MaxTenor - i];
         _storedImpliedVolSq[i]   = new double[_timeGrid.MaxTenor - i];
         _storedImpliedVolTerm[i] = new double[_timeGrid.MaxTenor - i][];
         for (int j = 0; j < _timeGrid.MaxTenor - i; j++)
         {
             _storedImpliedVolTerm[i][j] = new double[i + 1];
         }
     }
 }
Exemple #2
0
        private DenseMatrix SetXi(int exp, Vector x)
        {
            var cor = _economy.Correlation;
            var cov = new Matrix(_param.NumberOfTenors, _param.NumberOfTenors);

            for (int i = 0; i < _param.NumberOfTenors; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    cov[i, j] = cor[i, j] * x[i] * x[j];
                }
            }
            var eigenValueDecomposition = new EigenvalueDecomposition(cov);
            var baseVector   = eigenValueDecomposition.RealEigenvalues.ToList();
            var eval         = baseVector.GetRange(_param.NumberOfTenors - _param.NumberOfFactors, _param.NumberOfTenors - 1 + _param.NumberOfFactors);//Select the sub-vector starting at the index i and with length y
            var baseMatrix   = eigenValueDecomposition.EigenVectors;
            var eigenVectors = baseMatrix.GetMatrix(0, baseMatrix.RowCount - 1, _param.NumberOfTenors - _param.NumberOfFactors, _param.NumberOfTenors - 1);
            var xiSection    = new DenseMatrix(_param.UnderlyingTenor, _param.NumberOfFactors);

            for (int j = 0; j < _param.NumberOfFactors; j++)
            {
                eval[j] = Math.Sqrt(eval[j]);
                for (int i = 0; i < _param.NumberOfTenors; i++)
                {
                    var temp = eval[j] * eigenVectors[i, j];
                    for (int n = _param.Tenor[i]; n < Math.Min(_param.Tenor[i + 1], _param.UnderlyingTenor - _param.Expiry[exp]); n++)
                    {
                        xiSection[n, j] = temp;
                    }
                }
            }
            return(xiSection);
        }
Exemple #3
0
        /// <summary>
        /// Computes the implied volatility of swaption with given expiry and tenor, or a caplet with given expiry,
        /// with the volatility at one particular expiry time bucket replaced with temporary values.
        /// A caplet implied volatility is equivalent to that of a swaption with the tenor length of 1.
        /// Saves computation time when checking the effect of a simple perturbation.
        /// </summary>
        /// <param name="expiry"></param>
        /// <param name="tenor"></param>
        /// <param name="newRow">Indicating the expiry time bucket to be replaced.</param>
        /// <param name="replacedRow">New interest rate volatility values for the expiry time bucket.</param>
        /// <returns></returns>
        public double FindImpliedVolatility(int expiry, int tenor, Matrix newRow, int replacedRow)
        {
            int    exp = expiry - 1;
            int    ten = tenor - 1;
            double result;

            if (exp >= _timeGrid.ExpiryGrid[replacedRow])
            {
                result = _storedImpliedVolSq[exp][ten];
                for (int i = _timeGrid.ExpiryGrid[replacedRow]; i < Math.Min(_timeGrid.ExpiryGrid[replacedRow + 1], expiry); i++)
                {
                    var tempVector = new DenseVector(_factors);
                    for (int j = 0; j <= ten; j++)
                    {
                        tempVector = tempVector + _weights.Get(expiry, tenor, j + 1) * newRow.RowD(j + exp - i);
                    }
                    double tempSum = tempVector * tempVector;
                    result += tempSum - _storedImpliedVolTerm[exp][ten][i];
                }
                result = Math.Sqrt(result / expiry);
            }
            else
            {
                result = _storedImpliedVol[exp][ten];
            }
            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Computes the volatilities of a particular expiry time bucket.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="inputVol"></param>
        /// <returns></returns>
        public Matrix SingleRowOfVolatilities(int row, Vector inputVol)
        {
            //create covariance
            var covariance = new Matrix(_timeGrid.TenorCount, _timeGrid.TenorCount);

            for (int i = 0; i < _timeGrid.TenorCount; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    covariance[i, j] = _correlation[i, j] * inputVol[i] * inputVol[j];
                }
            }
            //principal component analysis
            var eigenValueDecomposition = new EigenvalueDecomposition(covariance);
            var baseVector   = eigenValueDecomposition.RealEigenvalues.ToList();
            var eval         = baseVector.GetRange(_timeGrid.TenorCount - 1 - _factors, _factors);//Select the sub-vector starting at the index i and with length y
            var baseMatrix   = eigenValueDecomposition.EigenVectors;
            var eigenVectors = baseMatrix.GetMatrix(0, baseMatrix.RowCount - 1, _timeGrid.TenorCount - _factors, _timeGrid.TenorCount - 1);
            var resultVol    = new Matrix(_timeGrid.MaxTenor, _factors);

            for (int j = 0; j < _factors; j++)
            {
                eval[j] = Math.Sqrt(eval[j]);
                for (int i = 0; i < _timeGrid.TenorCount; i++)
                {
                    var temp = eval[j] * eigenVectors[i, j];
                    for (int n = _timeGrid.TenorGrid[i]; n < Math.Min(_timeGrid.TenorGrid[i + 1], _timeGrid.MaxTenor - _timeGrid.ExpiryGrid[row]); n++)
                    {
                        resultVol[n, j] = temp;
                    }
                }
            }
            return(resultVol);
        }
Exemple #5
0
        private double SmoothV(Matrix <double> xMatrix)
        {
            double total = 0;

            for (int i = 0; i < _param.NumberOfExpiries - 1; i++)
            {
                for (int j = 0; j < _param.NumberOfTenors; j++)
                {
                    double temp = Math.Log(xMatrix[i, j] / xMatrix[i + 1, j]);
                    total += temp * temp;
                }
            }
            total = total * _vFactor;
            return(total);
        }
Exemple #6
0
 private void PopulateXi(Matrix <double> xMatrix)
 {
     for (int i = 0; i < _param.NumberOfExpiries; i++)
     {
         var gm = SetXi(i, (DenseVector)xMatrix.Row(i));
         for (int j = _param.Expiry[i]; j < _param.Expiry[i + 1]; j++)
         {
             for (int k = 0; k < _param.UnderlyingTenor - j; k++)
             {
                 for (int l = 0; l < _param.NumberOfFactors; l++)
                 {
                     _economy.Xi[j][k, l] = gm[k, l];
                 }
             }
             //economy.Xi[j] = (GeneralMatrix)gm.Clone();
         }
     }
 }
Exemple #7
0
 /// <summary>
 /// Computes the multi-factored volatilities given a particular input volatility grid, using principal component analysis.
 /// (See Pedersen, M. B. (1998) Calibrating Libor market models. Working paper, Financial Research Department, SimCorp.)
 /// </summary>
 /// <param name="inputVolMat"></param>
 public void Populate(Matrix inputVolMat)
 {
     if (!_volFixed)
     {
         for (int i = 0; i < _timeGrid.ExpiryCount; i++)
         {
             var currentRow = SingleRowOfVolatilities(i, inputVolMat.RowD(i));
             for (int j = _timeGrid.ExpiryGrid[i]; j < _timeGrid.ExpiryGrid[i + 1]; j++)
             {
                 for (int k = 0; k < _timeGrid.MaxTenor - j; k++)
                 {
                     for (int l = 0; l < _factors; l++)
                     {
                         _volatility[j][k, l] = currentRow[k, l];
                     }
                 }
             }
         }
     }
     else
     {
         throw new Exception("Cannot alter finalised volatility.");
     }
 }