Beispiel #1
0
        public HestonCallSimulationOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
            : base(equityCalData, matBound, strikeBound)
        {
            //this.dyFunc = equityCalData.dyFunc;
            this.dyFunc = CallEstimator.IstantaneousDividendYield(equityCalData);
            this.zrFunc = equityCalData.zrFunc;

            // Generates common random numbers
            I       = (int)Math.Ceiling(cpmd.Maturity[Range.End] / dt);
            epsilon = new Matrix(I, 2 * N);
            NewRandomNumbers();

            // Precalculates istantaneous growth rates
            growth = new Vector(I);
            for (int i = 0; i < I; i++)
            {
                double t    = i * dt;
                double zr_t = zrFunc.Evaluate(t);
                growth[i] = zr_t + FunctionHelper.Partial(zr_t, zrFunc, new Vector()
                {
                    t
                }, 0, dt) * t - dyFunc.Evaluate(t);
            }

            Console.WriteLine("Heston Simulation Calibration: Paths=" + N);
        }
        double DY(EquityCalibrationData equityCalData)
        {
            double dy = 0.5 * (equityCalData.dyFunc.Evaluate(1) + equityCalData.dyFunc.Evaluate(2));

            Console.WriteLine("Call/Put Parity Dividend\t" + dy);
            return(dy);
        }
        internal static IFunction IstantaneousDividendYield(EquityCalibrationData ecd)
        {
            double support = Math.Min(6, Math.Max(2, (ecd.dyFunc as PFunction).Support[Range.End]));

            var avgDy = new GBM.FunctionParamPiecewiseConstant(support, 0);//positive f.

            (avgDy as GBM.FunctionParamBase).FitToMean(ecd.dyFunc, 0, support);
            return(avgDy);
        }
        /// <summary>
        /// Initializes a new instance of the HestonCallOptimizationProblem class using the
        /// EquityCalibrationData data structure.
        /// </summary>
        /// <param name="equityCalData">
        /// An EquityCalibrationData object containing market data for calibration.
        /// </param>
        /// <param name="matBound">
        /// A vector containing the minimum and maximum values
        /// for maturities to be used in calibration.
        /// </param>
        /// <param name="strikeBound">
        /// A vector containing the minimum and maximum values
        /// for strikes to be used in calibration.
        /// </param>
        public HestonCallOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
        {
            this.cpmd        = equityCalData.Hdata;
            this.matBound    = matBound;
            this.strikeBound = strikeBound;
            SetVariables(equityCalData.Hdata.CallPrice, equityCalData.Hdata.Maturity,
                         equityCalData.Hdata.Strike, equityCalData.CallMatrixRiskFreeRate,
                         equityCalData.CallMatrixDividendYield, equityCalData.Hdata.S0);



            displayObjInfo = false;
        }
        private EstimationResult FairmatEstimate(CurveMarketData discountingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discountingCurve);
            //HCalData.Setup(Hdataset, discountingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);

            if (hasArbitrage)
            {
                Console.WriteLine("Market data contains arbitrage opportunity");
            }

            this.r = new DVPLDOM.PFunction(discountingCurve.Durations, discountingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.q.Expr = (double[,])ArrayHelper.Concat(HCalData.MaturityDY.ToArray(), HCalData.DividendYield.ToArray());
            this.r.Parse(null);
            this.q.Parse(null);

            Vector locVolMat, locVolStr;
            //IFunction fittedSurface = FitImplVolModel(Hdataset);
            //Matrix locVolMatrix = LocVolMatrixFromImpliedVol(Hdataset, fittedSurface, out locVolMat, out locVolStr);
            CallPriceSurface fittedSurface = CallPriceSurface.NoArbitrageSurface(HCalData);
            Matrix           locVolMatrix  = LocVolMatrixFromCallPrices(Hdataset, fittedSurface, out locVolMat, out locVolStr);

            Console.WriteLine(locVolMatrix);


            // Create dupire outputs.
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector   param = new Vector(1);

            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);

            //result.Objects = new object[3];
            result.Objects    = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = fittedSurface;

            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return(result);
        }
        /// <summary>
        /// Attempts to solve the Variance Gamma Optimization problem using
        /// <see cref="Heston.VarianceGammaOptimizationProblem"/>.
        /// </summary>
        /// <param name="data">
        /// The data to be used in order to perform the optimization.
        /// </param>
        /// <param name="settings">The parameter is not used.</param>
        /// <returns>The results of the optimization.</returns>
        public EstimationResult Estimate(List <object> data, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null)
        {
            EquitySpotMarketData       espmd = data[0] as EquitySpotMarketData;
            CallPriceMarketData        cpmd  = data[1] as CallPriceMarketData;
            DiscountingCurveMarketData dcmd  = data[2] as DiscountingCurveMarketData;
            EquityCalibrationData      ecd   = new EquityCalibrationData(cpmd, dcmd);

            this.s0 = espmd.Price;
            this.r  = espmd.RiskFreeRate;
            this.q  = espmd.DividendYield;

            this.k  = ecd.Hdata.Strike;
            this.m  = ecd.Hdata.Maturity;
            this.cp = ecd.Hdata.CallPrice;

            Vector x0 = (Vector) new double[] { -0.1, 0.2, 0.1 };
            IOptimizationAlgorithm algorithm            = new QADE();
            OptimizationSettings   optimizationSettings = new DESettings();

            // Maximum number of iteration allowed.

            // Positive integer values print debug info.
            optimizationSettings.Verbosity = 1;

            // Tolerance.
            optimizationSettings.epsilon = 10e-5;
            var solution = algorithm.Minimize(new VarianceGammaOptimizationProblem(this.q, this.s0, this.k,
                                                                                   this.r, this.cp, this.m),
                                              optimizationSettings, x0);

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

            var er = new EstimationResult();

            er.Names  = new string[] { "S0", "theta", "sigma", "nu", "rate", "dividend" };
            er.Values = new double[] { this.s0, solution.x[0], solution.x[1], solution.x[2], this.r, this.q };
            return(er);
        }
        protected override void Setup(EquityCalibrationData equityCalData, IEstimationSettings settings)
        {
            //No need to used constant values. In the optimization procedure we can use the term structure
            //as it is.


            /*
             * //equityCalData.dyFunc= LeastSquaresDividendCalibration(equityCalData.Hdata, equityCalData.zrFunc);
             *
             * if (settings != null) //uses settings if provided.
             * {
             *  var localSettings = (HestonEstimationSettings)settings;
             *
             *  equityCalData.SetToSpecificMaturity(localSettings.Maturity);
             * }
             * else
             *  equityCalData.SetToSpecificMaturity(1);
             */
            DY(equityCalData);
            return;
        }
        public HestonCallSimulationOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
            : base(equityCalData,matBound,strikeBound)
        {
            //this.dyFunc = equityCalData.dyFunc;
            this.dyFunc = CallEstimator.IstantaneousDividendYield(equityCalData);
            this.zrFunc = equityCalData.zrFunc;

            // Generates common random numbers
            I = (int)Math.Ceiling(cpmd.Maturity[Range.End] / dt);
            epsilon = new Matrix(I, 2*N);
            NewRandomNumbers();

            // Precalculates istantaneous growth rates
            growth = new Vector(I);
            for (int i = 0; i < I; i++)
            {
                double t = i * dt;
                double zr_t = zrFunc.Evaluate(t);
                growth[i] = zr_t + FunctionHelper.Partial(zr_t,zrFunc, new Vector() { t }, 0, dt) * t - dyFunc.Evaluate(t);
            }

            Console.WriteLine("Heston Simulation Calibration: Paths=" + N);
        }
 protected virtual void Setup(EquityCalibrationData equityCalData, IEstimationSettings settings)
 {
 }
        protected override EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution)
        {
            string[] names = new string[] { "S0", "kappa", "theta", "sigma",
                                            "rho", "V0", "r", "q" };
            Vector param = new Vector(8);

            param[0] = spotPrice.Value;
            param[Range.New(1, 5)] = solution.x[Range.New(0, 4)];
            param[6] = equityCalData.zrFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity);
            if (impliedDividends)
            {
                param[7] = solution.x[Range.End];// equityCalData.dyFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity);
            }
            else
            {
                param[7] = DY(equityCalData);
            }

            var result = new EstimationResult(names, param);

            result.Fit = HestonCallOptimizationProblem.avgPricingError;
            Console.WriteLine(result);
            return(result);
        }
        protected virtual EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution)
        {
            string[] names = new string[] { "S0", "kappa", "theta", "sigma", "rho", "V0" };
            Vector   param = new Vector(6);

            param[0] = spotPrice.Value;
            param[Range.New(1, 5)] = solution.x;
            var result = new EstimationResult(names, param);

            // In the following the two function describing the ZR and dividend yields are created
            //Matrix zerorate = new Matrix(interestDataSet.Durations.Length, 2);
            //zerorate[Range.All, 0] = interestDataSet.Durations;
            //zerorate[Range.All, 1] = interestDataSet.Values;

            //Matrix dividendYield = new Matrix(equityCalData.MaturityDY.Length, 2);
            //dividendYield[Range.All, 0] = equityCalData.MaturityDY;
            //dividendYield[Range.All, 1] = equityCalData.DividendYield;

            Matrix zerorate = new Matrix((equityCalData.zrFunc as PFunction).Expr);
            //Matrix dividendYield = new Matrix((equityCalData.dyFunc as PFunction).Expr);
            Matrix dividendYield = ToMatrix(IstantaneousDividendYield(equityCalData));

            result.Objects    = new object[2];
            result.Objects[0] = zerorate;
            result.Objects[1] = dividendYield;
            result.Fit        = solution.obj;
            Console.WriteLine(result);
            return(result);
        }
        /// <summary>
        /// Attempts to solve the Variance Gamma Optimization problem using
        /// <see cref="Heston.VarianceGammaOptimizationProblem"/>.
        /// </summary>
        /// <param name="data">
        /// The data to be used in order to perform the optimization.
        /// </param>
        /// <param name="settings">The parameter is not used.</param>
        /// <returns>The results of the optimization.</returns>
        public EstimationResult Estimate(List<object> data, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null)
        {
            EquitySpotMarketData espmd = data[0] as EquitySpotMarketData;
            CallPriceMarketData cpmd = data[1] as CallPriceMarketData;
            DiscountingCurveMarketData dcmd = data[2] as DiscountingCurveMarketData;
            EquityCalibrationData ecd = new EquityCalibrationData(cpmd, dcmd);
            this.s0 = espmd.Price;
            this.r = espmd.RiskFreeRate;
            this.q = espmd.DividendYield;

            this.k = ecd.Hdata.Strike;
            this.m = ecd.Hdata.Maturity;
            this.cp = ecd.Hdata.CallPrice;

            Vector x0 = (Vector)new double[] { -0.1, 0.2, 0.1 };
            IOptimizationAlgorithm algorithm = new QADE();
            OptimizationSettings optimizationSettings = new DESettings();

            // Maximum number of iteration allowed.

            // Positive integer values print debug info.
            optimizationSettings.Verbosity = 1;

            // Tolerance.
            optimizationSettings.epsilon = 10e-5;
            var solution = algorithm.Minimize(new VarianceGammaOptimizationProblem(this.q, this.s0, this.k,
                                                                          this.r, this.cp, this.m),
                                                                          optimizationSettings, x0);

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

            var er = new EstimationResult();
            er.Names= new string[]{"S0","theta","sigma","nu","rate","dividend"};
            er.Values = new double[] {this.s0,solution.x[0],solution.x[1],solution.x[2],this.r,this.q};
            return er;
        }
