Пример #1
0
        public static double ibachelier(OptionType optType, double F, double K, double T, double premium, bool safe = false)
        {
            if (T <= 0.0)
            {
                throw FS.FailWith($"T must be postive, got {T}");
            }
            var epsilon   = optType.ToEpsilon();
            var intrinsic = Math.Max(epsilon * (F - K), 0.0);

            if (premium <= intrinsic)
            {
                if (DoubleUtils.ApproximatelyEqual(premium, intrinsic, DoubleUtils.DoubleEpsilon))
                {
                    return(0.0);
                }


                if (safe)
                {
                    return(0.0);
                }
                throw FS.FailWith($"premium must be larger than intrinsic. Got premium = {premium},  vs intrinsic = {intrinsic}"); //!
            }

            if (F == K)
            {
                return(premium * Math.Sqrt(2.0 * Math.PI / T));
            }

            var sqrtT   = Math.Sqrt(T);
            var phiStar = -Math.Abs((premium - intrinsic) / (K - F));

            var xBar = 0.0;

            if (phiStar < -0.001882039271)
            {
                var g    = 1.0 / (phiStar - 0.5);
                var g2   = g * g;
                var zeta = (0.032114372355 - g2 * (0.016969777977 - g2 * (2.6207332461e-3 - 9.6066952861e-5 * g2)))
                           / (1.0 - g2 * (0.6635646938 - g2 * (0.14528712196 - 0.010472855461 * g2)));
                xBar = g * (1.0 / Math.Sqrt(2.0 * Math.PI) + zeta * g2);
            }
            else
            {
                var h = Math.Sqrt(-Math.Log(-phiStar));
                xBar = (9.4883409779 - h * (9.6320903635 - h * (0.58556997323 + 2.1464093351 * h)))
                       / (1 - h * (0.65174820867 + h * (1.5120247828 + 6.6437847132e-5 * h)));
            }

            var xBar2        = xBar * xBar;
            var nxBar        = SpecialFunction.pdf_normal(xBar);
            var phiTildaXBar = SpecialFunction.cdf_normal(xBar) + nxBar / xBar;
            var q            = (phiTildaXBar - phiStar) / nxBar;
            var xStar        = xBar + (3.0 * q * xBar2 * (2.0 - q * xBar * (2.0 + xBar2)))
                               / (6.0 + q * xBar * (-12.0 + xBar * (6.0 * q + xBar * (-6.0 + q * xBar * (3.0 + xBar2)))));

            return(Math.Abs((K - F) / (xStar * sqrtT)));
        }
Пример #2
0
        public static double beta_black_strike_to_quick_delta(double beta, double F, double T, double sigma, double strike)
        {
            var qd = SpecialFunction.cdf_normal((inv_g(beta, F) - inv_g(beta, strike)) / (sigma * Math.Sqrt(T)));

            if (qd <= -0.5)
            {
                return(1.0 + qd);
            }
            if (qd > 0.5)
            {
                return(qd - 1.0);
            }
            return(qd);
        }
Пример #3
0
        public static double black76(OptionType optType, double F, double K, double sdev)
        {
            var num = optType.ToEpsilon();

            if (sdev < 0.0)
            {
                throw FS.FailWith($"sdev must be positive. Got {sdev}");
            }
            if (sdev == 0.0 || K <= 0.0)
            {
                return(Math.Max(num * (F - K), 0.0));
            }
            else
            {
                var num2 = (Math.Log(F / K) + 0.5 * sdev * sdev) / sdev;
                var num3 = num2 - sdev;
                return(num * (F * SpecialFunction.cdf_normal(num * num2) -
                              K * SpecialFunction.cdf_normal(num * num3)));
            }
        }
