Beispiel #1
0
        static void Main(string[] args)
        {
            // 32-point Gauss-Laguerre Abscissas and weights
            double[] x = new Double[32];
            double[] w = 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(' ');
                    x[k] = double.Parse(bits[0]);
                    w[k] = double.Parse(bits[1]);
                }
            }
            // Heston parameters
            HParam param = new HParam();

            param.kappa  = 0.2;
            param.theta  = 0.05;
            param.sigma  = 0.3;
            param.v0     = 0.05;
            param.rho    = -0.7;
            param.lambda = 0.0;

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

            settings.S       = 50.0;
            settings.T       = 0.5;
            settings.r       = 0.03;
            settings.q       = 0.05;
            settings.PutCall = "C";
            settings.trap    = 1;

            // FFT settings
            double M       = Math.Pow(2.0, 10.0);
            int    N       = Convert.ToInt16(M);
            double alpha   = 1.5;
            double uplimit = 100.0;
            string rule    = "Trapezoidal";

            double[,] PriceFFT = new double[N, 2];

            // Discount the spot price by the dividend yield, use as input in FFT
            settings.S = settings.S * Math.Exp(-settings.q * settings.T);

            // Obtain the FFT strikes and calls
            FFT FFT = new FFT();

            PriceFFT = FFT.HestonFFT(N, uplimit, alpha, rule, param, settings);

            // Obtain the extact price and compare to FFT price
            HestonPrice HP = new HestonPrice();

            double[] PriceHeston = new double[N];
            for (int j = 0; j <= N - 1; j++)
            {
                settings.K     = PriceFFT[j, 0];
                PriceHeston[j] = HP.HestonPriceGaussLaguerre(param, settings, x, w);
            }

            // Output the results near the money
            int start = N / 2 - 5;
            int end   = N / 2 + 5;

            Console.WriteLine("Fast Fourier Transform");
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("Strike        FFT Price     Heston Price");
            Console.WriteLine("----------------------------------------");
            for (int j = start; j <= end; j++)
            {
                Console.WriteLine("{0,2:F2} {1,15:F4} {2,15:F4} ", PriceFFT[j, 0], PriceFFT[j, 1], PriceHeston[j]);
            }

            Console.WriteLine("----------------------------------------");
        }
Beispiel #2
0
        // Fast Fourier Transform
        public double[,] HestonFFT(int N, double uplimit, double alpha, string rule, HParam param, OpSet settings)
        {
            double s0 = Math.Log(settings.S);
            double pi = Math.PI;

            // Specify the increments
            double eta       = uplimit / Convert.ToDouble(N);
            double lambdainc = 2 * pi / Convert.ToDouble(N) / eta;

            // Initialize and specify the weights
            double[] w = new double[N];
            if (rule == "Trapezoidal")
            {
                w[0]     = 0.5;
                w[N - 1] = 0.5;
                for (int j = 1; j <= N - 2; j++)
                {
                    w[j] = 1;
                }
            }
            else if (rule == "Simpsons")
            {
                w[0]     = 1.0 / 3.0;
                w[N - 1] = 1.0 / 3.0;
                for (int j = 1; j <= N - 1; j++)
                {
                    w[j] = (1.0 / 3.0) * (3 + Math.Pow(-1, j + 1));
                }
            }

            // Specify the b parameter
            double b = Convert.ToDouble(N) * lambdainc / 2.0;

            // Create the grid for the integration
            double[] v = new double[N];
            for (int j = 0; j <= N - 1; j++)
            {
                v[j] = eta * j;
            }

            // Create the grid for the log-strikes and strikes
            double[] k = new double[N];
            double[] K = new double[N];
            for (int j = 0; j <= N - 1; j++)
            {
                k[j] = -b + lambdainc * Convert.ToDouble(j) + s0;
                K[j] = Math.Exp(k[j]);
            }

            double tau = settings.T;
            double r   = settings.r;
            double q   = settings.q;

            // Implement the FFT
            HestonPrice HP = new HestonPrice();
            Complex     i  = new Complex(0.0, 1.0);

            Complex[] psi     = new Complex[N];
            Complex[] phi     = new Complex[N];
            Complex[] x       = new Complex[N];
            Complex[] e       = new Complex[N];
            double[]  CallFFT = new double[N];
            double[]  sume    = new double[N];
            for (int u = 0; u <= N - 1; u++)
            {
                for (int j = 0; j <= N - 1; j++)
                {
                    psi[j]   = HP.HestonCF(v[j] - (alpha + 1.0) * i, param, settings);
                    phi[j]   = Complex.Exp(-r * tau) * psi[j] / (alpha * alpha + alpha - v[j] * v[j] + i * v[j] * (2.0 * alpha + 1.0));
                    x[j]     = Complex.Exp(i * (b - s0) * v[j]) * phi[j] * w[j];
                    e[j]     = Complex.Exp(-i * 2 * pi / Convert.ToDouble(N) * j * u) * x[j];
                    sume[u] += e[j].Real;
                }
                CallFFT[u] = eta * Math.Exp(-alpha * k[u]) / pi * sume[u];
            }

            // Return the FFT call price and the strikes
            double[,] output = new double[N, 2];
            for (int j = 0; j <= N - 1; j++)
            {
                output[j, 0] = K[j];
                output[j, 1] = CallFFT[j];
            }
            return(output);
        }