Beispiel #13
0
        internal static IFunction IstantaneousDividendYield(EquityCalibrationData ecd)
        {
            double support = Math.Min(6, Math.Max(2, (ecd.dyFunc as PFunction).Support[Range.End]));

            var avgDy = new GBM.FunctionParamPiecewiseConstant(support, 0);//positive f.
            (avgDy as GBM.FunctionParamBase).FitToMean(ecd.dyFunc, 0, support);
            return avgDy;
        }
 double DY(EquityCalibrationData equityCalData)
 {
     double dy= 0.5*(equityCalData.dyFunc.Evaluate(1) + equityCalData.dyFunc.Evaluate(2));
     Console.WriteLine("Call/Put Parity Dividend\t" + dy);
     return dy;
 }
        /// <summary>
        /// Initializes a new instance of the HestonCallOptimizationProblem class using the
        /// EquityCalibrationData data structure.
        /// </summary>
        /// <param name="equityCalData">
        /// An EquityCalibrationData object containing market data for calibration.
        /// </param>
        /// <param name="matBound">
        /// A vector containing the minimum and maximum values
        /// for maturities to be used in calibration.
        /// </param>
        /// <param name="strikeBound">
        /// A vector containing the minimum and maximum values
        /// for strikes to be used in calibration.
        /// </param>
        public HestonCallOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
        {
            this.cpmd = equityCalData.Hdata;
            this.matBound = matBound;
            this.strikeBound = strikeBound;
            SetVariables(equityCalData.Hdata.CallPrice, equityCalData.Hdata.Maturity,
                         equityCalData.Hdata.Strike, equityCalData.CallMatrixRiskFreeRate,
                         equityCalData.CallMatrixDividendYield, equityCalData.Hdata.S0);

            displayObjInfo = false;
        }
 protected override HestonCallOptimizationProblem NewOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
 {
     return new HestonCallSimulationOptimizationProblem(equityCalData, matBound, strikeBound);
 }
