예제 #1
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);
                        }
                    }
                }
            }
        }
예제 #2
0
        public void TestCallBachelier(int dim, SobolDirection direction)
        {
            var gaussianGen = RandomGenerators.GaussianSobol(direction).Build(dim);

            var chrono = new Stopwatch();

            chrono.Start();

            var       atmCalls    = new double[dim];
            var       strikeCall1 = new double[dim];
            var       strikeCall2 = new double[dim];
            var       strikePut1  = new double[dim];
            var       strikePut2  = new double[dim];
            const int nbPaths     = 1000000;

            for (int index = 0; index < nbPaths; index++)
            {
                var sample = gaussianGen.Next();
                for (int i = 0; i < dim; i++)
                {
                    var gaussian = sample[i];
                    atmCalls[i]    += Math.Max(0.0, gaussian);
                    strikeCall1[i] += Math.Max(0.0, gaussian - 1.0);
                    strikeCall2[i] += Math.Max(0.0, gaussian - 2.0);
                    strikePut1[i]  += Math.Max(0.0, -1.0 - gaussian);
                    strikePut2[i]  += Math.Max(0.0, -2.0 - gaussian);
                }
            }
            for (int i = 0; i < dim; i++)
            {
                atmCalls[i]    /= nbPaths;
                strikeCall1[i] /= nbPaths;
                strikeCall2[i] /= nbPaths;
                strikePut1[i]  /= nbPaths;
                strikePut2[i]  /= nbPaths;
            }

            chrono.Stop();
            Console.WriteLine("Elapsed " + chrono.Elapsed);

            var refAtmCalls    = atmCalls.Select(c => BachelierOption.Price(0.0, 0.0, 1.0, 1.0, 1)).ToArray();
            var refStrikeCall1 = atmCalls.Select(c => BachelierOption.Price(0.0, 1.0, 1.0, 1.0, 1)).ToArray();
            var refStrikeCall2 = atmCalls.Select(c => BachelierOption.Price(0.0, 2.0, 1.0, 1.0, 1)).ToArray();
            var refStrikePut1  = atmCalls.Select(c => BachelierOption.Price(0.0, -1.0, 1.0, 1.0, -1)).ToArray();
            var refStrikePut2  = atmCalls.Select(c => BachelierOption.Price(0.0, -2.0, 1.0, 1.0, -1)).ToArray();

            UnitTestUtils.EqualDoubleArray(atmCalls, refAtmCalls, 2.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikeCall1, refStrikeCall1, 8.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikeCall2, refStrikeCall2, 6.0e-4, true);
            UnitTestUtils.EqualDoubleArray(strikePut1, refStrikePut1, 8.0e-5, true);
            UnitTestUtils.EqualDoubleArray(strikePut2, refStrikePut2, 6.0e-4, true);
        }
예제 #3
0
        public void ImpliedVol_HighRegion_Test()
        {
            const double mat         = 0.5;
            const double vol         = 0.070;
            var          moneynesses = GridUtils.RegularGrid(5.5, 15.0, 10000);

            foreach (double m in moneynesses)
            {
                var strike     = m * vol * Math.Sqrt(mat);
                var option     = BachelierOption.Price(0.0, strike, vol, mat, m > 0 ? 1 : -1);
                var impliedVol = BachelierOption.ImpliedVol(option, 0.0, strike, mat, m > 0 ? 1 : -1);

                var errRelative = (impliedVol - vol) / vol;
                Assert.IsTrue(Math.Abs(errRelative) < 5.5e-11);
            }
        }