Esempio n. 1
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);
            }
        }
Esempio n. 2
0
        public static double beta_black_b(double beta, OptionType optType, double F, double K, double T, double sigma
                                          , ref double beta_b, ref double F_b, ref double K_b, ref double T_b, ref double sigma_b, double res_b)
        {
            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 sqrtT = Math.Sqrt(T);
            var stdev = sigma * sqrtT;

            if (stdev == 0.0)
            {
                return(Math.Max(optType.ToEpsilon() * (F - K), 0.0));
            }
            var dmu_dbeta  = 0.0;
            var dmu_dF     = 0.0;
            var dmu_dstdev = 0.0;
            var mu         = inv_m1_beta_black_b(beta, F, stdev, ref dmu_dbeta, ref dmu_dF, ref dmu_dstdev, 1.0);
            var digb_dbeta = 0.0;
            var digb_dK    = 0.0;
            var igb        = inv_g_b(beta, K, ref digb_dbeta, ref digb_dK, 1.0);
            var d          = (igb - mu) / stdev;
            var dNd_dd     = 0.0;
            var Nd         = SpecialFunction.cdf_normal_b(d, ref dNd_dd, 1.0);
            var t1         = K * Nd;
            var dt2_dbeta  = 0.0;
            var dt2_dmu    = 0.0;
            var dt2_dstdev = 0.0;
            var dt2_dd     = 0.0;
            var t2         = beta_black_trunc_b(beta, mu, stdev, d, ref dt2_dbeta, ref dt2_dmu, ref dt2_dstdev, ref dt2_dd, 1.0);
            var res        = t1 - t2;
            // now rewind
            var t1_b = res_b;
            var t2_b = -res_b;

            beta_b += t2_b * dt2_dbeta;
            var mu_b    = t2_b * dt2_dmu;
            var stdev_b = t2_b * dt2_dstdev;
            var d_b     = t2_b * dt2_dd;

            K_b += t1_b * Nd;
            var Nd_b = t1_b * K;

            d_b += Nd_b * dNd_dd;
            var igb_b = d_b / stdev;

            mu_b    += -d_b / stdev;
            stdev_b += -d_b * (igb - mu) / stdev / stdev;
            beta_b  += igb_b * digb_dbeta;
            K_b     += igb_b * digb_dK;
            beta_b  += mu_b * dmu_dbeta;
            F_b     += mu_b * dmu_dF;
            stdev_b += mu_b * dmu_dstdev;
            sigma_b += stdev_b * sqrtT;
            T_b     += stdev_b * sigma / (2.0 * sqrtT);
            if (optType == OptionType.Put)
            {
                return(res);
            }
            else if (optType == OptionType.Call)
            {
                F_b += res_b;
                K_b += -res_b;
                return(res + F - K);
            }
            else
            {
                throw FS.E_CASE(optType);
            }
        }