Beispiel #17
0
        private EstimationResult FairmatEstimate(CurveMarketData discountingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discountingCurve);
            //HCalData.Setup(Hdataset, discountingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);
            if (hasArbitrage)
                Console.WriteLine("Market data contains arbitrage opportunity");

            this.r = new DVPLDOM.PFunction(discountingCurve.Durations,discountingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.q.Expr = (double[,])ArrayHelper.Concat(HCalData.MaturityDY.ToArray(), HCalData.DividendYield.ToArray());
            this.r.Parse(null);
            this.q.Parse(null);

            Vector locVolMat, locVolStr;
            //IFunction fittedSurface = FitImplVolModel(Hdataset);
            //Matrix locVolMatrix = LocVolMatrixFromImpliedVol(Hdataset, fittedSurface, out locVolMat, out locVolStr);
            CallPriceSurface fittedSurface = CallPriceSurface.NoArbitrageSurface(HCalData);
            Matrix locVolMatrix = LocVolMatrixFromCallPrices(Hdataset, fittedSurface, out locVolMat, out locVolStr);
            Console.WriteLine(locVolMatrix);

            // Create dupire outputs.
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector param = new Vector(1);
            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);
            //result.Objects = new object[3];
            result.Objects = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = fittedSurface;

            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return result;
        }
        public static void Main(string[] args)
        {
            int Caso = 1;

            if (Caso == 0)
            {
                InterestRateMarketData MData   = InterestRateMarketData.FromFile("../../../TestData/InterestRatesModels/05052009-EU.xml");
                CallPriceMarketData    test    = CallPriceMarketData.FromFile("../../../TestData/Heston/05052009-SX5E-HestonData.xml");
                EquityCalibrationData  CalData = new EquityCalibrationData(test, MData);

                Matrix CallMarketPrice = (Matrix)test.CallPrice;
                Vector Maturity        = (Vector)test.Maturity;
                Vector Strike          = (Vector)test.Strike;
                Vector DividendYield   = (Vector)test.DividendYield;
                Vector Drift           = CalData.Rate - CalData.DividendYield;
                Vector Rate            = CalData.Rate;

                double u, kappa, theta, sigma, rho, v0, s0, r, q, T, K, val;
                u     = 1.0;
                kappa = 19.4;
                theta = 0.235;
                sigma = 0.00500999;
                rho   = -0.96;
                v0    = 0.664;
                s0    = 3872.15;
                r     = -0.0867303549580581;
                q     = 0;
                T     = 0.50;
                K     = 6000;
                Vector MatBound    = new Vector(2);
                Vector StrikeBound = new Vector(2);
                MatBound[0]    = 0.0;
                MatBound[1]    = 2.0;
                StrikeBound[0] = 0.7;
                StrikeBound[1] = 1.3;
                Matrix Volatility = new Matrix(test.CallPrice.R, test.CallPrice.C);
                HestonCallOptimizationProblem HP = new HestonCallOptimizationProblem(CallMarketPrice, Maturity, Strike, Rate, DividendYield, test.S0, MatBound, StrikeBound, Volatility);
                Complex Cval, Cu;
                Cu = u - Complex.I;
                HestonCall hc = new HestonCall(HP);

                Cval = hc.phi(u, kappa, theta, sigma, rho, s0, v0, r, T);
                Console.WriteLine("phi1 = {0}", Cval);
                Cval = hc.phi(Cu, kappa, theta, sigma, rho, s0, v0, r, T);
                Console.WriteLine("phi2 = {0}", Cval);
                val = hc.IntegrandFunc(u, kappa, theta, sigma, rho, s0, v0, r, q, T, K);
                Console.WriteLine("IntFunc = {0}", val);

                Vector x = new Vector(5);
                x[0] = kappa;
                x[1] = theta;
                x[2] = sigma;
                x[3] = rho;
                x[4] = v0;

                DateTime T1, T2;
                TimeSpan ElapsedTime;
                double   Time, Time2, Time3;

                T1          = DateTime.Now;
                val         = hc.HestonCallPrice(x, s0, T, K, r, q);
                T2          = DateTime.Now;
                ElapsedTime = T2 - T1;
                Time        = (double)ElapsedTime.Milliseconds;
                Time2       = (double)ElapsedTime.Seconds;
                Console.WriteLine("Price = {0}", val);
                Console.WriteLine("Elapsed Time = {0}", Time2 + Time / 1000);

                int    NProve = 10;
                int    NPassi = 1000;
                double val2;
                Random CasNum = new Random();
                for (int i = 0; i < NProve; i++)
                {
                    for (int j = 0; j < 5; j++)
                    {
                        val2 = ((double)CasNum.Next(0, NPassi)) / ((double)NPassi);
                        x[j] = HP.Bounds.Lb[j] + (HP.Bounds.Ub[j] - HP.Bounds.Lb[j]) * val2;
                    }
                    Console.Write("Trial {0}  x = " + x.ToString(), i + 1);
                    T1          = DateTime.Now;
                    val         = HP.Obj(x);
                    T2          = DateTime.Now;
                    ElapsedTime = T2 - T1;
                    Time        = (double)ElapsedTime.Milliseconds;
                    Time2       = (double)ElapsedTime.Seconds;
                    Time3       = (double)ElapsedTime.Minutes;
                    Console.WriteLine("  Time = {0}' {1}'' Val = {2}", Time3, Time2 + Time / 1000, val);
                }
            }
            if (Caso == 1)
            {
                TestHestonCallEstimation NewTest = new TestHestonCallEstimation();
                bool Result = NewTest.Run();
            }
        }
