예제 #1
0
 /// <summary>
 /// Returns the Strike vector embedded in the volatility matrix.
 /// The method manage the convention that if rates/strikes [defined in .ColumnValues fields] are equal to -1,
 /// the strike vector is ATM and must be derived from the term structure.
 /// </summary>
 /// <param name="normalVol">The matrix</param>
 /// <param name="zr">The term structure.</param>
 /// <returns>The strike vector.</returns>
 static Vector GetStrikes(MatrixMarketData normalVol, IFunction zr)
 {
     if (IsAtmMatrix(normalVol))
     {
         // builds the vector of ATM strikes
         var s = new Vector(normalVol.RowValues.Length);
         for (int j = 0; j < s.Length; j++)
         {
             s[j] = zr.Evaluate(normalVol.RowValues[j]);
         }
         return(s);
     }
     else
     {
         return(normalVol.ColumnValues);
     }
 }
        /// <summary>
        /// Attempts a calibration through <see cref="PelsserCappletOptimizationProblem"/>
        /// using caps matrices.
        /// </summary>
        /// <param name="data">The data to be used in order to perform the calibration.</param>
        /// <param name="settings">The parameter is not used.</param>
        /// <param name="controller">The controller which may be used to cancel the process.</param>
        /// <returns>The results of the calibration.</returns>
        public EstimationResult Estimate(List <object> data, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null)
        {
            InterestRateMarketData dataset   = data[0] as InterestRateMarketData;
            MatrixMarketData       normalVol = null;

            if (data.Count > 1)
            {
                normalVol = (MatrixMarketData)data[1];
            }
            EstimationResult result;

            if ((dataset.ZRMarket == null) || (dataset.CapVolatility == null))
            {
                result = new EstimationResult();
                result.ErrorMessage = "Not enough data to calibrate.\n" +
                                      "The estimator needs a ZRMarket and a CapVolatility " +
                                      "defined inside InterestRateMarketData";
                return(result);
            }

            // Backup the dates
            DateTime effectiveDate = DateTime.Now.Date;
            DateTime valuationDate = DateTime.Now.Date;

            if (Document.ActiveDocument != null)
            {
                effectiveDate = Document.ActiveDocument.ContractDate;
                valuationDate = Document.ActiveDocument.SimulationStartDate;
            }

            // Creates the Context.
            Document   doc = new Document();
            ProjectROV prj = new ProjectROV(doc);

            doc.Part.Add(prj);

            Function zr = new PFunction(null);

            zr.VarName = "zr";
            // Load the zr.
            double[,] zrvalue = (double[, ])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray());
            zr.Expr           = zrvalue;

            prj.Symbols.Add(zr);


            var bm = BlackModelFactory(zr);

            if (bm is BachelierNormalModel)
            {
                (bm as BachelierNormalModel).Tenor = dataset.CapTenor;
            }

            double deltak = dataset.CapTenor;


            Matrix capVol = normalVol != null ? normalVol.Values:dataset.CapVolatility;
            Vector capMat = normalVol != null ? normalVol.RowValues: dataset.CapMaturity;
            Vector capK   = normalVol != null ? normalVol.ColumnValues: dataset.CapRate;

            var preferences = settings as Fairmat.Calibration.CapVolatilityFiltering;

            // Matrix calculated with black.
            var blackCaps = new Matrix(capMat.Length, capK.Length);

            for (int m = 0; m < capMat.Length; m++)
            {
                for (int s = 0; s < capK.Length; s++)
                {
                    bool skip = false;
                    if (preferences != null)
                    {
                        if (capK[s] < preferences.MinCapRate || capK[s] > preferences.MaxCapRate ||
                            capMat[m] < preferences.MinCapMaturity || capMat[m] > preferences.MaxCapMaturity)
                        {
                            skip = true;
                        }
                    }

                    if (capVol[m, s] == 0 || skip)
                    {
                        blackCaps[m, s] = 0;
                    }
                    else
                    {
                        blackCaps[m, s] = bm.Cap(capK[s], capVol[m, s], deltak, capMat[m]);
                    }
                }
            }

            if (blackCaps.IsNaN())
            {
                Console.WriteLine("Black caps matrix has non real values:");
                Console.WriteLine(blackCaps);
                throw new Exception("Cannot calculate Black caps");
            }

            // Maturity goes from 0 to the last item with step deltaK.
            Vector maturity = new Vector((int)(1.0 + capMat[capMat.Length - 1] / deltak));

            for (int l = 0; l < maturity.Length; l++)
            {
                maturity[l] = deltak * l;
            }

            Vector fwd = new Vector(maturity.Length - 1);

            for (int i = 0; i < fwd.Length; i++)
            {
                fwd[i] = bm.Fk(maturity[i + 1], deltak);
            }

            // Creates a default Pelsser model.
            Pelsser.SquaredGaussianModel model = new Pelsser.SquaredGaussianModel();
            model.a1     = (ModelParameter)0.014;
            model.sigma1 = (ModelParameter)0.001;
            model.zr     = (ModelParameter)"@zr";
            StochasticProcessExtendible iex = new StochasticProcessExtendible(prj, model);

            prj.Processes.AddProcess(iex);

            prj.Parse();

            DateTime t0 = DateTime.Now;
            Caplet   cp = new Caplet();

            PelsserCappletOptimizationProblem problem = new PelsserCappletOptimizationProblem(prj, cp, maturity, fwd, capK, deltak, capMat, blackCaps);

            IOptimizationAlgorithm solver  = new QADE();
            IOptimizationAlgorithm solver2 = new SteepestDescent();

            DESettings o = new DESettings();

            o.NP         = 35;
            o.TargetCost = 0.0025;
            o.MaxIter    = 10;
            o.Verbosity  = Math.Max(1, Engine.Verbose);
            o.controller = controller;
            // Parallel evaluation is not supported for this calibration.
            o.Parallel = false;
            o.Debug    = true;
            SolutionInfo solution = null;

            Vector x0 = (Vector) new double[] { 0.1, 0.1 };

            solution = solver.Minimize(problem, o, x0);
            if (solution.errors)
            {
                return(new EstimationResult(solution.message));
            }

            o.epsilon   = 10e-7;
            o.h         = 10e-7;
            o.MaxIter   = 1000;
            o.Debug     = true;
            o.Verbosity = Math.Max(1, Engine.Verbose);

            if (solution != null)
            {
                solution = solver2.Minimize(problem, o, solution.x);
            }
            else
            {
                solution = solver2.Minimize(problem, o, x0);
            }

            if (solution.errors)
            {
                return(new EstimationResult(solution.message));
            }

            Console.WriteLine(solution);

            string[] names = new string[] { "alpha1", "sigma1" };
            result = new EstimationResult(names, solution.x);

            result.ZRX        = (double[])dataset.ZRMarketDates.ToArray();
            result.ZRY        = (double[])dataset.ZRMarket.ToArray();
            result.Objects    = new object[1];
            result.Objects[0] = solution.obj;
            //result.Fit = solution.obj;//Uncomment in 1.6
            // Restore the dates
            if (Document.ActiveDocument != null)
            {
                Document.ActiveDocument.ContractDate        = effectiveDate;
                Document.ActiveDocument.SimulationStartDate = valuationDate;
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Attempts a calibration through <see cref="SwaptionHW1OptimizationProblem"/>
        /// using swaption matrices.
        /// </summary>
        /// <param name="data">The data to be used in order to perform the calibration.</param>
        /// <param name="settings">The parameter is not used.</param>
        /// <param name="controller">The controller which may be used to cancel the process.</param>
        /// <returns>The results of the calibration.</returns>
        public EstimationResult Estimate(List <object> data, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null)
        {
            InterestRateMarketData dataset   = data[0] as InterestRateMarketData;
            MatrixMarketData       normalVol = null;

            if (data.Count > 1)
            {
                normalVol = (MatrixMarketData)data[1];
            }

            PFunction zr = new PFunction(null);

            // Loads the zero rate.
            double[,] zrvalue = (double[, ])ArrayHelper.Concat(dataset.ZRMarketDates.ToArray(), dataset.ZRMarket.ToArray());
            zr.Expr           = zrvalue;

            double deltak = dataset.SwaptionTenor;

            Console.WriteLine("Swaption Tenor\t" + dataset.SwaptionTenor);

            var swaptionsFiltering = settings as SwaptionsFiltering;

            if (swaptionsFiltering == null)
            {
                swaptionsFiltering = new SwaptionsFiltering();//creates a default
            }
            //F stands for Full matrix
            var optionMaturityF      = normalVol != null ? normalVol.RowValues: dataset.OptionMaturity;
            var swapDurationF        = normalVol != null ? normalVol.ColumnValues: dataset.SwapDuration;
            var swaptionsVolatilityF = normalVol != null ? normalVol.Values: dataset.SwaptionsVolatility;

            int maturitiesCount = optionMaturityF.Count(x => x >= swaptionsFiltering.MinSwaptionMaturity && x <= swaptionsFiltering.MaxSwaptionMaturity);
            int durationsCount  = swapDurationF.Count(x => x >= swaptionsFiltering.MinSwapDuration && x <= swaptionsFiltering.MaxSwapDuration);


            Console.WriteLine(string.Format("Calibrating on {0} swaptions prices [#maturiries x #durations]=[{1} x {2}]", maturitiesCount * durationsCount, maturitiesCount, durationsCount));

            if (maturitiesCount * durationsCount == 0)
            {
                return(new EstimationResult("No swaptions satisfying criteria found, please relax filters"));
            }

            //reduced version
            var swaptionsVolatility = new Matrix(maturitiesCount, durationsCount); // dataset.SwaptionsVolatility;
            var optionMaturity      = new Vector(maturitiesCount);                 // dataset.OptionMaturity;
            var swapDuration        = new Vector(durationsCount);                  // dataset.SwapDuration;


            //Build filtered matrix and vectors
            int fm = 0;

            for (int m = 0; m < optionMaturityF.Length; m++)
            {
                int fd = 0;
                if (optionMaturityF[m] >= swaptionsFiltering.MinSwaptionMaturity && optionMaturityF[m] <= swaptionsFiltering.MaxSwaptionMaturity)
                {
                    for (int d = 0; d < swapDurationF.Length; d++)
                    {
                        if (swapDurationF[d] >= swaptionsFiltering.MinSwapDuration && swapDurationF[d] <= swaptionsFiltering.MaxSwapDuration)
                        {
                            swaptionsVolatility[fm, fd] = swaptionsVolatilityF[m, d];
                            swapDuration[fd]            = swapDurationF[d];
                            fd++;
                        }
                    }

                    optionMaturity[fm] = optionMaturityF[m];
                    fm++;
                }
            }

            var swbm = new SwaptionsBlackModel(zr, BlackModelFactory(zr));

            Matrix fsr;
            var    blackSwaptionPrice = 1000.0 * swbm.SwaptionsSurfBM(optionMaturity, swapDuration, swaptionsVolatility, deltak, out fsr);


            Console.WriteLine("Maturities\t" + optionMaturity);
            Console.WriteLine("swapDuration\t" + swapDuration);
            Console.WriteLine("SwaptionHWEstimator: Black model prices");
            Console.WriteLine(blackSwaptionPrice);

            SwaptionHW1 swhw1 = new SwaptionHW1(zr);
            SwaptionHW1OptimizationProblem problem = new SwaptionHW1OptimizationProblem(swhw1, blackSwaptionPrice, optionMaturity, swapDuration, deltak);

            IOptimizationAlgorithm solver  = new QADE();
            IOptimizationAlgorithm solver2 = new SteepestDescent();

            DESettings o = new DESettings();

            o.NP         = 20;
            o.MaxIter    = 5;
            o.Verbosity  = 1;
            o.controller = controller;
            SolutionInfo solution = null;

            Vector x0 = new Vector(new double[] { 0.1, 0.1 });

            solution = solver.Minimize(problem, o, x0);
            if (solution.errors)
            {
                return(new EstimationResult(solution.message));
            }

            o.epsilon = 10e-8;
            o.h       = 10e-8;
            o.MaxIter = 1000;

            // We can permit this, given it is fast.
            o.accourate_numerical_derivatives = true;

            if (solution != null)
            {
                solution = solver2.Minimize(problem, o, solution.x);
            }
            else
            {
                solution = solver2.Minimize(problem, o, x0);
            }
            if (solution.errors)
            {
                return(new EstimationResult(solution.message));
            }
            Console.WriteLine("Solution:");
            Console.WriteLine(solution);
            string[] names = new string[] { "Alpha", "Sigma" };

            Console.WriteLine("SwaptionHWEstimator: hw model prices and error");
            problem.Obj(solution.x, true);

            EstimationResult result = new EstimationResult(names, solution.x);

            result.ZRX = (double[])dataset.ZRMarketDates.ToArray();
            result.ZRY = (double[])dataset.ZRMarket.ToArray();

            double obj = problem.Obj(solution.x);

            return(result);
        }
예제 #4
0
 private static bool IsAtmMatrix(MatrixMarketData normalVol)
 {
     return(normalVol != null &&
            normalVol.ColumnValues.Length == 1 &&
            normalVol.ColumnValues[0] == -1);
 }