Пример #1
0
        public void Compute(OptionPosition option)
        {
            var t = option.TimeToExpiry.TotalDays / 365.0;

            if (Math.Abs(t) < Double.Epsilon)
            {
                return;
            }

            var d1 = Math.Log(option.UnderlyingPrice / option.Strike) + (option.InterestRate - option.DividendRate + Math.Pow(option.Volatility, 2)) / t;
            var d2 = d1 - option.Volatility * Math.Sqrt(t);

            // when calculating option greeks keep in mind that we calculate greek for position,
            // and that's why BS formulas for greeks must be multiplied by -1 in case we're selling options
            // so formulas for greeks are [sign * BSFormula]

            if (option.Type == OptionType.Call)
            {
                option.OptionPrice = option.UnderlyingPrice * NormalDistribution.Phi(d1) -
                                     option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(d2);

                option.Delta = Math.Exp(-option.DividendRate * t) * NormalDistribution.Phi(d1);

                option.Theta = -Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) *
                               option.Volatility / (2 * Math.Sqrt(t))
                               +
                               option.DividendRate * Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice *
                               NormalDistribution.Phi(d1)
                               -
                               option.InterestRate * option.Strike * Math.Exp(-option.InterestRate * t) *
                               NormalDistribution.Phi(d2);

                option.Rho = t * option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(d2);
            }
            else
            {
                option.OptionPrice = -option.UnderlyingPrice * NormalDistribution.Phi(-d1) +
                                     option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(-d2);

                option.Delta = Math.Exp(-option.DividendRate * t) * (NormalDistribution.Phi(d1) - 1);

                option.Theta = -Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) *
                               option.Volatility / (2 * Math.Sqrt(t))
                               -
                               option.DividendRate * Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice *
                               NormalDistribution.Phi(-d1)
                               +
                               option.InterestRate * option.Strike * Math.Exp(-option.InterestRate * t) *
                               NormalDistribution.Phi(-d2);

                option.Rho = -t *option.Strike *Math.Exp(-option.InterestRate *t) * NormalDistribution.Phi(-d2);
            }

            option.Gamma = Math.Exp(-option.DividendRate * t) * NormalDistribution.Density(d1) /
                           (option.UnderlyingPrice * option.Volatility * Math.Sqrt(t));
            option.Vega = Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) *
                          Math.Sqrt(t);

            SideHelper.FixGreeksAccordingToSide(option);
        }
Пример #2
0
        public void Compute(OptionPosition option)
        {
            int    steps = option.TreeSteps;
            double s     = option.UnderlyingPrice;

            var t = option.TimeToExpiry.TotalDays / 365.0;

            if (Math.Abs(t) < Double.Epsilon)
            {
                return;
            }
            if (option.TreeSteps == 0)
            {
                return;
            }

            var deltaT = t / (double)steps;

            if (deltaT >= Math.Pow(option.Volatility, 2) / Math.Pow(option.InterestRate - option.DividendRate, 2))
            {
                return;
            }

            double u = Math.Exp(option.Volatility * Math.Sqrt(t));
            double d = 1 / u;

            var prices = GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility,
                                   option.Strike, option.InterestRate, option.DividendRate);

            // x x x
            //   x x
            //     x


            option.OptionPrice = prices[0, 0];
            option.Delta       = (prices[1, 1] - prices[1, 0]) / (s * u - s * d);
            option.Gamma       = ((prices[2, 2] - prices[2, 1]) / (s * u * u - s * u * d) -
                                  (prices[2, 1] - prices[2, 0]) / (s * u * d - s * d * d)) / (0.5 * (s * u * u - s * d * d));
            option.Theta = (prices[2, 1] - prices[0, 0]) / (2 * deltaT);

            option.Vega =
                (GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility * 1.01,
                           option.Strike, option.InterestRate, option.DividendRate)[0, 0]
                 - option.OptionPrice) / (option.Volatility * 0.01);

            option.Rho =
                (GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility,
                           option.Strike, option.InterestRate * 1.01, option.DividendRate)[0, 0]
                 - option.OptionPrice) / (option.InterestRate * 0.01);

            SideHelper.FixGreeksAccordingToSide(option);
        }
Пример #3
0
        public void Compute(OptionPosition option)
        {
            var t = option.TimeToExpiry.TotalDays / 365.0;

            if (Math.Abs(t) < Double.Epsilon)
            {
                return;
            }
            if (option.TreeSteps == 0)
            {
                return;
            }

            Func <double, double> getWithTime = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike,
                                                              option.Volatility, option.InterestRate, option.DividendRate, x, option.TreeSteps)[0, 0];
            Func <double, double> getWithVol = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike,
                                                             x, option.InterestRate, option.DividendRate, t, option.TreeSteps)[0, 0];
            Func <double, double> getWithR = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike,
                                                           option.Volatility, x, option.DividendRate, t, option.TreeSteps)[0, 0];

            var deltaT = t / (double)option.TreeSteps;

            double u = Math.Exp(option.Volatility * Math.Sqrt(2 * deltaT));
            double d = Math.Exp(-option.Volatility * Math.Sqrt(2 * deltaT));

            var prices = GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike,
                                  option.Volatility, option.InterestRate, option.DividendRate, t, option.TreeSteps);

            option.OptionPrice = prices[0, 0];

            option.Delta = (prices[1, 2] - 2 * prices[1, 1] + prices[1, 0]) / (option.UnderlyingPrice * (u - d));

            option.Gamma = ((prices[2, 4] - 2 * prices[2, 3] + prices[2, 2]) / (Math.Pow(option.UnderlyingPrice * (u * u - u), 2)) -
                            (prices[2, 2] - 2 * prices[2, 1] + prices[2, 0]) / (Math.Pow(option.UnderlyingPrice * (d - d * d), 2))) /
                           (0.5 * (option.UnderlyingPrice * (u * u - d * d)));

            option.Theta = (getWithTime(t + deltaT) - getWithTime(t - deltaT)) / (2 * deltaT);

            double volDelta = option.Volatility * 0.01;

            option.Vega = (getWithVol(option.Volatility + volDelta) - getWithVol(option.Volatility - volDelta)) /
                          (2 * volDelta);

            double rDelta = option.InterestRate * 0.01;

            option.Rho = (getWithR(option.InterestRate + rDelta) - getWithR(option.InterestRate - rDelta)) /
                         (2 * rDelta);

            SideHelper.FixGreeksAccordingToSide(option);
        }