Beispiel #19
0
        /// <summary>
        /// Attempts to solve the Heston optimization problem using
        /// <see cref="Heston.HestonOptimizationProblem"/>.
        /// </summary>
        /// <param name="marketData">Data to be used in order to perform the optimization.</param>
        /// <param name="settings">The parameter is not used.</param>
        /// <param name="controller">IController.</param>
        /// <returns>The results of the optimization.</returns>
        public EstimationResult Estimate(List<object> marketData, IEstimationSettings settings = null, IController controller = null, Dictionary<string, object> properties = null)
        {
            DateTime t0 = DateTime.Now;
            var interestDataSet = (CurveMarketData)marketData[0];
            CallPriceMarketData callDataSet = (CallPriceMarketData)marketData[1];
            EquityCalibrationData equityCalData = new EquityCalibrationData(callDataSet, interestDataSet);
            var spotPrice = (DVPLI.MarketDataTypes.Scalar)marketData[2];

            Setup(equityCalData, settings);

            var calSettings = settings as HestonCalibrationSettings;
            // Creates the context.
            Document doc = new Document();
            ProjectROV prj = new ProjectROV(doc);
            doc.Part.Add(prj);

            // Optimization problem instance.
            Vector matBound = new Vector(2);
            Vector strikeBound = new Vector(2);
            if (calSettings != null)
            {
                matBound[0] = calSettings.MinMaturity;
                matBound[1] = calSettings.MaxMaturity;
                strikeBound[0] = calSettings.MinStrike;
                strikeBound[1] = calSettings.MaxStrike;
            }
            else
            {
                //use defaults
                matBound[0] = 1.0 / 12;// .25;
                matBound[1] = 6;// 10; //Up to 6Y maturities
                strikeBound[0] = 0.4;
                strikeBound[1] = 1.6;
            }
            Console.WriteLine(callDataSet);
            /*
            //CBA TEST
            matBound[0] = 1;// .25;
            matBound[1] = 3.5;// 10; //Up to 6Y maturities
            strikeBound[0] = 0.5;// 0.5;
            strikeBound[1] = 2;//1.5;
            */
            HestonCallOptimizationProblem problem = NewOptimizationProblem(equityCalData, matBound, strikeBound);
            int totalOpts = problem.numCall + problem.numPut;
            Console.WriteLine("Calibration based on "+totalOpts+ " options. (" + problem.numCall + " call options and "+problem.numPut+" put options).");

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

            DESettings o = new DESettings();
            o.controller = controller;

            // If true the optimization algorithm will operate in parallel.
            o.Parallel = Engine.MultiThread;
            o.h = 10e-8;
            o.epsilon = 10e-8;

            SolutionInfo solution = null;

            double minObj=double.MaxValue;
            Vector minX= null;
            int Z = 1;
            //if (problem.GetType() == typeof(Heston.HestonCallSimulationOptimizationProblem))
            //    Z = 2;

            for(int z=0;z<Z;z++)
            {
                if (solver.GetType() == typeof(MultiLevelSingleLinkage))
                {
                    o.NP = 50;
                    o.MaxIter = 25;
                    o.MaxGamma = 6;
                }
                else
                {
                    o.NP = 60;
                    o.MaxIter = 35;
                }
                o.Verbosity = 1;
            Vector x0 = null;// new Vector(new double[] { 0.5, 0.5, 0.8, -0.5, 0.05 });

            // GA
            solution = solver.Minimize(problem, o, x0);
            if (solution.errors)
                return null;

            o.options = "qn";
            o.MaxIter = 500;// 1000;

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

            if (solution.obj < minObj)
            {
                minObj = solution.obj;
                minX = solution.x.Clone();
            }
            }

            solution.obj = minObj;
            solution.x = minX;

            //Displays pricing error structure
            HestonCallOptimizationProblem.displayObjInfo = true;
            problem.Obj(solution.x);
            HestonCallOptimizationProblem.displayObjInfo = false;
            Console.WriteLine("Calibration Time (s)\t" + (DateTime.Now - t0).TotalSeconds);

            return BuildEstimate(spotPrice,interestDataSet, callDataSet, equityCalData, solution);
        }
