Inheritance: IEstimator, IDescription
        /// <summary>
        /// Returns the root mean square error between market and model call prices
        /// </summary>
        /// <param name="x">Parameter vector</param>
        /// <param name="q">Dividend yield</param>
        /// <param name="s0">Index starting value</param>
        /// <param name="k">Call strike vector</param>
        /// <param name="r">Short rate</param>
        /// <param name="cp">Call price matrix</param>
        /// <param name="m">Call maturity vector</param>
        /// <returns>Call price root mean square error</returns>
        public static double VGDiff(Vector x, double q, double s0, Vector k, double r, Matrix cp, Vector m)
        {
            double y = 0;
            double residual;

            for (int i = 0; i < m.Length; i++)
            {
                for (int j = 0; j < k.Length; j++)
                {
                    double par  = m[i] / x[2];
                    double rest = par - Math.Floor(par);
                    if (rest != 0.5 && rest != 0.0 && cp[i, j] != 0.0)
                    {
                        residual = Math.Pow(cp[i, j] - VarianceGammaOptionsCalibration.VGCall(x[0], x[1], x[2], m[i], k[j], q, s0, r), 2);
                        if (residual > Math.Pow(10, 10) || double.IsNaN(residual))
                        {
                            y = y + 1000 * Math.Sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
                        }
                        else
                        {
                            y = y + residual;
                        }
                    }
                }
            }

            return(Math.Sqrt(y / (m.Length * k.Length)));
        }
        private static Vector Test(int nm, int nk, double q, double s0, double r, double t, double theta, double sigma, double nu)
        {
            // Simulate synthetic data.
            Vector m    = new Vector(nm);
            Vector k    = new Vector(nk);
            Matrix cp   = new Matrix(nm, nk);
            Random rand = new Random();

            for (int i = 0; i < nm; i++)
            {
                m[i] = 0.01 + rand.NextDouble() * 0.99;
            }

            for (int i = 0; i < nk; i++)
            {
                k[i] = 60 + rand.NextDouble() * 90;
            }

            for (int i = 0; i < nm; i++)
            {
                for (int j = 0; j < nk; j++)
                {
                    cp[i, j] = VarianceGammaOptionsCalibration.VGCall(theta, sigma, nu, m[i], k[j], q, s0, r);
                }
            }

            Console.WriteLine("Benchmark value");
            Console.WriteLine(new Vector()
            {
                theta, sigma, nu
            });

            Console.WriteLine("Call prices");
            Console.WriteLine(cp);

            // VGDiff at optimum.
            double fopt = VarianceGammaOptimizationProblem.VGDiff(new Vector()
            {
                theta, sigma, nu
            }, q, s0, k, r, cp, m);

            Console.WriteLine("fopt");
            Console.WriteLine(fopt);

            VarianceGammaOptionsCalibration c = new VarianceGammaOptionsCalibration();
            List <object> marketData          = new List <object>();

            var espmd = new EquitySpotMarketData();

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

            var cpmd = new CallPriceMarketData();

            cpmd.Strike    = k;
            cpmd.Maturity  = m;
            cpmd.CallPrice = cp;

            var dc = new DiscountingCurveMarketData();

            dc.Durations = new Vector()
            {
                0
            };
            dc.Values = new Vector()
            {
                r
            };

            marketData.Add(espmd);
            marketData.Add(cpmd);
            marketData.Add(dc);

            EstimationResult res = c.Estimate(marketData, null);

            return((Vector)res.Values);
        }