Пример #4
0
        public static double m1_beta_black(double beta, double mu, double sigma)
        {
            var betaMinusOne   = beta - 1.0;
            var betaMinusOneSq = betaMinusOne * betaMinusOne;
            var sigma2         = sigma * sigma;
            var sqrt2          = Math.Sqrt(2.0);
            var sqrtPi         = Math.Sqrt(Math.PI);
            var t  = -mu / sigma;
            var t2 = t * t;
            var one_over_two_betaMinusOneSq = 0.5 / betaMinusOneSq;
            var e4     = Math.Exp(-0.5 * t2);
            var a1     = t + sigma / betaMinusOne;
            var group1 = -SpecialFunction.exp_x_N_y(-beta * mu / betaMinusOneSq + (sigma2 + 2.0 * mu) * one_over_two_betaMinusOneSq, a1);
            var a2     = sigma - t;
            var group2 = SpecialFunction.exp_x_N_y(mu + 0.5 * sigma2, a2);
            var f0     = -1.0 / (2.0 * sqrtPi);

            return(f0 * sqrt2 * e4 * beta * sigma
                   - betaMinusOneSq * group1
                   + group2
                   - beta * (mu - beta + 2) * (SpecialFunction.cdf_normal(-t) - 1.0));
        }
Пример #5
0
        public static double beta_black(double beta, OptionType optType, double F, double K, double T, double sigma)
        {
            if (T < 0.0)
            {
                throw FS.FailWith($"T < 0 not allowed, {T}");
            }
            if (sigma < 0.0)
            {
                throw FS.FailWith($"sigma < 0 not allowed {sigma}");
            }
            var stdev = sigma * Math.Sqrt(T);

            if (stdev == 0.0)
            {
                return(Math.Max(optType.ToEpsilon() * (F - K), 0.0));
            }
            var mu  = inv_m1_beta_black(beta, F, stdev);
            var d   = (inv_g(beta, K) - mu) / stdev;
            var t1  = K * SpecialFunction.cdf_normal(d);
            var t2  = beta_black_trunc(beta, mu, stdev, d);
            var put = t1 - t2;

            var intrinsic = Math.Max(optType.ToEpsilon() * (F - K), 0.0);

            if (optType == OptionType.Put)
            {
                return(Math.Max(put, intrinsic));
            }
            else if (optType == OptionType.Call)
            {
                return(Math.Max(put + F - K, intrinsic));
            }
            else
            {
                throw FS.E_CASE(optType);
            }
        }
Пример #6
0
        public static double beta_black_trunc(double beta, double mu, double sigma, double x)
        {
            var betaMinusOne   = beta - 1.0;
            var betaMinusOneSq = betaMinusOne * betaMinusOne;
            var sigma2         = sigma * sigma;
            var sqrt2          = Math.Sqrt(2.0);
            var sqrtPi         = Math.Sqrt(Math.PI);
            var t = -mu / sigma;
            var one_over_two_betaMinusOneSq = 0.5 / betaMinusOneSq;
            var f0 = -1.0 / (2.0 * sqrtPi);

            if (x < t)
            {
                var x2     = x * x;
                var e2     = Math.Exp(-0.5 * x2);
                var a4     = x + sigma / betaMinusOne;
                var group4 = SpecialFunction.exp_x_N_y(-beta * mu / betaMinusOneSq + (sigma2 + 2.0 * mu) * one_over_two_betaMinusOneSq, a4);
                return(f0 * sqrt2 * e2 * beta * sigma +
                       +betaMinusOneSq * group4
                       + beta * SpecialFunction.cdf_normal(x) * (mu - beta + 2.0));
            }
            else
            {
                var t2     = t * t;
                var e4     = Math.Exp(-0.5 * t2);
                var a1     = t + sigma / betaMinusOne;
                var group1 = -SpecialFunction.exp_x_N_y(-beta * mu / betaMinusOneSq + (sigma2 + 2.0 * mu) * one_over_two_betaMinusOneSq, a1);
                var a2     = sigma - t;
                var a3     = x - sigma;
                var group2 = -SpecialFunction.exp_x_N_y(mu + 0.5 * sigma2, -a2);
                var group3 = SpecialFunction.exp_x_N_y(mu + 0.5 * sigma2, a3);
                return(f0 * sqrt2 * e4 * beta * sigma
                       - betaMinusOneSq * group1
                       + (group2 + group3)
                       - beta * (mu - beta + 2) * (SpecialFunction.cdf_normal(-t) - 1.0));
            }
        }
Пример #7
0
 public static double beta_black_cdf(double beta, double mu, double sigma, double x)
 {
     return(SpecialFunction.cdf_normal((inv_g(beta, x) - mu) / sigma));
 }