예제 #1
0
        public void CheckZeroVolForward(AssetMarket assetMkt)
        {
            var zcCurve = assetMkt.RiskFreeDiscount;
            var market  = new Market(new[] { zcCurve }, new[] { assetMkt });

            var zeroVol           = new MapRawDatas <DateOrDuration, double>(new[] { new DateOrDuration(assetMkt.RefDate) }, new[] { 0.0 });
            var blackScholesDesc  = new BlackScholesModelDescription(assetMkt.Asset.Name, zeroVol, true);
            var mcConfig          = new MonteCarloConfig(1, RandomGenerators.GaussianSobol(SobolDirection.Kuo3));
            var blackScholesModel = ModelFactory.Instance.Build(blackScholesDesc, market);

            var fwdDates = new[] { Duration.Month, 6 * Duration.Month, Duration.Year, 2 * Duration.Year, 5 * Duration.Year }
            .Map(d => assetMkt.RefDate + d);

            IProduct    fwdLeg      = ForwardLeg(fwdDates);
            PriceResult priceResult = (PriceResult)McPricer.WithDetails(mcConfig).Price(fwdLeg, blackScholesModel, market);

            double[] fwds = priceResult.Details.Map(kv => kv.Item3.Value);

            var assetFwdCurve = assetMkt.Forward();

            double[] refFwds = fwdDates.Map(d => assetFwdCurve.Fwd(d) * zcCurve.Zc(d));

            foreach (var i  in Enumerable.Range(0, fwdDates.Length))
            {
                var err = Math.Abs(fwds[i] / refFwds[i] - 1.0);
                Assert.LessOrEqual(err, 20.0 * DoubleUtils.MachineEpsilon);
            }
        }
예제 #2
0
        public void Test()
        {
            var market = Market();

            const double lambda   = 0.01;
            var          sigma    = new StepFunction(new[] { 0.0, 1.0, 2.0 }, new[] { 0.007, 0.004, 0.0065 }, 0.0);
            var          hw1      = new Hw1Model(TimeMeasure.Act365(market.RefDate), Currency.Eur, lambda, sigma);
            var          mcConfig = new MonteCarloConfig(20000,
                                                         RandomGenerators.GaussianSobol(SobolDirection.JoeKuoD5));

            var mcPricer = McPricer.WithDetails(mcConfig);

            var fixedLeg      = FixedLeg(market.RefDate);
            var mcPriceResult = (PriceResult)mcPricer.Price(fixedLeg, hw1, market);

            var mcCoupons  = mcPriceResult.Details.Map(p => p.Item3.Value);
            var refCoupons = mcPriceResult.Details.Map(pi => market.DiscountCurve(pi.Item2.Financing).Zc(pi.Item2.Date));

            var errAbs = Math.Abs(mcCoupons.Sum() - refCoupons.Sum());

            Assert.LessOrEqual(errAbs, 7.0e-5);

            var errRel = Math.Abs(mcCoupons.Sum() / refCoupons.Sum() - 1.0);

            Assert.LessOrEqual(errRel, 8.0e-6);
        }
예제 #3
0
        private static MonteCarloConfig BuildMonteCarloConfig(object[,] bag)
        {
            int      nbPaths = bag.ProcessScalarInteger("NbPaths");
            Duration mcStep  = bag.Has("McStep") ? bag.ProcessScalarDateOrDuration("McStep").Duration : null;

            //TODO investigate which generator is the best
            var randomGenerator = RandomGenerators.GaussianSobol(SobolDirection.Kuo3);

            return(new MonteCarloConfig(nbPaths, randomGenerator, mcStep));
        }
예제 #4
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);
        }