Beispiel #20
0
 protected virtual void Setup(EquityCalibrationData equityCalData, IEstimationSettings settings)
 {
 }
Beispiel #21
0
 protected virtual HestonCallOptimizationProblem NewOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
 {
     return new HestonCallOptimizationProblem(equityCalData, matBound, strikeBound);
 }
Beispiel #22
0
        protected virtual EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution)
        {
            string[] names = new string[] { "S0", "kappa", "theta", "sigma", "rho", "V0" };
            Vector param = new Vector(6);
            param[0] = spotPrice.Value;
            param[Range.New(1, 5)] = solution.x;
            var result = new EstimationResult(names, param);

            // In the following the two function describing the ZR and dividend yields are created
            //Matrix zerorate = new Matrix(interestDataSet.Durations.Length, 2);
            //zerorate[Range.All, 0] = interestDataSet.Durations;
            //zerorate[Range.All, 1] = interestDataSet.Values;

            //Matrix dividendYield = new Matrix(equityCalData.MaturityDY.Length, 2);
            //dividendYield[Range.All, 0] = equityCalData.MaturityDY;
            //dividendYield[Range.All, 1] = equityCalData.DividendYield;

            Matrix zerorate = new Matrix((equityCalData.zrFunc as PFunction).Expr);
            //Matrix dividendYield = new Matrix((equityCalData.dyFunc as PFunction).Expr);
            Matrix dividendYield = ToMatrix(IstantaneousDividendYield(equityCalData));
            result.Objects = new object[2];
            result.Objects[0] = zerorate;
            result.Objects[1] = dividendYield;
            result.Fit = solution.obj;
            Console.WriteLine(result);
            return result;
        }
 protected virtual HestonCallOptimizationProblem NewOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
 {
     return(new HestonCallOptimizationProblem(equityCalData, matBound, strikeBound));
 }
        /// <summary>
        /// Attempts to solve the Heston optimization problem using
        /// <see cref="Heston.HestonOptimizationProblem"/>.
        /// </summary>
        /// <param name="marketData">Data to be used in order to perform the optimization.</param>
        /// <param name="settings">The parameter is not used.</param>
        /// <param name="controller">IController.</param>
        /// <returns>The results of the optimization.</returns>
        public EstimationResult Estimate(List <object> marketData, IEstimationSettings settings = null, IController controller = null, Dictionary <string, object> properties = null)
        {
            DateTime              t0 = DateTime.Now;
            var                   interestDataSet = (CurveMarketData)marketData[0];
            CallPriceMarketData   callDataSet     = (CallPriceMarketData)marketData[1];
            EquityCalibrationData equityCalData   = new EquityCalibrationData(callDataSet, interestDataSet);
            var                   spotPrice       = (DVPLI.MarketDataTypes.Scalar)marketData[2];


            Setup(equityCalData, settings);

            var calSettings = settings as HestonCalibrationSettings;
            // Creates the context.
            Document   doc = new Document();
            ProjectROV prj = new ProjectROV(doc);

            doc.Part.Add(prj);

            // Optimization problem instance.
            Vector matBound    = new Vector(2);
            Vector strikeBound = new Vector(2);

            if (calSettings != null)
            {
                matBound[0]    = calSettings.MinMaturity;
                matBound[1]    = calSettings.MaxMaturity;
                strikeBound[0] = calSettings.MinStrike;
                strikeBound[1] = calSettings.MaxStrike;
            }
            else
            {
                //use defaults
                matBound[0]    = 1.0 / 12; // .25;
                matBound[1]    = 6;        // 10; //Up to 6Y maturities
                strikeBound[0] = 0.4;
                strikeBound[1] = 1.6;
            }
            Console.WriteLine(callDataSet);

            /*
             * //CBA TEST
             * matBound[0] = 1;// .25;
             * matBound[1] = 3.5;// 10; //Up to 6Y maturities
             * strikeBound[0] = 0.5;// 0.5;
             * strikeBound[1] = 2;//1.5;
             */
            HestonCallOptimizationProblem problem = NewOptimizationProblem(equityCalData, matBound, strikeBound);
            int totalOpts = problem.numCall + problem.numPut;

            Console.WriteLine("Calibration based on " + totalOpts + " options. (" + problem.numCall + " call options and " + problem.numPut + " put options).");

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

            DESettings o = new DESettings();

            o.controller = controller;

            // If true the optimization algorithm will operate in parallel.
            o.Parallel = Engine.MultiThread;
            o.h        = 10e-8;
            o.epsilon  = 10e-8;

            SolutionInfo solution = null;

            double minObj = double.MaxValue;
            Vector minX   = null;
            int    Z      = 1;

            //if (problem.GetType() == typeof(Heston.HestonCallSimulationOptimizationProblem))
            //    Z = 2;

            for (int z = 0; z < Z; z++)
            {
                if (solver.GetType() == typeof(MultiLevelSingleLinkage))
                {
                    o.NP       = 50;
                    o.MaxIter  = 25;
                    o.MaxGamma = 6;
                }
                else
                {
                    o.NP      = 60;
                    o.MaxIter = 35;
                }
                o.Verbosity = 1;
                Vector x0 = null;// new Vector(new double[] { 0.5, 0.5, 0.8, -0.5, 0.05 });

                // GA
                solution = solver.Minimize(problem, o, x0);
                if (solution.errors)
                {
                    return(null);
                }

                o.options = "qn";
                o.MaxIter = 500;// 1000;

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

                if (solution.obj < minObj)
                {
                    minObj = solution.obj;
                    minX   = solution.x.Clone();
                }
            }



            solution.obj = minObj;
            solution.x   = minX;

            //Displays pricing error structure
            HestonCallOptimizationProblem.displayObjInfo = true;
            problem.Obj(solution.x);
            HestonCallOptimizationProblem.displayObjInfo = false;
            Console.WriteLine("Calibration Time (s)\t" + (DateTime.Now - t0).TotalSeconds);

            return(BuildEstimate(spotPrice, interestDataSet, callDataSet, equityCalData, solution));
        }
