Beispiel #1
0
        /// <summary>
        /// Расчет будущей цены стредла с учетом заданной волатильности
        /// </summary>
        /// <param name="basePrice">Цена базового актива</param>
        /// <param name="strike">Цена страйк</param>
        /// <param name="expTime">Время до экспирации в долях года (с учетом рабочих дней биржи)</param>
        /// <param name="sigma">Волатильность (всегда положительное число; без перевода в проценты)</param>
        /// <param name="pctRate">Процентная ставка без риска (В ПРОЦЕНТАХ)</param>
        /// <returns>Цена стредла</returns>
        public static double GetStradlePrice(double basePrice, double strike, double expTime, double sigma, double pctRate)
        {
            if ((basePrice <= 0) || (strike <= 0) ||
                (expTime <= 0) || (sigma <= 0))
            {
                return(0);
            }

            double rate = pctRate / 100.0;

            double sst  = sigma * sigma * expTime;
            double sqst = Math.Sqrt(sst);

            double lnP = Math.Log(basePrice / strike);

            double putPx, callPx;
            {
                double d1 = (lnP + 0.5 * sst) / sqst;
                double d2 = (lnP - 0.5 * sst) / sqst;

                double normDistD1;
                try
                {
                    normDistD1 = StatMath.NormalDistribution(d1);
                }
                catch (ArithmeticException arex)
                {
                    ArgumentException argEx = new ArgumentException(
                        String.Format("d1:{0}; lnP:{1}; basePrice:{2}; strike:{3}; sigma:{4}; sst:{5}; sqst:{6}",
                                      d1, lnP, basePrice, strike, sigma, sst, sqst),
                        "d1", arex);
                    throw argEx;
                }

                double normDistD2;
                try
                {
                    normDistD2 = StatMath.NormalDistribution(d2);
                }
                catch (ArithmeticException arex)
                {
                    ArgumentException argEx = new ArgumentException(
                        String.Format("d2:{0}; lnP:{1}; basePrice:{2}; strike:{3}; sigma:{4}; sst:{5}; sqst:{6}",
                                      d2, lnP, basePrice, strike, sigma, sst, sqst),
                        "d2", arex);
                    throw argEx;
                }

                callPx = Math.Exp(-rate * expTime) * (basePrice * normDistD1 - strike * normDistD2);
                putPx  = Math.Exp(-rate * expTime) *
                         (basePrice * (normDistD1 - 1) - strike * (normDistD2 - 1));
            }

            double res = putPx + callPx;

            return(res);
        }
