Exemple #1
0
        static void Main(string[] args)
        {
            // 32-point Gauss-Laguerre Abscissas and weights
            double[] xGLa = new Double[32];
            double[] wGLa = new Double[32];
            using (TextReader reader = File.OpenText("../../GaussLaguerre32.txt"))
            {
                for (int k = 0; k <= 31; k++)
                {
                    string   text = reader.ReadLine();
                    string[] bits = text.Split(' ');
                    xGLa[k] = double.Parse(bits[0]);
                    wGLa[k] = double.Parse(bits[1]);
                }
            }
            // 32-point Gauss-Legendre Abscissas and weights
            double[] xGLe = new Double[32];
            double[] wGLe = new Double[32];
            using (TextReader reader = File.OpenText("../../GaussLegendre32.txt"))
            {
                for (int k = 0; k <= 31; k++)
                {
                    string   text = reader.ReadLine();
                    string[] bits = text.Split(' ');
                    xGLe[k] = double.Parse(bits[0]);
                    wGLe[k] = double.Parse(bits[1]);
                }
            }
            // 32-point Gauss-Lobatto Abscissas and weights
            double[] xGLo = new Double[32];
            double[] wGLo = new Double[32];
            using (TextReader reader = File.OpenText("../../GaussLobatto32.txt"))
            {
                for (int k = 0; k <= 31; k++)
                {
                    string   text = reader.ReadLine();
                    string[] bits = text.Split(' ');
                    xGLo[k] = double.Parse(bits[0]);
                    wGLo[k] = double.Parse(bits[1]);
                }
            }

            // Heston parameters
            HParam param = new HParam();

            param.kappa  = 2.0;
            param.theta  = 0.05;
            param.sigma  = 0.3;
            param.v0     = 0.035;
            param.rho    = -0.9;
            param.lambda = 0.0;

            // Option price settings
            OpSet settings = new OpSet();

            settings.S    = 100.0;
            settings.T    = 0.25;
            settings.r    = 0.05;
            settings.q    = 0.02;
            settings.trap = 1;

            // Lower and upper integration limits
            double a = 0.0;         // Lower Limit for Gauss Legendre and Newton Coates
            double b = 100.0;       // Upper Limit for Gauss Legendre
            double A = 1e-5;        // Lower Limit for Gauss Lobatto
            double B = 100.0;       // Upper Limit for Gauss Lobatto

            int N = 5000;           // Number of points for Newton Coates quadratures

            // Range of strikes and option flavor
            double[] Strikes = new double[] { 90.0, 95.0, 100.0, 105.0, 110.0 };
            settings.PutCall = "C";

            // Initialize the price vectors
            int M = Strikes.Length;

            double[] PriceGLa    = new double[M];
            double[] PriceGLe    = new double[M];
            double[] PriceGLo    = new double[M];
            double[] PriceMP     = new double[M];
            double[] PriceTrapz  = new double[M];
            double[] PriceSimp   = new double[M];
            double[] PriceSimp38 = new double[M];

            // Obtain the prices and output to console
            HestonPrice HP = new HestonPrice();
            NewtonCotes NC = new NewtonCotes();

            Console.WriteLine("Using {0:0} points for Newton Cotes and 32 points for quadrature ", N);
            Console.WriteLine(" ");
            for (int k = 0; k <= M - 1; k++)
            {
                settings.K     = Strikes[k];
                PriceGLa[k]    = HP.HestonPriceGaussLaguerre(param, settings, xGLa, wGLa);       // Gauss Laguerre
                PriceGLe[k]    = HP.HestonPriceGaussLegendre(param, settings, xGLe, wGLe, a, b); // Gauss Legendre
                PriceGLo[k]    = HP.HestonPriceGaussLegendre(param, settings, xGLo, wGLo, A, B); // Gauss Lobatto
                PriceMP[k]     = NC.HestonPriceNewtonCotes(param, settings, 1, a, b, N);         // Mid point rule
                PriceTrapz[k]  = NC.HestonPriceNewtonCotes(param, settings, 2, A, B, N);         // Trapezoidal rule
                PriceSimp[k]   = NC.HestonPriceNewtonCotes(param, settings, 3, A, B, N);         // Simpson's Rule
                PriceSimp38[k] = NC.HestonPriceNewtonCotes(param, settings, 4, A, B, N);         // Simpson's 3/8 rule
                Console.Write("Strike {0,2}", Strikes[k]);
                Console.WriteLine(" ------------------");
                Console.WriteLine("Mid Point       {0:F5}", PriceMP[k]);
                Console.WriteLine("Trapezoidal     {0:F5}", PriceTrapz[k]);
                Console.WriteLine("Simpson's       {0:F5}", PriceSimp[k]);
                Console.WriteLine("Simpson's 3/8   {0:F5}", PriceSimp38[k]);
                Console.WriteLine("Gauss Laguerre  {0:F5}", PriceGLa[k]);
                Console.WriteLine("Gauss Legendre  {0:F5}", PriceGLe[k]);
                Console.WriteLine("Gauss Lobatto   {0:F5}", PriceGLo[k]);
                Console.WriteLine(" ");
            }
        }
        // Heston price by Newton Coates quadratures
        public double HestonPriceNewtonCotes(HParam param, OpSet settings, int method, double a, double b, int N)
        {
            // Built the integration grid
            // For Simpson's 3/8 rule, the code ensures that N-1 is divisible by 3
            double h = (b - a) / (Convert.ToDouble(N) - 1.0);

            double[] phi = new double[N];
            phi[0]     = a;
            phi[N - 1] = b;
            for (int k = 1; k <= N - 2; k++)
            {
                phi[k] = phi[k - 1] + h;
            }

            double[] int1 = new double[N];
            double[] int2 = new double[N];

            HestonPrice HP = new HestonPrice();

            //   Integration methods
            if (method == 1)
            {
                // Mid-Point rule --------------------------------------
                double[] wt = new double[N];
                for (int k = 0; k <= N - 1; k++)
                {
                    wt[k] = h;
                }
                for (int k = 0; k <= N - 2; k++)
                {
                    double mid = (phi[k] + phi[k + 1]) / 2.0;
                    int1[k] = wt[k] * HP.HestonProb(mid, param, settings, 1);
                    int2[k] = wt[k] * HP.HestonProb(mid, param, settings, 2);
                }
                int1[N - 1] = 0.0;
                int2[N - 1] = 0.0;
            }
            else if (method == 2)
            {
                // Trapezoidal rule --------------------------------------------------
                double[] wt = new double[N];
                wt[0]     = 0.5 * h;
                wt[N - 1] = 0.5 * h;
                for (int k = 1; k <= N - 2; k++)
                {
                    wt[k] = h;
                }
                for (int k = 0; k <= N - 1; k++)
                {
                    int1[k] = wt[k] * HP.HestonProb(phi[k], param, settings, 1);
                    int2[k] = wt[k] * HP.HestonProb(phi[k], param, settings, 2);
                }
            }
            else if (method == 3)
            {
                // Simpson's Rule ----------------------------------------------------
                double[] wt = new double[N];
                wt[0]     = h / 3.0;
                wt[N - 1] = h / 3.0;
                for (int k = 1; k <= N - 1; k++)
                {
                    wt[k] = (h / 3.0) * (3 + Math.Pow(-1, k + 1));
                }
                for (int k = 0; k <= N - 1; k++)
                {
                    int1[k] = wt[k] * HP.HestonProb(phi[k], param, settings, 1);
                    int2[k] = wt[k] * HP.HestonProb(phi[k], param, settings, 2);
                }
            }
            else if (method == 4)
            {
                // Simpson's 3/8 rule --------------------------------------------
                // Ensure that N-1 is divisible by 3
                N = N - (N % 3);

                // Build the new grid
                h = (b - a) / (N - 1.0);
                double[] phi2 = new double[N];
                phi2[0]     = a;
                phi2[N - 1] = b;
                for (int k = 1; k <= N - 2; k++)
                {
                    phi2[k] = phi2[k - 1] + h;
                }

                double[] wt = new double[N];
                wt[0]     = 3.0 / 8.0 * h;
                wt[1]     = 9.0 / 8.0 * h;
                wt[2]     = 9.0 / 8.0 * h;
                wt[N - 1] = 3.0 / 8.0 * h;
                for (int k = 3; k <= N - 1; k++)
                {
                    if ((k % 3) == 1)
                    {
                        wt[k] = 6.0 / 8.0 * h;
                    }
                    else
                    {
                        wt[k] = 9.0 / 8.0 * h;
                    }
                }
                for (int k = 0; k <= N - 1; k++)
                {
                    int1[k] = wt[k] * HP.HestonProb(phi2[k], param, settings, 1);
                    int2[k] = wt[k] * HP.HestonProb(phi2[k], param, settings, 2);
                }
            }

            // The integrals
            double I1 = int1.Sum();
            double I2 = int2.Sum();

            // The probabilities P1 and P2
            double pi = Math.PI;
            double P1 = 0.5 + 1.0 / pi * I1;
            double P2 = 0.5 + 1.0 / pi * I2;

            // The call price
            double S       = settings.S;
            double K       = settings.K;
            double q       = settings.q;
            double r       = settings.r;
            double T       = settings.T;
            string PutCall = settings.PutCall;

            double HestonC = S * Math.Exp(-q * T) * P1 - K * Math.Exp(-r * T) * P2;

            // The put price by put-call parity
            double HestonP = HestonC - S * Math.Exp(-q * T) + K * Math.Exp(-r * T);

            // Output the option price
            if (PutCall == "C")
            {
                return(HestonC);
            }
            else
            {
                return(HestonP);
            }
        }