Beispiel #25
0
 protected override HestonCallOptimizationProblem NewOptimizationProblem(EquityCalibrationData equityCalData, Vector matBound, Vector strikeBound)
 {
     return(new HestonCallSimulationOptimizationProblem(equityCalData, matBound, strikeBound));
 }
        protected override void Setup(EquityCalibrationData equityCalData, IEstimationSettings  settings)
        {
            //No need to used constant values. In the optimization procedure we can use the term structure
            //as it is.

            /*
             //equityCalData.dyFunc= LeastSquaresDividendCalibration(equityCalData.Hdata, equityCalData.zrFunc);

            if (settings != null) //uses settings if provided.
            {
                var localSettings = (HestonEstimationSettings)settings;

                equityCalData.SetToSpecificMaturity(localSettings.Maturity);
            }
            else
                equityCalData.SetToSpecificMaturity(1);
            */
            DY(equityCalData);
            return;
        }
Beispiel #27
0
        private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);

            if (hasArbitrage)
            {
                Console.WriteLine("Market data contains arbitrage opportunity");
            }

            this.r = new DVPLDOM.PFunction(discoutingCurve.Durations, discoutingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.r.Parse(null);
            //this.q.Parse(null);

            Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C);
            for (int i = 0; i < Hdataset.Volatility.R; i++)
            {
                double m = Hdataset.Maturity[i];
                for (int j = 0; j < Hdataset.Volatility.C; j++)
                {
                    if (Hdataset.CallPrice[i, j] > 0)
                    {
                        var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m));
                        //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i];

                        //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]);
                    }
                }
            }

            Console.WriteLine(Hdataset.Volatility);

            IFunction impVol = FitImplVolModel(Hdataset);

            Document   doc = new Document();
            ProjectROV prj = new ProjectROV(doc);

            doc.Part.Add(prj);
            prj.Symbols.Add(impVol);
            // doc.WriteToXMLFile("impVol.fair");

            int       nmat = calibrationSettings.LocalVolatilityMaturities;
            int       nstrike = calibrationSettings.LocalVolatilityStrikes;
            double    lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End];
            double    lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End];
            Vector    locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            Vector    locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix    locVolMatrix = new Matrix(nmat, nstrike);
            double    t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy;
            double    d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt;
            Integrate integrate = new Integrate(this);

            for (int i = 0; i < nmat; i++)
            {
                t            = locVolMat[i];
                forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t));
                for (int j = 0; j < nstrike; j++)
                {
                    strike = locVolStr[j];
                    y      = Math.Log(strike / forwardValue);
                    dy     = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001);

                    // strike derivative
                    strikep = strike * Math.Exp(dy);
                    strikem = strike / Math.Exp(dy);
                    w       = impVol.Evaluate(t, strike);
                    wp      = impVol.Evaluate(t, strikep);
                    wm      = impVol.Evaluate(t, strikem);
                    dwdy    = (wp - wm) / (2.0 * dy);
                    d2wdy2  = (wp - 2.0 * w + wm) / (dy * dy);

                    // time derivative
                    if (t == 0.0)
                    {
                        dt       = 0.0001;
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt));
                        wpt      = impVol.Evaluate(t + dt, strikept);
                        // if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        dwdt = (wpt - w) / dt;
                    }
                    else
                    {
                        dt       = Math.Min(0.0001, t / 2.0);
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt));
                        strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t));
                        wpt      = impVol.Evaluate(t + dt, strikept);
                        wmt      = impVol.Evaluate(t + dt, strikemt);

                        //if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        //if (w < wmt)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t);
                        dwdt = (wpt - wmt) / (2.0 * dt);
                    }
                    if (dwdy == 0.0 && d2wdy2 == 0.0)
                    {
                        locVolMatrix[i, j] = Math.Sqrt(dwdt);
                    }
                    else
                    {
                        den1 = 1.0 - y / w * dwdy;
                        den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy;
                        den3 = 0.5 * d2wdy2;
                        locVolMatrix[i, j] = dwdt / (den1 + den2 + den3);
                        //if (locVolMatrix[i,j] < 0.0)
                        //    Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " +
                        //        "Black vol surface is not smooth enought.", strike, t);
                    }
                }
            }

            // Create dupire outputs.
            Console.WriteLine(locVolMat);
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector   param = new Vector(1);

            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);

            //result.Objects = new object[3];
            result.Objects    = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = impVol;
            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return(result);
        }
        protected override EstimationResult BuildEstimate(Scalar spotPrice, CurveMarketData interestDataSet, CallPriceMarketData callDataSet, EquityCalibrationData equityCalData, SolutionInfo solution)
        {
            string[] names = new string[] { "S0", "kappa", "theta", "sigma",
                                            "rho", "V0", "r", "q" };
            Vector param = new Vector(8);
            param[0] = spotPrice.Value;
            param[Range.New(1, 5)] = solution.x[Range.New(0, 4)];
            param[6] = equityCalData.zrFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity);
            if (impliedDividends)
                param[7] = solution.x[Range.End];// equityCalData.dyFunc.Evaluate(TheoreticalModelsSettings.ConstantDYRFMaturity);
            else
                param[7] = DY(equityCalData);

            var result = new EstimationResult(names, param);
            result.Fit = HestonCallOptimizationProblem.avgPricingError;
            Console.WriteLine(result);
            return result;
        }
        private EstimationResult QuantLibEstimate(CurveMarketData discoutingCurve, CallPriceMarketData Hdataset)
        {
            EquityCalibrationData HCalData = new EquityCalibrationData(Hdataset, discoutingCurve);

            bool hasArbitrage = HCalData.HasArbitrageOpportunity(10e-2);
            if (hasArbitrage)
                Console.WriteLine("Market data contains arbitrage opportunity");

            this.r = new DVPLDOM.PFunction(discoutingCurve.Durations,discoutingCurve.Values);
            this.q = HCalData.dyFunc as PFunction;

            //this.r.Parse(null);
            //this.q.Parse(null);

            Hdataset.Volatility = new Matrix(Hdataset.CallPrice.R, Hdataset.CallPrice.C);
            for (int i = 0; i < Hdataset.Volatility.R; i++)
            {
                double m=Hdataset.Maturity[i];
                for (int j = 0; j < Hdataset.Volatility.C; j++)
                {
                    if (Hdataset.CallPrice[i, j] > 0)
                    {
                        var bs = new Fairmat.Finance.BlackScholes(r.Evaluate(m), Hdataset.S0, Hdataset.Strike[j], 0, m, q.Evaluate(m));
                        //Hdataset.Volatility[i, j] = Hdataset.Volatility[i, j] * Hdataset.Volatility[i, j] * Hdataset.Maturity[i];

                        //Hdataset.Volatility[i, j] = bs.ImpliedCallVolatility(Hdataset.CallPrice[i, j]);
                    }
                }
            }

            Console.WriteLine(Hdataset.Volatility);

            IFunction impVol = FitImplVolModel(Hdataset);

            Document doc = new Document();
            ProjectROV prj = new ProjectROV(doc);
            doc.Part.Add(prj);
            prj.Symbols.Add(impVol);
            // doc.WriteToXMLFile("impVol.fair");

            int nmat = calibrationSettings.LocalVolatilityMaturities;
            int nstrike = calibrationSettings.LocalVolatilityStrikes;
            double lastMat = Hdataset.Maturity[SymbolicIntervalExtremes.End];
            double lastStr = Hdataset.Strike[SymbolicIntervalExtremes.End];
            Vector locVolMat = Vector.Linspace(Hdataset.Maturity[0], lastMat, nmat);
            Vector locVolStr = Vector.Linspace(Hdataset.Strike[0], lastStr, nstrike);
            Matrix locVolMatrix = new Matrix(nmat, nstrike);
            double t, dt, forwardValue, y, dy, strike, strikep, strikem, w, wp, wm, dwdy;
            double d2wdy2, den1, den2, den3, strikept, strikemt, wpt, wmt, dwdt;
            Integrate integrate = new Integrate(this);

            for (int i = 0; i < nmat; i++)
            {
                t = locVolMat[i];
                forwardValue = Hdataset.S0 * Math.Exp(integrate.AdaptLobatto(0.0, t));
                for (int j = 0; j < nstrike; j++)
                {
                    strike = locVolStr[j];
                    y = Math.Log(strike / forwardValue);
                    dy = ((Math.Abs(y) > 0.001) ? y * 0.0001 : 0.000001);

                    // strike derivative
                    strikep = strike * Math.Exp(dy);
                    strikem = strike / Math.Exp(dy);
                    w = impVol.Evaluate(t, strike);
                    wp = impVol.Evaluate(t, strikep);
                    wm = impVol.Evaluate(t, strikem);
                    dwdy = (wp - wm) / (2.0 * dy);
                    d2wdy2 = (wp - 2.0 * w + wm) / (dy * dy);

                    // time derivative
                    if (t == 0.0)
                    {
                        dt = 0.0001;
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(0.0, t + dt));
                        wpt = impVol.Evaluate(t + dt, strikept);
                        // if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        dwdt = (wpt - w) / dt;
                    }
                    else
                    {
                        dt = Math.Min(0.0001, t / 2.0);
                        strikept = strike * Math.Exp(integrate.AdaptLobatto(t, t + dt));
                        strikemt = strike * Math.Exp(-integrate.AdaptLobatto(t - dt, t));
                        wpt = impVol.Evaluate(t + dt, strikept);
                        wmt = impVol.Evaluate(t + dt, strikemt);

                        //if (wpt < w)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t, t + dt);
                        //if (w < wmt)
                        //    Console.WriteLine("Decreasing variance at strike {0} between time {1} and time {2}", strike, t-dt, t);
                        dwdt = (wpt - wmt) / (2.0 * dt);
                    }
                    if (dwdy == 0.0 && d2wdy2 == 0.0)
                        locVolMatrix[i, j] = Math.Sqrt(dwdt);
                    else
                    {
                        den1 = 1.0 - y / w * dwdy;
                        den2 = 0.25 * (-0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy;
                        den3 = 0.5 * d2wdy2;
                        locVolMatrix[i, j] = dwdt / (den1 + den2 + den3);
                        //if (locVolMatrix[i,j] < 0.0)
                        //    Console.WriteLine("Negative local vol^2 at strike {0} and time {1}; " +
                        //        "Black vol surface is not smooth enought.", strike, t);
                    }
                }
            }

            // Create dupire outputs.
            Console.WriteLine(locVolMat);
            PFunction2D.PFunction2D localVol = new PFunction2D.PFunction2D(locVolMat, locVolStr, locVolMatrix);
            localVol.Parse(null);
            string[] names = new string[] { "S0" };
            Vector param = new Vector(1);
            param[0] = Hdataset.S0;
            EstimationResult result = new EstimationResult(names, param);
            //result.Objects = new object[3];
            result.Objects = new object[4];
            result.Objects[0] = this.r;
            result.Objects[1] = this.q;
            result.Objects[2] = localVol;
            result.Objects[3] = impVol;
            //Console.WriteLine("r = " + HCalData.Rate.ToString());
            //Console.WriteLine("q = " + HCalData.DividendYield.ToString());
            return result;
        }