예제 #1
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.");
     }
 }
예제 #2
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);
        }