Beispiel #2
0
        /// <summary>
        /// Теоретическая дельта опциона согласно модели Блека-Шолза
        /// </summary>
        /// <param name="basePrice">Цена базового актива</param>
        /// <param name="strike">Цена страйк</param>
        /// <param name="expTime">Время до экспирации в долях года (с учетом рабочих дней биржи)</param>
        /// <param name="sigma">Волатильность (всегда положительное число; без перевода в проценты)</param>
        /// <param name="pctRate">Процентная ставка без риска (В ПРОЦЕНТАХ)</param>
        /// <param name="isCall">Тип опциона, True = CALL</param>
        /// <returns>Дельта опциона</returns>
        public static double GetOptionDelta(double basePrice, double strike, double expTime, double sigma, double pctRate, bool isCall = true)
        {
            double rate = pctRate / 100.0;

            if (isCall)
            {
                if (expTime < Double.Epsilon)
                {
                    if (basePrice <= strike)
                    {
                        return(0);
                    }
                    else
                    {
                        return(1);
                    }
                }

                var variation = sigma * Math.Sqrt(expTime);
                var d1        = Math.Log(basePrice / strike) + rate * expTime + 0.5 * variation * variation;
                d1 /= variation;
                var nd1 = StatMath.NormalDistribution(d1);

                return(nd1);
            }
            else
            {
                if (expTime < Double.Epsilon)
                {
                    if (basePrice >= strike)
                    {
                        return(0);
                    }
                    else
                    {
                        return(-1);
                    }
                }

                var variation = sigma * Math.Sqrt(expTime);
                var d1        = Math.Log(basePrice / strike) + rate * expTime + 0.5 * variation * variation;
                d1 /= variation;
                var nd1 = StatMath.NormalDistribution(d1);

                return(nd1 - 1.0);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Теоретическая тета опциона согласно модели Блека-Шолза
        /// </summary>
        /// <param name="basePrice">Цена базового актива</param>
        /// <param name="strike">Цена страйк</param>
        /// <param name="expTime">Время до экспирации в долях года (с учетом рабочих дней биржи)</param>
        /// <param name="sigma">Волатильность (всегда положительное число; без перевода в проценты)</param>
        /// <param name="pctRate">Процентная ставка без риска (В ПРОЦЕНТАХ)</param>
        /// <param name="isCall">Тип опциона, True = CALL</param>
        /// <returns>Тета опциона</returns>
        public static double GetOptionTheta(double basePrice, double strike, double expTime, double sigma, double pctRate, bool isCall = true)
        {
            double rate = pctRate / 100.0;

            if (isCall)
            {
                if (expTime < Double.Epsilon)
                {
                    return(0);
                }

                var variation = sigma * Math.Sqrt(expTime);
                var d1        = Math.Log(basePrice / strike) + rate * expTime + 0.5 * variation * variation;
                d1 /= variation;
                var d2 = d1 - variation;

                var dnd1 = Math.Exp(-d1 * d1 / 2.0) / Math.Sqrt(2.0 * Math.PI);
                var nd2  = StatMath.NormalDistribution(d2);

                var result = -basePrice * dnd1 * sigma / 2.0 / Math.Sqrt(expTime) - rate * strike * nd2 * Math.Exp(-rate * expTime);

                // know-how: тета нормируется на число дней в году
                return(result / TSLab.Script.Handlers.Options.OptionUtils.DaysInYear);
            }
            else
            {
                if (expTime < Double.Epsilon)
                {
                    return(0);
                }

                var variation = sigma * Math.Sqrt(expTime);
                var d1        = Math.Log(basePrice / strike) + rate * expTime + 0.5 * variation * variation;
                d1 /= variation;
                var d2 = d1 - variation;

                var dnd1 = Math.Exp(-d1 * d1 / 2.0) / Math.Sqrt(2.0 * Math.PI);
                var nd2  = StatMath.NormalDistribution(-d2);

                var result = -basePrice * dnd1 * sigma / 2.0 / Math.Sqrt(expTime) + rate * strike * nd2 * Math.Exp(-rate * expTime);

                // know-how: тета нормируется на число дней в году
                return(result / TSLab.Script.Handlers.Options.OptionUtils.DaysInYear);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Расчет будущей цены опциона с учетом заданной волатильности
        /// </summary>
        /// <param name="basePrice">Цена базового актива</param>
        /// <param name="strike">Цена страйк</param>
        /// <param name="expTime">Время до экспирации в долях года (с учетом рабочих дней биржи)</param>
        /// <param name="sigma">Волатильность (всегда положительное число; без перевода в проценты)</param>
        /// <param name="pctRate">Процентная ставка без риска (В ПРОЦЕНТАХ)</param>
        /// <param name="isCall">Тип опциона, True = CALL</param>
        /// <returns>Цена опциона</returns>
        public static double GetOptionPrice(double basePrice, double strike, double expTime, double sigma, double pctRate, bool isCall = true)
        {
            if ((basePrice <= 0) || (strike <= 0) ||
                (expTime <= 0) || (sigma <= 0))
            {
                return(0);
            }

            double sst  = sigma * sigma * expTime;
            double sqst = Math.Sqrt(sst);

            double lnP = Math.Log(basePrice / strike);

            // [2015-12-09] Википедия даёт другую формулу ПРИ УЧЕТЕ ПРОЦЕНТНОЙ СТАВКИ
            // https://en.wikipedia.org/wiki/Black%E2%80%93Scholes_model
            double rate = pctRate / 100.0;

            //double d1 = (lnP + 0.5 * sst) / sqst;
            //double d2 = (lnP - 0.5 * sst) / sqst;

            double d1 = (lnP + 0.5 * sst + rate * expTime) / sqst;
            double d2 = (lnP - 0.5 * sst + rate * expTime) / sqst;

            double normDistD1;

            try
            {
                normDistD1 = StatMath.NormalDistribution(d1);
            }
            catch (ArithmeticException arex)
            {
                ArgumentException argEx = new ArgumentException(
                    String.Format("d1:{0}; lnP:{1}; basePrice:{2}; strike:{3}; sigma:{4}; sst:{5}; sqst:{6}",
                                  d1, lnP, basePrice, strike, sigma, sst, sqst),
                    "d1", arex);
                throw argEx;
            }

            double normDistD2;

            try
            {
                normDistD2 = StatMath.NormalDistribution(d2);
            }
            catch (ArithmeticException arex)
            {
                ArgumentException argEx = new ArgumentException(
                    String.Format("d2:{0}; lnP:{1}; basePrice:{2}; strike:{3}; sigma:{4}; sst:{5}; sqst:{6}",
                                  d2, lnP, basePrice, strike, sigma, sst, sqst),
                    "d2", arex);
                throw argEx;
            }

            double expRt  = Math.Exp(-rate * expTime);
            double callPx = basePrice * normDistD1 - expRt * strike * normDistD2;

            if (isCall)
            {
                //return Math.Exp(-rate * expTime) * (basePrice * normDistD1 - strike * normDistD2);
                return(callPx);
            }
            else
            {
                //return Math.Exp(-rate * expTime) * (basePrice * (normDistD1 - 1) - strike * (normDistD2 - 1));

                // Цена ПУТ вычисляется через паритет:
                double putPx = callPx + expRt * strike - basePrice;
                return(putPx);
            }
        }