Exemple #3
0
        public void Test()
        {
            double nu       = 0.6;
            double theta    = -0.2;
            double sigma    = 0.2;
            double rate     = 0.02;
            double dy       = 0.01;
            double s0       = 1;
            double maturity = 2.0;
            double strike   = 1.2;
            Vector mat      = new Vector(1) + maturity;
            Vector k        = new Vector(1) + strike;

            // Calculates the theoretical value of the call.
            double theoreticalPrice = VarianceGammaOptionsCalibration.VGCall(theta, sigma, nu,
                                                                             maturity, strike,
                                                                             dy, s0, rate);

            Engine.MultiThread = true;
            Document   doc = new Document();
            ProjectROV rov = new ProjectROV(doc);

            doc.Part.Add(rov);
            doc.DefaultProject.NMethods.m_UseAntiteticPaths = true;

            int n_sim   = 50000;
            int n_steps = 512;

            ModelParameter paramStrike = new ModelParameter(strike, "strike");

            paramStrike.VarName = "strike";
            rov.Symbols.Add(paramStrike);

            ModelParameter paramRate = new ModelParameter(rate, "rfrate");

            paramRate.VarName = "rfrate";
            rov.Symbols.Add(paramRate);

            AFunction payoff = new AFunction(rov);

            payoff.VarName = "payoff";
            payoff.m_IndependentVariables = 1;
            payoff.m_Value = (RightValue)("max(x1 - strike ; 0)");
            rov.Symbols.Add(payoff);

            VarianceGamma process = new VarianceGamma(s0, theta, sigma, nu, rate, dy);

            StochasticProcessExtendible s = new StochasticProcessExtendible(rov, process);

            rov.Processes.AddProcess(s);

            // Set the discounting.
            RiskFreeInfo rfi = rov.GetDiscountingModel() as RiskFreeInfo;

            rfi.ActualizationType = EActualizationType.RiskFree;
            rfi.m_deterministicRF = rate;

            OptionTree op = new OptionTree(rov);

            op.PayoffInfo.PayoffExpression          = "payoff(v1)";
            op.PayoffInfo.Timing.EndingTime.m_Value = (RightValue)maturity;
            op.PayoffInfo.European = true;
            rov.Map.Root           = op;

            rov.NMethods.Technology      = ETechType.T_SIMULATION;
            rov.NMethods.PathsNumber     = n_sim;
            rov.NMethods.SimulationSteps = n_steps;

            ROVSolver solver = new ROVSolver();

            solver.BindToProject(rov);
            solver.DoValuation(-1);

            if (rov.HasErrors)
            {
                rov.DisplayErrors();
            }

            Assert.IsFalse(rov.HasErrors);

            ResultItem price = rov.m_ResultList[0] as ResultItem;

            double samplePrice = price.value;
            double sampleDevSt = price.stdDev / Math.Sqrt((double)n_sim);

            Console.WriteLine("Theoretical Price = " + theoreticalPrice);
            Console.WriteLine("Monte Carlo Price = " + samplePrice);
            Console.WriteLine("Standard Deviation = " + sampleDevSt.ToString());
            double tol = 4.0 * sampleDevSt;

            Assert.Less(Math.Abs(theoreticalPrice - samplePrice), tol);
        }
        private static Vector Test(int nm, int nk, double q, double s0, double r, double t, double theta, double sigma, double nu)
        {
            // Simulate synthetic data.
            Vector m = new Vector(nm);
            Vector k = new Vector(nk);
            Matrix cp = new Matrix(nm, nk);
            Random rand = new Random();
            for (int i = 0; i < nm; i++)
            {
                m[i] = 0.01 + rand.NextDouble() * 0.99;
            }

            for (int i = 0; i < nk; i++)
            {
                k[i] = 60 + rand.NextDouble() * 90;
            }

            for (int i = 0; i < nm; i++)
            {
                for (int j = 0; j < nk; j++)
                {
                    cp[i, j] = VarianceGammaOptionsCalibration.VGCall(theta, sigma, nu, m[i], k[j], q, s0, r);
                }
            }

            Console.WriteLine("Benchmark value");
            Console.WriteLine(new Vector() { theta, sigma, nu });

            Console.WriteLine("Call prices");
            Console.WriteLine(cp);

            // VGDiff at optimum.
            double fopt = VarianceGammaOptimizationProblem.VGDiff(new Vector() { theta, sigma, nu }, q, s0, k, r, cp, m);
            Console.WriteLine("fopt");
            Console.WriteLine(fopt);

            VarianceGammaOptionsCalibration c = new VarianceGammaOptionsCalibration();
            List<object> marketData = new List<object>();

            EquitySpotMarketData espmd = new EquitySpotMarketData();
            CallPriceMarketData cpmd = new CallPriceMarketData();
            espmd.Price = s0;
            espmd.RiskFreeRate = r;
            espmd.DividendYield = q;
            cpmd.Strike = k;
            cpmd.Maturity = m;
            cpmd.CallPrice = cp;

            marketData.Add(espmd);
            marketData.Add(cpmd);

            EstimationResult res = c.Estimate(marketData, null);
            return (Vector)res.Values;
        }