Esempio n. 1
0
        ///<summary>
        ///</summary>
        ///<param name="discount"></param>
        ///<param name="shift"></param>
        public void Populate(QuarterlyDiscounts discount, QuarterlyShifts shift)
        {
            var forward                      = new double[_maxTenor + 1];
            var accumForward                 = new double[_maxTenor + 1];
            var accumForwardTimesRate        = new double[_maxTenor + 1];
            var accumForwardTimesShiftedRate = new double[_maxTenor + 1];

            accumForward[0]                 = 0;
            accumForwardTimesRate[0]        = 0;
            accumForwardTimesShiftedRate[0] = 0;
            var w = new double[_maxTenor];
            var h = new double[_maxTenor];

            for (int i = 0; i < _maxExpiry; i++)
            {
                for (int j = 0; j < _maxTenor - i; j++)
                {
                    //See "Engineering BGM" page 34 for explicit formula. Function definitions can be found in chapter 4.
                    forward[j + 1]      = RateAnalytics.ForwardContract(i + 1, i + j + 2, discount);
                    accumForward[j + 1] = accumForward[j] + forward[j + 1];
                    accumForwardTimesRate[j + 1]
                        = accumForwardTimesRate[j] + forward[j + 1] * RateAnalytics.CashForwardRate(i + j + 1, discount);
                    accumForwardTimesShiftedRate[j + 1]
                         = accumForwardTimesShiftedRate[j] + forward[j + 1] * RateAnalytics.ShiftedCashForwardRate(i + j + 1, discount, shift);
                    h[j] = 0.25 * RateAnalytics.ShiftedCashForwardRate(i + j + 1, discount, shift) / (1 + 0.25 * RateAnalytics.CashForwardRate(i + j + 1, discount));
                    for (int k = 0; k < j + 1; k++)
                    {
                        w[k] = forward[k + 1] * RateAnalytics.ShiftedCashForwardRate(i + k + 1, discount, shift) / accumForwardTimesShiftedRate[j + 1];
                        _weights[i][j][k] = w[k] - h[k] * ((accumForwardTimesRate[j + 1] - accumForwardTimesRate[k]) / accumForwardTimesShiftedRate[j + 1]
                                                           - (1 - accumForward[k] / accumForward[j + 1]) * accumForwardTimesRate[j + 1] / accumForwardTimesShiftedRate[j + 1]);
                    }
                }
            }
        }
Esempio n. 2
0
        private static double AdjustCapletImpliedVol(int expiry, double volatility, QuarterlyDiscounts discount, QuarterlyShifts shift)
        {
            double strike      = RateAnalytics.CashForwardRate(expiry, discount);
            double capletPrice = BlackModel.GetValue(expiry / 4.0, strike, strike, volatility, PayStyle.Call);
            double result      = BlackModel.GetImpliedVolatility(expiry / 4.0, strike + shift.Get(expiry), strike + shift.Get(expiry), capletPrice, volatility, PayStyle.Call);

            return(result);
        }
Esempio n. 3
0
 ///<summary>
 ///</summary>
 ///<param name="discount"></param>
 ///<param name="shift"></param>
 public void AdjustImpliedVolsForShift(QuarterlyDiscounts discount, QuarterlyShifts shift)
 {
     if (!AdjustedForShift)
     {
         AdjustedForShift = true;
         for (int i = 0; i < CapletCount; i++)
         {
             CapletImpliedVol[i] = AdjustCapletImpliedVol(CapletExpiry[i], CapletImpliedVol[i], discount, shift);
         }
         for (int i = 0; i < SwaptionCount; i++)
         {
             SwaptionImpliedVol[i] = AdjustSwaptionImpliedVol(SwaptionExpiry[i], SwaptionTenor[i], SwaptionImpliedVol[i], discount, shift);
         }
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Main calibration method.
        /// </summary>
        /// <param name="timeGrid">Time discretisation</param>
        /// <param name="discount">Quarterly discount factors</param>
        /// <param name="shift">Quarterly shift values</param>
        /// <param name="correlation">Correlation matrix, corresponding the tenor time discretisation</param>
        /// <param name="targets">Caplet and swaption implied vols</param>
        /// <param name="parameters">Calibration settings</param>
        /// <param name="factors">Factors used</param>
        /// <param name="useCascade">Whether to apply cascade algorithm post-calibration</param>
        /// <param name="output"></param>
        /// <returns></returns>
        public static InterestRateVolatilities Calibrate(PedersenTimeGrid timeGrid, QuarterlyDiscounts discount,
                                                         QuarterlyShifts shift, DenseMatrix correlation, CalibrationTargets targets,
                                                         CalibrationSettings parameters, int factors, bool useCascade, ref string output)
        {
            #region Initialisations

            targets.AdjustImpliedVolsForShift(discount, shift);
            var swaptionWeights = new SwaptionWeights(timeGrid.MaxExpiry, timeGrid.MaxTenor);
            swaptionWeights.Populate(discount, shift);
            var volatilities = new InterestRateVolatilities(timeGrid, factors, swaptionWeights, correlation);
            var objective    = new CalibrationObjective(targets, timeGrid, volatilities, parameters);
            Func <Vector <double>, double>           f = objective.ObjFun;
            Func <Vector <double>, Vector <double> > g = objective.ObjGrad;
            var    initialGuess = new DenseVector(timeGrid.ExpiryCount * timeGrid.TenorCount);
            double guessValue   = targets.AverageImpliedVol();
            if (guessValue == 0)
            {
                throw new Exception("The selected time range does not include any calibration targets.");
            }
            if (parameters.ExponentialForm)
            {
                for (var i = 0; i < initialGuess.Count; i++)
                {
                    initialGuess[i] = Math.Log(guessValue) / 20;
                }
            }
            else
            {
                for (var i = 0; i < initialGuess.Count; i++)
                {
                    initialGuess[i] = guessValue;
                }
            }
            Trace.WriteLine(String.Format("Calibration Starting..."));
            objective.StartOtherThreads();
            var solution = BfgsSolver.Solve(initialGuess, f, g);
            objective.Finished = true;
            Trace.WriteLine($"Value at extremum: {solution}");
            objective.PopulateVol(solution);
            objective.AverageAbsVol();

            #endregion

            #region Cascade

            if (useCascade)
            {
                Trace.WriteLine(String.Format("Applying Cascade Algorithm..."));
                var cascade = new CascadeAlgorithm(volatilities, timeGrid, swaptionWeights, targets, parameters.CascadeParam, factors);
                cascade.ApplyCascade();
            }

            #endregion

            #region Output

            output = objective.AverageAbsVol();
            return(objective.ReturnVol(solution));

            #endregion
        }
Esempio n. 5
0
        private static double AdjustSwaptionImpliedVol(int expiry, int tenor, double volatility, QuarterlyDiscounts discount, QuarterlyShifts shift)
        {
            double strike        = RateAnalytics.SwapRate(expiry, tenor, discount);
            double swapShift     = RateAnalytics.SwapShift(expiry, tenor, discount, shift);
            double swaptionPrice = BlackModel.GetValue(expiry / 4.0, strike, strike, volatility, PayStyle.Call);
            double result        = BlackModel.GetImpliedVolatility(expiry / 4.0, strike + swapShift, strike + swapShift, swaptionPrice, volatility, PayStyle.Call);

            return(result);
        }