/// <summary>
        /// Вега будет иметь размерность 'пункты за 100% волатильности'.
        /// Обычно же опционщики любят смотреть размерность 'пункты за 1% волатильности'.
        /// Поэтому полученное сырое значение ещё надо делить на 100%.
        /// (Эквивалентно умножению на интересующий набег волы для получения дифференциала).
        /// </summary>
        internal static bool TryEstimateVega(double putQty, double callQty, IOptionSeries optSer, IOptionStrikePair pair,
                                             InteractiveSeries smile, NumericalGreekAlgo greekAlgo,
                                             double f, double dSigma, double timeToExpiry, double riskFreeRate, out double rawVega)
        {
            rawVega = Double.NaN;

            if (timeToExpiry < Double.Epsilon)
            {
                throw new ArgumentOutOfRangeException("timeToExpiry", "timeToExpiry must be above zero. timeToExpiry:" + timeToExpiry);
            }

            SmileInfo sInfo = smile.GetTag <SmileInfo>();

            if (sInfo == null)
            {
                return(false);
            }

            double pnl1 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect1 = true;
            {
                // Для первой точки улыбку не трогаем
                {
                    double pairPnl;
                    pnlIsCorrect1 &= SingleSeriesProfile.TryGetPairPrice(
                        putQty, callQty, smile, pair, f, timeToExpiry, riskFreeRate, out pairPnl);
                    pnl1 += pairPnl;
                }
            }

            double pnl2 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect2 = true;

            {
                //InteractiveSeries actualSmile = SingleSeriesProfile.GetRaisedSmile(smile, greekAlgo, dSigma);
                SmileInfo actualSmile = SingleSeriesProfile.GetRaisedSmile(sInfo, greekAlgo, dSigma);

                double pairPnl;
                pnlIsCorrect2 &= SingleSeriesProfile.TryGetPairPrice(
                    putQty, callQty, actualSmile, pair, f, timeToExpiry, riskFreeRate, out pairPnl);
                pnl2 += pairPnl;
            }

            if (pnlIsCorrect1 && pnlIsCorrect2)
            {
                // Первая точка совпадает с текущей, поэтому нет деления на 2.
                //rawVega = ((cash2 + pnl2) - (cash1 + pnl1)) / dSigma;
                rawVega = (pnl2 - pnl1) / dSigma;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Вомма будет иметь размерность 'пункты за 100% волатильности'.
        /// Обычно же опционщики любят смотреть размерность 'пункты за 1% волатильности'.
        /// Поэтому полученное сырое значение ещё надо делить на 100%.
        /// (Эквивалентно умножению на интересующий набег волы для получения дифференциала).
        /// </summary>
        internal static bool TryEstimateVomma(PositionsManager posMan, IOptionSeries optSer, IOptionStrikePair[] pairs,
                                              InteractiveSeries smile, NumericalGreekAlgo greekAlgo,
                                              double f, double dSigma, double timeToExpiry, out double rawVomma)
        {
            rawVomma = Double.NaN;

            if (timeToExpiry < Double.Epsilon)
            {
                throw new ArgumentOutOfRangeException("timeToExpiry", "timeToExpiry must be above zero. timeToExpiry:" + timeToExpiry);
            }

            SmileInfo sInfo = smile.GetTag <SmileInfo>();

            if (sInfo == null)
            {
                return(false);
            }

            double cash1 = 0, pnl1 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect1 = true;
            {
                // фьюч на даёт вклад в вегу
                //SingleSeriesProfile.GetBasePnl(posMan, optSer.UnderlyingAsset, optSer.UnderlyingAsset.Bars.Count - 1, f, out cash1, out pnl1);

                //InteractiveSeries actualSmile;
                //// 1. Изменение положения БА
                //actualSmile = SingleSeriesProfile.GetActualSmile(smile, greekAlgo, f);

                SmileInfo actualSmile;
                // 1. Изменение положения БА
                actualSmile = SingleSeriesProfile.GetActualSmile(sInfo, greekAlgo, f);

                for (int j = 0; j < pairs.Length; j++)
                {
                    IOptionStrikePair pair = pairs[j];
                    double            pairPnl, pairCash;
                    pnlIsCorrect1 &= SingleSeriesProfile.TryGetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    cash1         += pairCash;
                    pnl1          += pairPnl;
                }
            }

            double cash2 = 0, pnl2 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect2 = true;
            {
                // фьюч на даёт вклад в вегу
                //SingleSeriesProfile.GetBasePnl(posMan, optSer.UnderlyingAsset, optSer.UnderlyingAsset.Bars.Count - 1, f, out cash2, out pnl2);

                //InteractiveSeries actualSmile;
                //// 1. Изменение положения БА
                //actualSmile = SingleSeriesProfile.GetActualSmile(smile, greekAlgo, f);
                //// 2. Подъём улыбки на dSigma
                //actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, dSigma);

                SmileInfo actualSmile;
                // 1. Изменение положения БА
                actualSmile = SingleSeriesProfile.GetActualSmile(sInfo, greekAlgo, f);
                // 2. Подъём улыбки на dSigma
                actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, dSigma);

                for (int j = 0; j < pairs.Length; j++)
                {
                    IOptionStrikePair pair = pairs[j];
                    double            pairPnl, pairCash;
                    pnlIsCorrect2 &= SingleSeriesProfile.TryGetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    cash2         += pairCash;
                    pnl2          += pairPnl;
                }
            }

            double cash3 = 0, pnl3 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect3 = true;

            {
                // фьюч на даёт вклад в вегу
                //SingleSeriesProfile.GetBasePnl(posMan, optSer.UnderlyingAsset, optSer.UnderlyingAsset.Bars.Count - 1, f, out cash2, out pnl2);

                //InteractiveSeries actualSmile;
                //// 1. Изменение положения БА
                //actualSmile = SingleSeriesProfile.GetActualSmile(smile, greekAlgo, f);
                //// 2. Подъём улыбки на dSigma
                //actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, dSigma);

                SmileInfo actualSmile;
                // 1. Изменение положения БА
                actualSmile = SingleSeriesProfile.GetActualSmile(sInfo, greekAlgo, f);
                // 2. Подъём улыбки на 2*dSigma
                actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, 2 * dSigma);

                for (int j = 0; j < pairs.Length; j++)
                {
                    IOptionStrikePair pair = pairs[j];
                    double            pairPnl, pairCash;
                    pnlIsCorrect2 &= SingleSeriesProfile.TryGetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    cash3         += pairCash;
                    pnl3          += pairPnl;
                }
            }

            if (pnlIsCorrect1 && pnlIsCorrect2 && pnlIsCorrect3)
            {
                // См. Вики случай r=2, N=2: https://ru.wikipedia.org/wiki/Численное_дифференцирование
                // f''(x0) ~= (f0 - 2*f1 + f2)/h/h
                rawVomma = ((cash1 + pnl1) - 2 * (cash2 + pnl2) + (cash3 + pnl3)) / dSigma / dSigma;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Вега будет иметь размерность 'пункты за 100% волатильности'.
        /// Обычно же опционщики любят смотреть размерность 'пункты за 1% волатильности'.
        /// Поэтому полученное сырое значение ещё надо делить на 100%.
        /// (Эквивалентно умножению на интересующий набег волы для получения дифференциала).
        /// </summary>
        internal static bool TryEstimateVega(PositionsManager posMan, IOptionSeries optSer, IOptionStrikePair[] pairs,
                                             InteractiveSeries smile, NumericalGreekAlgo greekAlgo,
                                             double f, double dSigma, double timeToExpiry, out double rawVega)
        {
            rawVega = Double.NaN;

            if (timeToExpiry < Double.Epsilon)
            {
                throw new ArgumentOutOfRangeException("timeToExpiry", "timeToExpiry must be above zero. timeToExpiry:" + timeToExpiry);
            }

            SmileInfo sInfo = smile.GetTag <SmileInfo>();

            if (sInfo == null)
            {
                return(false);
            }

            double cash1 = 0, pnl1 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect1 = true;
            {
                // фьюч на даёт вклад в вегу
                //SingleSeriesProfile.GetBasePnl(posMan, optSer.UnderlyingAsset, optSer.UnderlyingAsset.Bars.Count - 1, f, out cash1, out pnl1);

                //InteractiveSeries actualSmile;
                //// 1. Изменение положения БА
                //actualSmile = SingleSeriesProfile.GetActualSmile(smile, greekAlgo, f);

                SmileInfo actualSmile;
                // 1. Изменение положения БА
                actualSmile = SingleSeriesProfile.GetActualSmile(sInfo, greekAlgo, f);

                for (int j = 0; j < pairs.Length; j++)
                {
                    IOptionStrikePair pair = pairs[j];
                    double            pairPnl, pairCash;
                    //double putPx = FinMath.GetOptionPrice(f, pair.Strike, dT, sigma.Value, 0, false);
                    //SingleSeriesProfile.GetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    pnlIsCorrect1 &= SingleSeriesProfile.TryGetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    cash1         += pairCash;
                    pnl1          += pairPnl;
                }
            }

            double cash2 = 0, pnl2 = 0;
            // Флаг того, что ПНЛ по всем инструментам был расчитан верно
            bool pnlIsCorrect2 = true;

            {
                // фьюч на даёт вклад в вегу
                //SingleSeriesProfile.GetBasePnl(posMan, optSer.UnderlyingAsset, optSer.UnderlyingAsset.Bars.Count - 1, f, out cash2, out pnl2);

                //InteractiveSeries actualSmile;
                //// 1. Изменение положения БА
                //actualSmile = SingleSeriesProfile.GetActualSmile(smile, greekAlgo, f);
                //// 2. Подъём улыбки на dSigma
                //actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, dSigma);

                SmileInfo actualSmile;
                // 1. Изменение положения БА
                actualSmile = SingleSeriesProfile.GetActualSmile(sInfo, greekAlgo, f);
                // 2. Подъём улыбки на dSigma
                actualSmile = SingleSeriesProfile.GetRaisedSmile(actualSmile, greekAlgo, dSigma);

                for (int j = 0; j < pairs.Length; j++)
                {
                    IOptionStrikePair pair = pairs[j];
                    double            pairPnl, pairCash;
                    //double putPx = FinMath.GetOptionPrice(f, pair.Strike, dT, sigma.Value, 0, false);
                    //SingleSeriesProfile.GetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    pnlIsCorrect2 &= SingleSeriesProfile.TryGetPairPnl(posMan, actualSmile, pair, f, timeToExpiry, out pairCash, out pairPnl);
                    cash2         += pairCash;
                    pnl2          += pairPnl;
                }
            }

            if (pnlIsCorrect1 && pnlIsCorrect2)
            {
                // Первая точка совпадает с текущей, поэтому нет деления на 2.
                rawVega = ((cash2 + pnl2) - (cash1 + pnl1)) / dSigma;
                return(true);
            }
            else
            {
                return(false);
            }
        }