Exemplo n.º 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);
        }
Exemplo n.º 2
0
        private static double CdfProxy(double x)
        {//c.f. D.Lamberton, B.Lapeyre "Introduction au calcul stochastique applique a la finance" p158.
            if (x < 0.0)
            {
                throw new Exception("positive value expected !");
            }

            double t = 1 / (1 + 0.2316419 * x);

            return(1.0 - NormalDistribution.Density(x)
                   * t * (0.319381530 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429)))));
        }
Exemplo n.º 3
0
        public void CallNaiveImplemXCheck()
        {
            var maturities     = GridUtils.RegularGrid(0.1, 5.0, 100);
            var vols           = GridUtils.RegularGrid(0.001, 0.015, 10);
            var volMoneynesses = GridUtils.RegularGrid(-3, 3, 100);

            foreach (var mat in maturities)
            {
                foreach (var vol in vols)
                {
                    var sigma = Math.Sqrt(mat) * vol;
                    foreach (var vm in volMoneynesses)
                    {
                        var strike = vm * sigma;
                        var call   = BachelierOption.Price(0.0, strike, vol, mat, 1);

                        //Naive implementation of bachelier formulae
                        var d           = strike / sigma;
                        var call_xcheck = -strike *NormalDistribution.Cumulative(-d) + sigma * NormalDistribution.Density(d);

                        if (DoubleUtils.EqualZero(call))
                        {
                            Assert.IsTrue(DoubleUtils.EqualZero(call_xcheck));
                        }
                        else
                        {
                            var errRelative = (call - call_xcheck) / call_xcheck;
                            Assert.IsTrue(Math.Abs(errRelative) < 1.0e-13);
                        }
                    }
                }
            }
        }