public double CZEuroCall(double S0, double tau, HParam param, double K, double rf, double q, double[] Xs, double[] Ws)
        {
            Complex i   = new Complex(0.0, 1.0);
            double  xi  = 0;
            Complex psi = 0;
            int     Nx  = Xs.Length;

            double[] Int1 = new double[Nx];
            double[] Int2 = new double[Nx];
            Complex  I1, I2;

            // Compute the integrands
            CharFun CF = new CharFun();

            for (int k = 0; k <= Nx - 1; k++)
            {
                Complex phi = Xs[k];
                I1      = Complex.Exp(-i * phi * Math.Log(K)) * CF.CZCharFun(S0, tau, xi, param, K, rf, q, phi, psi, 1) / (i * phi);
                Int1[k] = Ws[k] * I1.Real;
                I2      = Complex.Exp(-i * phi * Math.Log(K)) * CF.CZCharFun(S0, tau, xi, param, K, rf, q, phi, psi, 2) / (i * phi);
                Int2[k] = Ws[k] * I2.Real;
            }

            // Define the probabilities
            double pi = Math.PI;
            double P1 = 0.5 + (1.0 / pi) * Int1.Sum();
            double P2 = 0.5 + (1.0 / pi) * Int2.Sum();

            // Return the call price
            return(S0 * Math.Exp(-q * tau) * P1 - K * Math.Exp(-rf * tau) * P2);
        }
Example #2
0
        // Double integral using trapezoidal rule
        public double DoubleTrapezoidal(HParam param, double S0, double K, double tau, double rf, double q,
                                        double b0, double b1, double[] X, double[] T, int funNum)
        {
            Complex i = new Complex(0.0, 1.0);
            double  a, b, c, d, qr = 0.0;
            Complex fun1, fun2, fun3, fun4;
            double  g1, g2, g3, g4, term1, term2, term3;
            int     Nt = T.Length;
            int     Nx = X.Length;

            // Select rate or dividend
            if (funNum == 1)
            {
                qr = q;
            }
            else if (funNum == 2)
            {
                qr = rf;
            }
            double[,] Int = new double[Nt, Nx];
            double sumInt = 0.0;

            // Double trapezoidal rule
            CharFun CF = new CharFun();

            for (int t = 1; t <= Nt - 1; t++)
            {
                a = T[t - 1];
                b = T[t];
                for (int x = 1; x <= Nx - 1; x++)
                {
                    c         = X[x - 1];
                    d         = X[x];
                    fun1      = Complex.Exp(-b0 * i * c) * CF.CZCharFun(S0, tau, a, param, K, rf, q, c, -b1 * c, funNum) / (i * c);
                    fun2      = Complex.Exp(-b0 * i * d) * CF.CZCharFun(S0, tau, a, param, K, rf, q, d, -b1 * d, funNum) / (i * d);
                    fun3      = Complex.Exp(-b0 * i * c) * CF.CZCharFun(S0, tau, b, param, K, rf, q, c, -b1 * c, funNum) / (i * c);
                    fun4      = Complex.Exp(-b0 * i * d) * CF.CZCharFun(S0, tau, b, param, K, rf, q, d, -b1 * d, funNum) / (i * d);
                    g1        = Math.Exp(qr * a) * fun1.Real;
                    g2        = Math.Exp(qr * a) * fun2.Real;
                    g3        = Math.Exp(qr * b) * fun3.Real;
                    g4        = Math.Exp(qr * b) * fun4.Real;
                    term1     = g1 + g2 + g3 + g4;
                    fun1      = Complex.Exp(-b0 * i * c) * CF.CZCharFun(S0, tau, (a + b) / 2.0, param, K, rf, q, c, -b1 * c, funNum) / (i * c);
                    fun2      = Complex.Exp(-b0 * i * d) * CF.CZCharFun(S0, tau, (a + b) / 2.0, param, K, rf, q, d, -b1 * d, funNum) / (i * d);
                    fun3      = Complex.Exp(-b0 * i * (c + d) / 2.0) * CF.CZCharFun(S0, tau, a, param, K, rf, q, (c + d) / 2.0, -b1 * (c + d) / 2.0, funNum) / (i * (c + d) / 2.0);
                    fun4      = Complex.Exp(-b0 * i * (c + d) / 2.0) * CF.CZCharFun(S0, tau, b, param, K, rf, q, (c + d) / 2.0, -b1 * (c + d) / 2.0, funNum) / (i * (c + d) / 2.0);
                    g1        = Math.Exp(qr * (a + b) / 2.0) * fun1.Real;
                    g2        = Math.Exp(qr * (a + b) / 2.0) * fun2.Real;
                    g3        = Math.Exp(qr * a) * fun3.Real;
                    g4        = Math.Exp(qr * b) * fun4.Real;
                    term2     = g1 + g2 + g3 + g4;
                    fun1      = Complex.Exp(-b0 * i * (c + d) / 2.0) * CF.CZCharFun(S0, tau, (a + b) / 2.0, param, K, rf, q, (c + d) / 2.0, -b1 * (c + d) / 2.0, funNum) / (i * (c + d) / 2.0);
                    term3     = Math.Exp(qr * (a + b) / 2.0) * fun1.Real;
                    Int[t, x] = (b - a) * (d - c) / 16.0 * (term1 + 2 * term2 + 4 * term3);
                    sumInt   += Int[t, x];
                }
            }
            return(sumInt);
        }
Example #3
0
        // Double integral using Gauss-Legendre
        public double DoubleGaussLegendre(double S0, double tau, HParam param, double K, double rf, double q, double b0, double b1,
                                          double[] xt, double[] wt, double[] xs, double[] ws, double a, double b, double c, double d, int funNum)
        {
            Complex i = new Complex(0.0, 1.0);
            int     Nt = xt.Length;
            int     Ns = xs.Length;
            double  h1 = (b - a) / 2.0;
            double  h2 = (b + a) / 2.0;
            double  k1 = (d - c) / 2.0;
            double  k2 = (d + c) / 2.0;
            double  time, phi, realfun, qr = 0.0;
            Complex fun;

            // Select rate or dividend
            if (funNum == 1)
            {
                qr = q;
            }
            else if (funNum == 2)
            {
                qr = rf;
            }
            double Int = 0.0;

            // Double integral
            CharFun CF = new CharFun();

            for (int t = 0; t <= Nt - 1; t++)
            {
                time = h1 * xt[t] + h2;
                for (int x = 0; x <= Ns - 1; x++)
                {
                    phi     = k1 * xs[x] + k2;
                    fun     = Complex.Exp(-b0 * i * phi) * CF.CZCharFun(S0, tau, time, param, K, rf, q, phi, -b1 * phi, funNum) / (i * phi);
                    realfun = Math.Exp(qr * time) * fun.Real;
                    Int    += h1 * k1 * wt[t] * ws[x] * realfun;
                }
            }
            return(Int);
        }