コード例 #1
0
        public void testIntraday()
        {
            // Testing intraday information of dates

            Date d1 = new Date(12, Month.February, 2015, 10, 45, 12, 234);

            QAssert.IsTrue(d1.year() == 2015, "failed to reproduce year");
            QAssert.IsTrue(d1.month() == (int)Month.February, "failed to reproduce month");
            QAssert.IsTrue(d1.Day == 12, "failed to reproduce day");
            QAssert.IsTrue(d1.hours == 10, "failed to reproduce hour of day");
            QAssert.IsTrue(d1.minutes == 45, "failed to reproduce minute of hour");
            QAssert.IsTrue(d1.seconds == 12, "failed to reproduce second of minute");
            QAssert.IsTrue(d1.milliseconds == 234, "failed to reproduce number of milliseconds");

            QAssert.IsTrue(d1.fractionOfSecond == 0.234, "failed to reproduce fraction of second");


            Date d2 = new Date(28, Month.February, 2015, 4, 52, 57, 999);

            QAssert.IsTrue(d2.year() == 2015, "failed to reproduce year");
            QAssert.IsTrue(d2.month() == (int)Month.February, "failed to reproduce month");
            QAssert.IsTrue(d2.Day == 28, "failed to reproduce day");
            QAssert.IsTrue(d2.hours == 4, "failed to reproduce hour of day");
            QAssert.IsTrue(d2.minutes == 52, "failed to reproduce minute of hour");
            QAssert.IsTrue(d2.seconds == 57, "failed to reproduce second of minute");
            QAssert.IsTrue(d2.milliseconds == 999, "failed to reproduce number of milliseconds");

            // test daysBetween when d2 time part is earlier in the day than d1 time part.
            d1 = new Date(new DateTime(2016, 1, 1, 18, 0, 0));
            d2 = new Date(new DateTime(2016, 1, 2, 0, 0, 0));
            QAssert.IsTrue(Date.daysBetween(d1, d2) == 0.25, "failed daysBetween");
        }
コード例 #2
0
        public void testIntraday()
        {
            // Testing intraday behavior of day counter

            Date d1 = new Date(12, Month.February, 2015);
            Date d2 = new Date(14, Month.February, 2015, 12, 34, 17, 1);

            double tol = 100 * Const.QL_EPSILON;

            DayCounter[] dayCounters = { new ActualActual(), new Actual365Fixed(), new Actual360() };

            for (int i = 0; i < dayCounters.Length; ++i)
            {
                DayCounter dc = dayCounters[i];

                double expected = ((12 * 60 + 34) * 60 + 17 + 0.001)
                                  * dc.yearFraction(d1, d1 + 1) / 86400
                                  + dc.yearFraction(d1, d1 + 2);

                QAssert.IsTrue(Math.Abs(dc.yearFraction(d1, d2) - expected) < tol,
                               "can not reproduce result for day counter " + dc.name());

                QAssert.IsTrue(Math.Abs(dc.yearFraction(d2, d1) + expected) < tol,
                               "can not reproduce result for day counter " + dc.name());
            }
        }
コード例 #3
0
ファイル: T_CPISwap.cs プロジェクト: sandboxorg/QLNet
        public void zciisconsistency()
        {
            CommonVars common = new CommonVars();

            ZeroCouponInflationSwap.Type ztype = ZeroCouponInflationSwap.Type.Payer;
            double   nominal   = 1000000.0;
            Date     startDate = new Date(common.evaluationDate);
            Date     endDate   = new Date(25, Month.November, 2059);
            Calendar cal       = new UnitedKingdom();
            BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            dummyDC = null, dc = new ActualActual();
            Period observationLag = new Period(2, TimeUnit.Months);

            double quote          = 0.03714;
            ZeroCouponInflationSwap zciis = new ZeroCouponInflationSwap(ztype, nominal, startDate, endDate, cal,
                                                                        paymentConvention, dc, quote, common.ii, observationLag);

            // simple structure so simple pricing engine - most work done by index
            DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK);

            zciis.setPricingEngine(dse);
            QAssert.IsTrue(Math.Abs(zciis.NPV()) < 1e-3, "zciis does not reprice to zero");

            List <Date> oneDate = new List <Date>();

            oneDate.Add(endDate);
            Schedule schOneDate = new Schedule(oneDate, cal, paymentConvention);

            CPISwap.Type stype = CPISwap.Type.Payer;
            double       inflationNominal = nominal;
            double       floatNominal = inflationNominal * Math.Pow(1.0 + quote, 50);
            bool         subtractInflationNominal = true;
            double       dummySpread = 0.0, dummyFixedRate = 0.0;
            int          fixingDays = 0;
            Date         baseDate   = startDate - observationLag;
            double       baseCPI    = common.ii.fixing(baseDate);

            IborIndex dummyFloatIndex = new IborIndex();

            CPISwap cS = new CPISwap(stype, floatNominal, subtractInflationNominal, dummySpread, dummyDC, schOneDate,
                                     paymentConvention, fixingDays, dummyFloatIndex,
                                     dummyFixedRate, baseCPI, dummyDC, schOneDate, paymentConvention, observationLag,
                                     common.ii, InterpolationType.AsIndex, inflationNominal);

            cS.setPricingEngine(dse);
            QAssert.IsTrue(Math.Abs(cS.NPV()) < 1e-3, "CPISwap as ZCIIS does not reprice to zero");

            for (int i = 0; i < 2; i++)
            {
                double cs = cS.legNPV(i).GetValueOrDefault();
                double z  = zciis.legNPV(i).GetValueOrDefault();
                QAssert.IsTrue(Math.Abs(cs - z) < 1e-3, "zciis leg does not equal CPISwap leg");
            }
            // remove circular refernce
            common.hcpi.linkTo(null);
        }
コード例 #4
0
        public void cpicapfloorpricesurface()
        {
            // check inflation leg vs calculation directly from inflation TS
            CommonVars common = new CommonVars();

            double nominal = 1.0;
            InterpolatedCPICapFloorTermPriceSurface <Bilinear> cpiSurf = new InterpolatedCPICapFloorTermPriceSurface <Bilinear>(
                nominal,
                common.baseZeroRate,
                common.observationLag,
                common.calendar,
                common.convention,
                common.dcZCIIS,
                common.hii,
                common.nominalUK,
                common.cStrikesUK,
                common.fStrikesUK,
                common.cfMaturitiesUK,
                common.cPriceUK,
                common.fPriceUK);

            // test code - note order of indices
            for (int i = 0; i < common.fStrikesUK.Count; i++)
            {
                double qK   = common.fStrikesUK[i];
                int    nMat = common.cfMaturitiesUK.Count;
                for (int j = 0; j < nMat; j++)
                {
                    Period t = common.cfMaturitiesUK[j];
                    double a = common.fPriceUK[i, j];
                    double b = cpiSurf.floorPrice(t, qK);

                    Utils.QL_REQUIRE(Math.Abs(a - b) < 1e-7, () => "cannot reproduce cpi floor data from surface: "
                                     + a + " vs constructed = " + b);
                }
            }

            for (int i = 0; i < common.cStrikesUK.Count; i++)
            {
                double qK   = common.cStrikesUK[i];
                int    nMat = common.cfMaturitiesUK.Count;
                for (int j = 0; j < nMat; j++)
                {
                    Period t = common.cfMaturitiesUK[j];
                    double a = common.cPriceUK[i, j];
                    double b = cpiSurf.capPrice(t, qK);

                    QAssert.IsTrue(Math.Abs(a - b) < 1e-7, "cannot reproduce cpi cap data from surface: "
                                   + a + " vs constructed = " + b);
                }
            }

            // remove circular refernce
            common.hcpi.linkTo(null);
        }
コード例 #5
0
ファイル: T_Vector.cs プロジェクト: OpenDerivatives/QLCore
        public void testEquals()
        {
            Vector vector1 = new Vector(Data);
            Vector vector2 = new Vector(Data);
            Vector vector3 = new Vector(4);

            QAssert.IsTrue(vector1.Equals(vector1));
            QAssert.IsTrue(vector1.Equals(vector2));
            QAssert.IsFalse(vector1.Equals(vector3));
            QAssert.IsFalse(vector1.Equals(null));
            QAssert.IsFalse(vector1.Equals(2));
        }
コード例 #6
0
        public void testClosestIndex()
        {
            // Testing that the returned index is closest to the requested time
            List <double> test_times = new List <double> {
                1.0, 2.0, 5.0
            };
            TimeGrid tg             = new TimeGrid(test_times);
            int      expected_index = 3;

            QAssert.IsTrue(tg.closestIndex(4) == expected_index,
                           "Expected index: " + expected_index + ", which does not match " +
                           "the returned index: " + tg.closestIndex(4));
        }
コード例 #7
0
        public void testClosestTime()
        {
            // Testing that the returned time matches the requested index
            List <double> test_times = new List <double> {
                1.0, 2.0, 5.0
            };
            TimeGrid tg            = new TimeGrid(test_times);
            int      expected_time = 5;

            QAssert.IsTrue(tg.closestTime(4).IsEqual(expected_time),
                           "Expected time of: " + expected_time + ", which does not match " +
                           "the returned time: " + tg.closestTime(4));
        }
コード例 #8
0
ファイル: T_Schedule.cs プロジェクト: OpenDerivatives/QLCore
        public void testCDS2015Convention()
        {
            // Testing CDS2015 semi-annual rolling convention
            //From September 20th 2016 to March 19th 2017 of the next Year,
            //end date is December 20th 2021 for a 5 year Swap
            Schedule s1 = new  MakeSchedule().from(new Date(12, Month.December, 2016))
                          .to(new Date(12, Month.December, 2016) + new Period(5, TimeUnit.Years))
                          .withCalendar(new WeekendsOnly())
                          .withTenor(new Period(3, TimeUnit.Months))
                          .withConvention(BusinessDayConvention.ModifiedFollowing)
                          .withTerminationDateConvention(BusinessDayConvention.Unadjusted)
                          .withRule(DateGeneration.Rule.CDS2015).value();

            QAssert.IsTrue(s1.startDate() == new Date(20, Month.September, 2016));
            QAssert.IsTrue(s1.endDate() == new Date(20, Month.December, 2021));
            Schedule s2 = new MakeSchedule().from(new Date(1, Month.March, 2017))
                          .to(new Date(1, Month.March, 2017) + new Period(5, TimeUnit.Years))
                          .withCalendar(new WeekendsOnly())
                          .withTenor(new Period(3, TimeUnit.Months))
                          .withConvention(BusinessDayConvention.ModifiedFollowing)
                          .withTerminationDateConvention(BusinessDayConvention.Unadjusted)
                          .withRule(DateGeneration.Rule.CDS2015).value();

            QAssert.IsTrue(s2.startDate() == new Date(20, Month.December, 2016));
            QAssert.IsTrue(s2.endDate() == new Date(20, Month.December, 2021));
            //From March 20th 2017 to September 19th 2017
            //end date is June 20th 2022 for a 5 year Swap
            Schedule s3 = new MakeSchedule().from(new Date(20, Month.March, 2017))
                          .to(new Date(20, Month.March, 2017) + new Period(5, TimeUnit.Years))
                          .withCalendar(new WeekendsOnly())
                          .withTenor(new Period(3, TimeUnit.Months))
                          .withConvention(BusinessDayConvention.ModifiedFollowing)
                          .withTerminationDateConvention(BusinessDayConvention.Unadjusted)
                          .withRule(DateGeneration.Rule.CDS2015).value();

            QAssert.IsTrue(s3.startDate() == new Date(20, Month.March, 2017));
            QAssert.IsTrue(s3.endDate() == new Date(20, Month.June, 2022));
        }
コード例 #9
0
        public void testIsdaEngine()
        {
            // Testing ISDA engine calculations for credit-default swaps

            SavedSettings backup = new SavedSettings();

            Date tradeDate = new Date(21, Month.May, 2009);

            Settings.setEvaluationDate(tradeDate);


            //build an ISDA compliant yield curve
            //data comes from Markit published rates
            List <RateHelper> isdaRateHelpers = new List <RateHelper>();

            int[]    dep_tenors = { 1, 2, 3, 6, 9, 12 };
            double[] dep_quotes = { 0.003081,
                                    0.005525,
                                    0.007163,
                                    0.012413,
                                    0.014,
                                    0.015488 };

            for (int i = 0; i < dep_tenors.Length; i++)
            {
                isdaRateHelpers.Add(new DepositRateHelper(dep_quotes[i], new Period(dep_tenors[i], TimeUnit.Months), 2,
                                                          new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360())
                                    );
            }
            int[]    swap_tenors = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30 };
            double[] swap_quotes = { 0.011907,
                                     0.01699,
                                     0.021198,
                                     0.02444,
                                     0.026937,
                                     0.028967,
                                     0.030504,
                                     0.031719,
                                     0.03279,
                                     0.034535,
                                     0.036217,
                                     0.036981,
                                     0.037246,
                                     0.037605 };

            IborIndex isda_ibor = new IborIndex("IsdaIbor", new Period(3, TimeUnit.Months), 2, new USDCurrency(),
                                                new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360());

            for (int i = 0; i < swap_tenors.Length; i++)
            {
                isdaRateHelpers.Add(new SwapRateHelper(swap_quotes[i], new Period(swap_tenors[i], TimeUnit.Years),
                                                       new WeekendsOnly(), Frequency.Semiannual, BusinessDayConvention.ModifiedFollowing, new Thirty360(),
                                                       isda_ibor));
            }

            RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();

            discountCurve.linkTo(new PiecewiseYieldCurve <Discount, LogLinear>(0, new WeekendsOnly(), isdaRateHelpers,
                                                                               new Actual365Fixed()));


            RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle <DefaultProbabilityTermStructure>();

            Date[]   termDates = { new Date(20, Month.June, 2010),
                                   new Date(20,   Month.June, 2011),
                                   new Date(20,   Month.June, 2012),
                                   new Date(20,   Month.June, 2016),
                                   new Date(20,   Month.June, 2019) };
            double[] spreads    = { 0.001, 0.1 };
            double[] recoveries = { 0.2, 0.4 };

            double[] markitValues = { 97798.29358,  //0.001
                                      97776.11889,  //0.001
                                      -914971.5977, //0.1
                                      -894985.6298, //0.1
                                      186921.3594,  //0.001
                                      186839.8148,  //0.001
                                      -1646623.672, //0.1
                                      -1579803.626, //0.1
                                      274298.9203,
                                      274122.4725,
                                      -2279730.93,
                                      -2147972.527,
                                      592420.2297,
                                      591571.2294,
                                      -3993550.206,
                                      -3545843.418,
                                      797501.1422,
                                      795915.9787,
                                      -4702034.688,
                                      -4042340.999 };
#if !QL_USE_INDEXED_COUPON
            double tolerance = 1.0e-2; //TODO Check calculation , tolerance must be 1.0e-6;
#else
            /* The risk-free curve is a bit off. We might skip the tests
             * altogether and rely on running them with indexed coupons
             * disabled, but leaving them can be useful anyway. */
            double tolerance = 1.0e-3;
#endif

            int l = 0;

            for (int i = 0; i < termDates.Length; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        CreditDefaultSwap quotedTrade = new MakeCreditDefaultSwap(termDates[i], spreads[j])
                                                        .withNominal(10000000.0).value();

                        double h = quotedTrade.impliedHazardRate(0.0,
                                                                 discountCurve,
                                                                 new Actual365Fixed(),
                                                                 recoveries[k],
                                                                 1e-10,
                                                                 PricingModel.ISDA);

                        probabilityCurve.linkTo(new FlatHazardRate(0, new WeekendsOnly(), h, new Actual365Fixed()));

                        IsdaCdsEngine engine = new IsdaCdsEngine(probabilityCurve, recoveries[k], discountCurve);

                        CreditDefaultSwap conventionalTrade = new MakeCreditDefaultSwap(termDates[i], 0.01)
                                                              .withNominal(10000000.0)
                                                              .withPricingEngine(engine).value();

                        double x = conventionalTrade.notional().Value;
                        double y = conventionalTrade.fairUpfront();

                        double calculated = Math.Abs((x * y) - markitValues[l]);

                        QAssert.IsTrue(calculated <= tolerance);

                        l++;
                    }
                }
            }
        }
コード例 #10
0
        public void testConventions()
        {
            // Testing business day conventions...

            SingleCase[] testCases =
            {
                // Following
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Following,                  new Date(3,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(3,  Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Following,                  new Date(3,  Month.February, 2015), new Period(4,  TimeUnit.Days),   false, new Date(9,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Following,                  new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), true,  new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Following,                  new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), false, new Date(2,  Month.March,    2015)),

                //ModifiedFollowing
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(3,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(3,  Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(3,  Month.February, 2015), new Period(4,  TimeUnit.Days),   false, new Date(9,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), true,  new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), false, new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(25, Month.March,    2015), new Period(1,  TimeUnit.Months), false, new Date(28, Month.April,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedFollowing,          new Date(7,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(9,  Month.March,    2015)),

                //Preceding
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding,                  new Date(3,  Month.March,    2015), new Period(-1, TimeUnit.Months), false, new Date(3,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding,                  new Date(3,  Month.February, 2015), new Period(-2, TimeUnit.Days),   false, new Date(30, Month.January,  2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding,                  new Date(1,  Month.March,    2015), new Period(-1, TimeUnit.Months), true,  new Date(30, Month.January,  2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Preceding,                  new Date(1,  Month.March,    2015), new Period(-1, TimeUnit.Months), false, new Date(30, Month.January,  2015)),

                //ModifiedPreceding
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding,          new Date(3,  Month.March,    2015), new Period(-1, TimeUnit.Months), false, new Date(3,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding,          new Date(3,  Month.February, 2015), new Period(-2, TimeUnit.Days),   false, new Date(30, Month.January,  2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding,          new Date(1,  Month.March,    2015), new Period(-1, TimeUnit.Months), true,  new Date(2,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.ModifiedPreceding,          new Date(1,  Month.March,    2015), new Period(-1, TimeUnit.Months), false, new Date(2,  Month.February, 2015)),

                //Unadjusted
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted,                 new Date(3,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(3,  Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted,                 new Date(3,  Month.February, 2015), new Period(4,  TimeUnit.Days),   false, new Date(9,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted,                 new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), true,  new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Unadjusted,                 new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), false, new Date(28, Month.February, 2015)),

                //HalfMonthModifiedFollowing
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(3,  Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,  Month.February, 2015), new Period(4,  TimeUnit.Days),   false, new Date(9,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), true,  new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(31, Month.January,  2015), new Period(1,  TimeUnit.Months), false, new Date(27, Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(3,  Month.January,  2015), new Period(1,  TimeUnit.Weeks),  false, new Date(12, Month.January,  2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(21, Month.March,    2015), new Period(1,  TimeUnit.Weeks),  false, new Date(30, Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.HalfMonthModifiedFollowing, new Date(7,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(9,  Month.March,    2015)),

                //Nearest
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(3,  Month.February, 2015), new Period(1,  TimeUnit.Months), false, new Date(3,  Month.March,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(3,  Month.February, 2015), new Period(4,  TimeUnit.Days),   false, new Date(9,  Month.February, 2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(16, Month.April,    2015), new Period(1,  TimeUnit.Months), false, new Date(15, Month.May,      2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(17, Month.April,    2015), new Period(1,  TimeUnit.Months), false, new Date(18, Month.May,      2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(4,  Month.March,    2015), new Period(1,  TimeUnit.Months), false, new Date(2,  Month.April,    2015)),
                new SingleCase(new SouthAfrica(), BusinessDayConvention.Nearest,                    new Date(2,  Month.April,    2015), new Period(1,  TimeUnit.Months), false, new Date(4,  Month.May, 2015))
            };

            int n = testCases.Length;

            for (int i = 0; i < n; i++)
            {
                Calendar calendar = new Calendar(testCases[i].calendar);
                Date     result   = calendar.advance(testCases[i].start, testCases[i].period, testCases[i].convention, testCases[i].endOfMonth);

                QAssert.IsTrue(result == testCases[i].result,
                               "\ncase " + i + ":\n" //<< j << " ("<< desc << "): "
                               + "start date: " + testCases[i].start + "\n"
                               + "calendar: " + calendar + "\n"
                               + "period: " + testCases[i].period + ", end of month: " + testCases[i].endOfMonth + "\n"
                               + "convention: " + testCases[i].convention + "\n"
                               + "expected: " + testCases[i].result + " vs. actual: " + result);
            }
        }
コード例 #11
0
        public void testBMACurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : ITraits <YieldTermStructure>, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap <PiecewiseYieldCurve>, new()
        {
            // readjust settlement
            vars.calendar = new JointCalendar(new BMAIndex().fixingCalendar(),
                                              new USDLibor(new Period(3, TimeUnit.Months)).fixingCalendar(),
                                              JointCalendar.JointCalendarRule.JoinHolidays);
            vars.today = vars.calendar.adjust(Date.Today);
            Settings.setEvaluationDate(vars.today);
            vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days);

            Handle <YieldTermStructure> riskFreeCurve = new Handle <YieldTermStructure>(
                new FlatForward(vars.settlement, 0.04, new Actual360()));

            BMAIndex  bmaIndex   = new BMAIndex();
            IborIndex liborIndex = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve);

            for (int i = 0; i < vars.bmas; ++i)
            {
                Handle <Quote> f = new Handle <Quote>(vars.fractions[i]);
                vars.bmaHelpers.Add(new BMASwapRateHelper(f, new Period(vars.bmaData[i].n, vars.bmaData[i].units),
                                                          vars.settlementDays,
                                                          vars.calendar,
                                                          new Period(vars.bmaFrequency),
                                                          vars.bmaConvention,
                                                          vars.bmaDayCounter,
                                                          bmaIndex,
                                                          liborIndex));
            }

            int  w             = vars.today.weekday();
            Date lastWednesday = (w >= 4) ? vars.today - (w - 4) : vars.today + (4 - w - 7);
            Date lastFixing    = bmaIndex.fixingCalendar().adjust(lastWednesday);

            bmaIndex.addFixing(lastFixing, 0.03);

            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bmaHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check BMA swaps
            BMAIndex  bma     = new BMAIndex(curveHandle);
            IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve);

            for (int i = 0; i < vars.bmas; i++)
            {
                Period tenor = new Period(vars.bmaData[i].n, vars.bmaData[i].units);

                Schedule bmaSchedule = new MakeSchedule().from(vars.settlement)
                                       .to(vars.settlement + tenor)
                                       .withFrequency(vars.bmaFrequency)
                                       .withCalendar(bma.fixingCalendar())
                                       .withConvention(vars.bmaConvention)
                                       .backwards()
                                       .value();

                Schedule liborSchedule = new MakeSchedule().from(vars.settlement)
                                         .to(vars.settlement + tenor)
                                         .withTenor(libor3m.tenor())
                                         .withCalendar(libor3m.fixingCalendar())
                                         .withConvention(libor3m.businessDayConvention())
                                         .endOfMonth(libor3m.endOfMonth())
                                         .backwards()
                                         .value();

                BMASwap swap = new BMASwap(BMASwap.Type.Payer, 100.0, liborSchedule, 0.75, 0.0,
                                           libor3m, libor3m.dayCounter(), bmaSchedule, bma, vars.bmaDayCounter);
                swap.setPricingEngine(new DiscountingSwapEngine(libor3m.forwardingTermStructure()));

                double expectedFraction  = vars.bmaData[i].rate / 100,
                       estimatedFraction = swap.fairLiborFraction();
                double error             = Math.Abs(expectedFraction - estimatedFraction);
                QAssert.IsTrue(error < tolerance,
                               vars.bmaData[i].n + " year(s) BMA swap:\n"
                               + "\n estimated libor fraction: " + estimatedFraction
                               + "\n expected libor fraction:  " + expectedFraction
                               + "\n error:          " + error
                               + "\n tolerance:      " + tolerance);
            }

            // this is a workaround for grabage collection
            // garbage collection needs a proper solution
            IndexManager.instance().clearHistories();
        }
コード例 #12
0
        public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : ITraits <YieldTermStructure>, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap <PiecewiseYieldCurve>, new()
        {
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check deposits
            for (int i = 0; i < vars.deposits; i++)
            {
                Euribor index         = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle);
                double  expectedRate  = vars.depositData[i].rate / 100,
                        estimatedRate = index.fixing(vars.today);
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               vars.depositData[i].n + " "
                               + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)")
                               + " deposit:"
                               + "\n    estimated rate: " + estimatedRate
                               + "\n    expected rate:  " + expectedRate);
            }

            // check swaps
            IborIndex euribor6m = new Euribor6M(curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention);

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                QAssert.IsTrue(error < tolerance,
                               vars.swapData[i].n + " year(s) swap:\n"
                               + "\n estimated rate: " + estimatedRate
                               + "\n expected rate:  " + expectedRate
                               + "\n error:          " + error
                               + "\n tolerance:      " + tolerance);
            }

            // check bonds
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            for (int i = 0; i < vars.bonds; i++)
            {
                Date          maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units);
                Date          issue    = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years);
                List <double> coupons  = new List <double>()
                {
                    vars.bondData[i].coupon / 100.0
                };

                FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0,
                                                       vars.schedules[i], coupons,
                                                       vars.bondDayCounter, vars.bondConvention,
                                                       vars.bondRedemption, issue);

                IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle);
                bond.setPricingEngine(bondEngine);

                double expectedPrice  = vars.bondData[i].price,
                       estimatedPrice = bond.cleanPrice();
                QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance,
                               i + 1 + " bond failure:" +
                               "\n  estimated price: " + estimatedPrice +
                               "\n  expected price:  " + expectedPrice);
            }

            // check FRA
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            IborIndex euribor3m = new Euribor3M(curveHandle);

            for (int i = 0; i < vars.fras; i++)
            {
                Date start = vars.calendar.advance(vars.settlement,
                                                   vars.fraData[i].n,
                                                   vars.fraData[i].units,
                                                   euribor3m.businessDayConvention(),
                                                   euribor3m.endOfMonth());
                Date end = vars.calendar.advance(start, 3, TimeUnit.Months,
                                                 euribor3m.businessDayConvention(),
                                                 euribor3m.endOfMonth());

                ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100,
                                                                    100.0, euribor3m, curveHandle);
                double expectedRate  = vars.fraData[i].rate / 100,
                       estimatedRate = fra.forwardRate().rate();
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               i + 1 + " FRA failure:" +
                               "\n  estimated rate: " + estimatedRate +
                               "\n  expected rate:  " + expectedRate);
            }
        }
コード例 #13
0
        public void testCatBondWithDoomOnceInTenYearsProportional()
        {
            // Testing floating-rate cat bond in a doom once in 10 years scenario with proportional notional reduction

            CommonVars vars = new CommonVars();

            Date today = new Date(22, Month.November, 2004);

            Settings.setEvaluationDate(today);

            int settlementDays = 1;

            Handle <YieldTermStructure> riskFreeRate  = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.025, new Actual360()));
            Handle <YieldTermStructure> discountCurve = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360()));

            IborIndex index      = new USDLibor(new Period(6, TimeUnit.Months), riskFreeRate);
            int       fixingDays = 1;

            double tolerance = 1.0e-6;

            IborCouponPricer pricer = new BlackIborCouponPricer(new Handle <OptionletVolatilityStructure>());

            Schedule sch =
                new Schedule(new Date(30, Month.November, 2004),
                             new Date(30, Month.November, 2008),
                             new Period(Frequency.Semiannual),
                             new UnitedStates(UnitedStates.Market.GovernmentBond),
                             BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                             DateGeneration.Rule.Backward, false);

            List <KeyValuePair <Date, double> > events = new List <KeyValuePair <Date, double> >();

            events.Add(new KeyValuePair <Date, double>(new Date(30, Month.November, 2008), 1000));
            CatRisk doomCatRisk = new EventSet(events, new Date(30, Month.November, 2004), new Date(30, Month.November, 2044));

            CatRisk noCatRisk = new EventSet(new List <KeyValuePair <Date, double> > (),
                                             new Date(1, Month.Jan, 2000), new Date(31, Month.Dec, 2010));

            EventPaymentOffset paymentOffset = new NoOffset();
            NotionalRisk       notionalRisk  = new ProportionalNotionalRisk(paymentOffset, 500, 1500);

            FloatingCatBond catBond =
                new FloatingCatBond(settlementDays, vars.faceAmount, sch,
                                    index, new ActualActual(ActualActual.Convention.ISMA),
                                    notionalRisk,
                                    BusinessDayConvention.ModifiedFollowing, fixingDays,
                                    new List <double>(), new List <double>(),
                                    new List <double?>(), new List <double?>(),
                                    false,
                                    100.0, new Date(30, Month.November, 2004));

            IPricingEngine catBondEngine = new MonteCarloCatBondEngine(doomCatRisk, discountCurve);

            catBond.setPricingEngine(catBondEngine);
            Utils.setCouponPricer(catBond.cashflows(), pricer);

            double price                 = catBond.cleanPrice();
            double yield                 = catBond.yield(new ActualActual(ActualActual.Convention.ISMA), Compounding.Simple, Frequency.Annual);
            double lossProbability       = catBond.lossProbability();
            double exhaustionProbability = catBond.exhaustionProbability();
            double expectedLoss          = catBond.expectedLoss();

            QAssert.AreEqual(0.1, lossProbability, tolerance);
            QAssert.AreEqual(0.0, exhaustionProbability, tolerance);
            QAssert.AreEqual(0.05, expectedLoss, tolerance);

            IPricingEngine catBondEngineRF = new MonteCarloCatBondEngine(noCatRisk, discountCurve);

            catBond.setPricingEngine(catBondEngineRF);

            double riskFreePrice           = catBond.cleanPrice();
            double riskFreeYield           = catBond.yield(new ActualActual(ActualActual.Convention.ISMA), Compounding.Simple, Frequency.Annual);
            double riskFreeLossProbability = catBond.lossProbability();
            double riskFreeExpectedLoss    = catBond.expectedLoss();

            QAssert.AreEqual(0.0, riskFreeLossProbability, tolerance);
            QAssert.IsTrue(Math.Abs(riskFreeExpectedLoss) < tolerance);

            QAssert.AreEqual(riskFreePrice * 0.95, price, tolerance);
            QAssert.IsTrue(riskFreeYield < yield);
        }
コード例 #14
0
ファイル: T_DayCounters.cs プロジェクト: zeta1999/QLNet
        public void testActualActualWithSemiannualSchedule()
        {
            // Testing actual/actual with schedule for undefined semiannual reference periods

            Calendar calendar     = new UnitedStates();
            Date     fromDate     = new Date(10, Month.January, 2017);
            Date     firstCoupon  = new Date(31, Month.August, 2017);
            Date     quasiCoupon  = new Date(28, Month.February, 2017);
            Date     quasiCoupon2 = new Date(31, Month.August, 2016);

            Schedule schedule = new MakeSchedule()
                                .from(fromDate)
                                .withFirstDate(firstCoupon)
                                .to(new Date(28, Month.February, 2026))
                                .withFrequency(Frequency.Semiannual)
                                .withCalendar(calendar)
                                .withConvention(BusinessDayConvention.Unadjusted)
                                .backwards().endOfMonth(true).value();

            Date       testDate             = schedule.date(1);
            DayCounter dayCounter           = new ActualActual(ActualActual.Convention.ISMA, schedule);
            DayCounter dayCounterNoSchedule = new ActualActual(ActualActual.Convention.ISMA);

            Date referencePeriodStart = schedule.date(1);
            Date referencePeriodEnd   = schedule.date(2);

            // Test
            QAssert.IsTrue(dayCounter.yearFraction(referencePeriodStart,
                                                   referencePeriodStart).IsEqual(0.0), "This should be zero.");

            QAssert.IsTrue(dayCounterNoSchedule.yearFraction(referencePeriodStart,
                                                             referencePeriodStart).IsEqual(0.0), "This should be zero");

            QAssert.IsTrue(dayCounterNoSchedule.yearFraction(referencePeriodStart,
                                                             referencePeriodStart, referencePeriodStart, referencePeriodStart).IsEqual(0.0),
                           "This should be zero");

            QAssert.IsTrue(dayCounter.yearFraction(referencePeriodStart,
                                                   referencePeriodEnd).IsEqual(0.5),
                           "This should be exact using schedule; "
                           + referencePeriodStart + " to " + referencePeriodEnd
                           + "Should be 0.5");

            QAssert.IsTrue(dayCounterNoSchedule.yearFraction(referencePeriodStart,
                                                             referencePeriodEnd, referencePeriodStart, referencePeriodEnd).IsEqual(0.5),
                           "This should be exact for explicit reference periods with no schedule");

            while (testDate < referencePeriodEnd)
            {
                double difference =
                    dayCounter.yearFraction(testDate, referencePeriodEnd,
                                            referencePeriodStart, referencePeriodEnd) -
                    dayCounter.yearFraction(testDate, referencePeriodEnd);
                if (Math.Abs(difference) > 1.0e-10)
                {
                    QAssert.Fail("Failed to correctly use the schedule to find the reference period for Act/Act");
                }
                testDate = calendar.advance(testDate, 1, TimeUnit.Days);
            }

            //Test long first coupon
            double calculatedYearFraction =
                dayCounter.yearFraction(fromDate, firstCoupon);
            double expectedYearFraction =
                0.5 + ((double)dayCounter.dayCount(fromDate, quasiCoupon))
                / (2 * dayCounter.dayCount(quasiCoupon2, quasiCoupon));

            QAssert.IsTrue(Math.Abs(calculatedYearFraction - expectedYearFraction) < 1.0e-10,
                           "Failed to compute the expected year fraction " +
                           "\n expected:   " + expectedYearFraction +
                           "\n calculated: " + calculatedYearFraction);

            // test multiple periods

            schedule = new MakeSchedule()
                       .from(new Date(10, Month.January, 2017))
                       .withFirstDate(new Date(31, Month.August, 2017))
                       .to(new Date(28, Month.February, 2026))
                       .withFrequency(Frequency.Semiannual)
                       .withCalendar(calendar)
                       .withConvention(BusinessDayConvention.Unadjusted)
                       .backwards().endOfMonth(false).value();

            Date periodStartDate = schedule.date(1);
            Date periodEndDate   = schedule.date(2);

            dayCounter = new ActualActual(ActualActual.Convention.ISMA, schedule);

            while (periodEndDate < schedule.date(schedule.size() - 2))
            {
                double expected =
                    actualActualDaycountComputation(schedule,
                                                    periodStartDate,
                                                    periodEndDate);
                double calculated = dayCounter.yearFraction(periodStartDate,
                                                            periodEndDate);

                if (Math.Abs(expected - calculated) > 1e-8)
                {
                    QAssert.Fail("Failed to compute the correct year fraction " +
                                 "given a schedule: " + periodStartDate +
                                 " to " + periodEndDate +
                                 "\n expected: " + expected +
                                 " calculated: " + calculated);
                }
                periodEndDate = calendar.advance(periodEndDate, 1, TimeUnit.Days);
            }
        }
コード例 #15
0
ファイル: T_CmsSpread.cs プロジェクト: OpenDerivatives/QLCore
        public void testFixings()
        {
            TestData d = new TestData();

            SwapIndex       cms10y   = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), d.yts2, d.yts2);
            SwapIndex       cms2y    = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), d.yts2, d.yts2);
            SwapSpreadIndex cms10y2y = new SwapSpreadIndex("cms10y2y", cms10y, cms2y);

            Settings.Instance.enforcesTodaysHistoricFixings = false;

            try
            {
                cms10y2y.fixing(d.refDate - 1);
                QAssert.Fail("fixing on refDate did not throwed an error.");
            }
            catch
            {
            }

            try
            {
                cms10y2y.fixing(d.refDate);
            }
            catch
            {
                QAssert.Fail("fixing on refDate throwed an error.");
            }

            QAssert.IsTrue(cms10y2y.fixing(d.refDate) ==
                           cms10y.fixing(d.refDate) - cms2y.fixing(d.refDate));
            cms10y.addFixing(d.refDate, 0.05);
            QAssert.IsTrue(cms10y2y.fixing(d.refDate) ==
                           cms10y.fixing(d.refDate) - cms2y.fixing(d.refDate));
            cms2y.addFixing(d.refDate, 0.04);
            QAssert.IsTrue(cms10y2y.fixing(d.refDate) ==
                           cms10y.fixing(d.refDate) - cms2y.fixing(d.refDate));
            Date futureFixingDate = new TARGET().adjust(d.refDate + new Period(1, TimeUnit.Years));

            QAssert.IsTrue(cms10y2y.fixing(futureFixingDate) ==
                           cms10y.fixing(futureFixingDate) -
                           cms2y.fixing(futureFixingDate));
            IndexManager.Instance.clearHistories();

            Settings.Instance.enforcesTodaysHistoricFixings = true;
            try
            {
                cms10y2y.fixing(d.refDate);
                QAssert.Fail("fixing on refDate did not throwed an error.");
            }
            catch
            {
            }

            cms10y.addFixing(d.refDate, 0.05);

            try
            {
                cms10y2y.fixing(d.refDate);
                QAssert.Fail("fixing on refDate did not throwed an error.");
            }
            catch
            {
            }
            cms2y.addFixing(d.refDate, 0.04);

            QAssert.IsTrue(cms10y2y.fixing(d.refDate) ==
                           cms10y.fixing(d.refDate) - cms2y.fixing(d.refDate));
            IndexManager.Instance.clearHistories();
        }
コード例 #16
0
        public void cpicapfloorpricer()
        {
            CommonVars common  = new CommonVars();
            double     nominal = 1.0;
            CPICapFloorTermPriceSurface cpiCFpriceSurf = new InterpolatedCPICapFloorTermPriceSurface
                                                         <Bilinear>(nominal,
                                                                    common.baseZeroRate,
                                                                    common.observationLag,
                                                                    common.calendar,
                                                                    common.convention,
                                                                    common.dcZCIIS,
                                                                    common.hii,
                                                                    common.nominalUK,
                                                                    common.cStrikesUK,
                                                                    common.fStrikesUK,
                                                                    common.cfMaturitiesUK,
                                                                    common.cPriceUK,
                                                                    common.fPriceUK);

            common.cpiCFsurfUK = cpiCFpriceSurf;

            // interpolation pricer first
            // N.B. no new instrument required but we do need a new pricer

            Date     startDate = Settings.evaluationDate();
            Date     maturity = (startDate + new Period(3, TimeUnit.Years));
            Calendar fixCalendar = new UnitedKingdom(), payCalendar = new UnitedKingdom();
            BusinessDayConvention fixConvention        = BusinessDayConvention.Unadjusted,
                                  payConvention        = BusinessDayConvention.ModifiedFollowing;
            double            strike                   = 0.03;
            double            baseCPI                  = common.hii.link.fixing(fixCalendar.adjust(startDate - common.observationLag, fixConvention));
            InterpolationType observationInterpolation = InterpolationType.AsIndex;
            CPICapFloor       aCap                     = new CPICapFloor(Option.Type.Call,
                                                                         nominal,
                                                                         startDate, // start date of contract (only)
                                                                         baseCPI,
                                                                         maturity,  // this is pre-adjustment!
                                                                         fixCalendar,
                                                                         fixConvention,
                                                                         payCalendar,
                                                                         payConvention,
                                                                         strike,
                                                                         common.hii,
                                                                         common.observationLag,
                                                                         observationInterpolation);

            Handle <CPICapFloorTermPriceSurface> cpiCFsurfUKh = new Handle <CPICapFloorTermPriceSurface>(common.cpiCFsurfUK);
            IPricingEngine engine = new InterpolatingCPICapFloorEngine(cpiCFsurfUKh);

            aCap.setPricingEngine(engine);

            Date d = common.cpiCFsurfUK.cpiOptionDateFromTenor(new Period(3, TimeUnit.Years));


            double cached = cpiCFsurfUKh.link.capPrice(d, strike);

            QAssert.IsTrue(Math.Abs(cached - aCap.NPV()) < 1e-10, "InterpolatingCPICapFloorEngine does not reproduce cached price: "
                           + cached + " vs " + aCap.NPV());

            // remove circular refernce
            common.hcpi.linkTo(null);
        }
コード例 #17
0
ファイル: T_CPISwap.cs プロジェクト: sandboxorg/QLNet
        public void cpibondconsistency()
        {
            CommonVars common = new CommonVars();

            // ZeroInflationSwap aka CPISwap

            CPISwap.Type type    = CPISwap.Type.Payer;
            double       nominal = 1000000.0;
            bool         subtractInflationNominal = true;
            // float+spread leg
            double                spread                 = 0.0;
            DayCounter            floatDayCount          = new Actual365Fixed();
            BusinessDayConvention floatPaymentConvention = BusinessDayConvention.ModifiedFollowing;
            int       fixingDays = 0;
            IborIndex floatIndex = new GBPLibor(new Period(6, TimeUnit.Months), common.nominalUK);

            // fixed x inflation leg
            double                fixedRate                = 0.1;   //1% would be 0.01
            double                baseCPI                  = 206.1; // would be 206.13871 if we were interpolating
            DayCounter            fixedDayCount            = new Actual365Fixed();
            BusinessDayConvention fixedPaymentConvention   = BusinessDayConvention.ModifiedFollowing;
            Calendar              fixedPaymentCalendar     = new UnitedKingdom();
            ZeroInflationIndex    fixedIndex               = common.ii;
            Period                contractObservationLag   = common.contractObservationLag;
            InterpolationType     observationInterpolation = common.contractObservationInterpolation;

            // set the schedules
            Date     startDate     = new Date(2, Month.October, 2007);
            Date     endDate       = new Date(2, Month.October, 2052);
            Schedule floatSchedule = new MakeSchedule().from(startDate).to(endDate)
                                     .withTenor(new Period(6, TimeUnit.Months))
                                     .withCalendar(new UnitedKingdom())
                                     .withConvention(floatPaymentConvention)
                                     .backwards().value();
            Schedule fixedSchedule = new MakeSchedule().from(startDate).to(endDate)
                                     .withTenor(new Period(6, TimeUnit.Months))
                                     .withCalendar(new UnitedKingdom())
                                     .withConvention(BusinessDayConvention.Unadjusted)
                                     .backwards().value();

            CPISwap zisV = new CPISwap(type, nominal, subtractInflationNominal,
                                       spread, floatDayCount, floatSchedule,
                                       floatPaymentConvention, fixingDays, floatIndex,
                                       fixedRate, baseCPI, fixedDayCount, fixedSchedule,
                                       fixedPaymentConvention, contractObservationLag,
                                       fixedIndex, observationInterpolation);

            double[] floatFix = { 0.06255, 0.05975, 0.0637, 0.018425, 0.0073438, -1, -1 };
            double[] cpiFix   = { 211.4, 217.2, 211.4, 213.4, -2, -2 };
            for (int i = 0; i < floatSchedule.Count; i++)
            {
                if (floatSchedule[i] < common.evaluationDate)
                {
                    floatIndex.addFixing(floatSchedule[i], floatFix[i], true);//true=overwrite
                }

                CPICoupon zic = zisV.cpiLeg()[i] as CPICoupon;
                if (zic != null)
                {
                    if (zic.fixingDate() < (common.evaluationDate - new Period(1, TimeUnit.Months)))
                    {
                        fixedIndex.addFixing(zic.fixingDate(), cpiFix[i], true);
                    }
                }
            }

            // simple structure so simple pricing engine - most work done by index
            DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK);

            zisV.setPricingEngine(dse);

            // now do the bond equivalent
            List <double> fixedRates     = new InitializedList <double>(1, fixedRate);
            int           settlementDays = 1;// cannot be zero!
            bool          growthOnly     = true;
            CPIBond       cpiB           = new CPIBond(settlementDays, nominal, growthOnly,
                                                       baseCPI, contractObservationLag, fixedIndex,
                                                       observationInterpolation, fixedSchedule,
                                                       fixedRates, fixedDayCount, fixedPaymentConvention);

            DiscountingBondEngine dbe = new DiscountingBondEngine(common.nominalUK);

            cpiB.setPricingEngine(dbe);

            QAssert.IsTrue(Math.Abs(cpiB.NPV() - zisV.legNPV(0).GetValueOrDefault()) < 1e-5,
                           "cpi bond does not equal equivalent cpi swap leg");
            // remove circular refernce
            common.hcpi.linkTo(null);
        }
コード例 #18
0
ファイル: T_CPISwap.cs プロジェクト: sandboxorg/QLNet
        public void consistency()
        {
            // check inflation leg vs calculation directly from inflation TS
            CommonVars common = new CommonVars();

            // ZeroInflationSwap aka CPISwap
            CPISwap.Type type    = CPISwap.Type.Payer;
            double       nominal = 1000000.0;
            bool         subtractInflationNominal = true;
            // float+spread leg
            double                spread                 = 0.0;
            DayCounter            floatDayCount          = new Actual365Fixed();
            BusinessDayConvention floatPaymentConvention = BusinessDayConvention.ModifiedFollowing;
            int       fixingDays = 0;
            IborIndex floatIndex = new GBPLibor(new Period(6, TimeUnit.Months), common.nominalUK);

            // fixed x inflation leg
            double                fixedRate                = 0.1;   //1% would be 0.01
            double                baseCPI                  = 206.1; // would be 206.13871 if we were interpolating
            DayCounter            fixedDayCount            = new Actual365Fixed();
            BusinessDayConvention fixedPaymentConvention   = BusinessDayConvention.ModifiedFollowing;
            Calendar              fixedPaymentCalendar     = new UnitedKingdom();
            ZeroInflationIndex    fixedIndex               = common.ii;
            Period                contractObservationLag   = common.contractObservationLag;
            InterpolationType     observationInterpolation = common.contractObservationInterpolation;

            // set the schedules
            Date     startDate     = new Date(2, Month.October, 2007);
            Date     endDate       = new Date(2, Month.October, 2052);
            Schedule floatSchedule = new MakeSchedule().from(startDate).to(endDate)
                                     .withTenor(new Period(6, TimeUnit.Months))
                                     .withCalendar(new UnitedKingdom())
                                     .withConvention(floatPaymentConvention)
                                     .backwards().value();
            Schedule fixedSchedule = new MakeSchedule().from(startDate).to(endDate)
                                     .withTenor(new Period(6, TimeUnit.Months))
                                     .withCalendar(new UnitedKingdom())
                                     .withConvention(BusinessDayConvention.Unadjusted)
                                     .backwards().value();


            CPISwap zisV = new CPISwap(type, nominal, subtractInflationNominal,
                                       spread, floatDayCount, floatSchedule,
                                       floatPaymentConvention, fixingDays, floatIndex,
                                       fixedRate, baseCPI, fixedDayCount, fixedSchedule,
                                       fixedPaymentConvention, contractObservationLag,
                                       fixedIndex, observationInterpolation);
            Date asofDate = Settings.evaluationDate();

            double[] floatFix = { 0.06255, 0.05975, 0.0637, 0.018425, 0.0073438, -1, -1 };
            double[] cpiFix   = { 211.4, 217.2, 211.4, 213.4, -2, -2 };
            for (int i = 0; i < floatSchedule.Count; i++)
            {
                if (floatSchedule[i] < common.evaluationDate)
                {
                    floatIndex.addFixing(floatSchedule[i], floatFix[i], true);//true=overwrite
                }

                CPICoupon zic = zisV.cpiLeg()[i] as CPICoupon;
                if (zic != null)
                {
                    if (zic.fixingDate() < (common.evaluationDate - new Period(1, TimeUnit.Months)))
                    {
                        fixedIndex.addFixing(zic.fixingDate(), cpiFix[i], true);
                    }
                }
            }

            // simple structure so simple pricing engine - most work done by index
            DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK);

            zisV.setPricingEngine(dse);

            // get float+spread & fixed*inflation leg prices separately
            double testInfLegNPV = 0.0;
            double diff;

            for (int i = 0; i < zisV.leg(0).Count; i++)
            {
                Date zicPayDate = (zisV.leg(0))[i].date();
                if (zicPayDate > asofDate)
                {
                    testInfLegNPV += (zisV.leg(0))[i].amount() * common.nominalUK.link.discount(zicPayDate);
                }

                CPICoupon zicV = zisV.cpiLeg()[i] as CPICoupon;
                if (zicV != null)
                {
                    diff = Math.Abs(zicV.rate() - (fixedRate * (zicV.indexFixing() / baseCPI)));
                    QAssert.IsTrue(diff < 1e-8, "failed " + i + "th coupon reconstruction as "
                                   + (fixedRate * (zicV.indexFixing() / baseCPI)) + " vs rate = "
                                   + zicV.rate() + ", with difference: " + diff);
                }
            }

            double error = Math.Abs(testInfLegNPV - zisV.legNPV(0).Value);

            QAssert.IsTrue(error < 1e-5, "failed manual inf leg NPV calc vs pricing engine: " + testInfLegNPV + " vs " +
                           zisV.legNPV(0));

            diff = Math.Abs(1 - zisV.NPV() / 4191660.0);
         #if QL_USE_INDEXED_COUPON
            double max_diff = 1e-5;
         #else
            double max_diff = 3e-5;
         #endif
            QAssert.IsTrue(diff < max_diff, "failed stored consistency value test, ratio = " + diff);

            // remove circular refernce
            common.hcpi.linkTo(null);
        }
コード例 #19
0
        public void testCachedValue()
        {
            // Testing Black yoy inflation cap/floor price  against cached values...
            CommonVars vars = new CommonVars();

            int whichPricer = 0;          // black

            double          K   = 0.0295; // one centi-point is fair rate error i.e. < 1 cp
            int             j   = 2;
            List <CashFlow> leg = vars.makeYoYLeg(vars.evaluationDate, j);
            Instrument      cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer);

            Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer);


            // close to atm prices
            double cachedCapNPVblack   = 219.452;
            double cachedFloorNPVblack = 314.641;

            // N.B. notionals are 10e6.
            QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVblack) < 0.02, "yoy cap cached NPV wrong "
                           + cap.NPV() + " should be " + cachedCapNPVblack + " Black pricer"
                           + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVblack)));
            QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVblack) < 0.02, "yoy floor cached NPV wrong "
                           + floor.NPV() + " should be " + cachedFloorNPVblack + " Black pricer"
                           + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVblack)));

            whichPricer = 1; // dd

            cap   = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer);
            floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer);

            // close to atm prices
            double cachedCapNPVdd   = 9114.61;
            double cachedFloorNPVdd = 9209.8;

            // N.B. notionals are 10e6.
            QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVdd) < 0.22, "yoy cap cached NPV wrong "
                           + cap.NPV() + " should be " + cachedCapNPVdd + " dd Black pricer"
                           + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVdd)));
            QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVdd) < 0.22, "yoy floor cached NPV wrong "
                           + floor.NPV() + " should be " + cachedFloorNPVdd + " dd Black pricer"
                           + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVdd)));

            whichPricer = 2; // bachelier

            cap   = vars.makeYoYCapFloor(CapFloorType.Cap, leg, K, 0.01, whichPricer);
            floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, K, 0.01, whichPricer);

            // close to atm prices
            double cachedCapNPVbac   = 8852.4;
            double cachedFloorNPVbac = 8947.59;

            // N.B. notionals are 10e6.
            QAssert.IsTrue(Math.Abs(cap.NPV() - cachedCapNPVbac) < 0.22, "yoy cap cached NPV wrong "
                           + cap.NPV() + " should be " + cachedCapNPVbac + " bac Black pricer"
                           + " diff was " + (Math.Abs(cap.NPV() - cachedCapNPVbac)));
            QAssert.IsTrue(Math.Abs(floor.NPV() - cachedFloorNPVbac) < 0.22, "yoy floor cached NPV wrong "
                           + floor.NPV() + " should be " + cachedFloorNPVbac + " bac Black pricer"
                           + " diff was " + (Math.Abs(floor.NPV() - cachedFloorNPVbac)));

            // remove circular refernce
            vars.hy.linkTo(null);
        }
コード例 #20
0
ファイル: T_TermStructures.cs プロジェクト: igitur/qlnet
        public void testCompositeZeroYieldStructures()
        {
            // Testing composite zero yield structures...

            Settings.setEvaluationDate(new Date(10, Month.Nov, 2017));

            // First curve
            var dates = new List <Date>
            {
                new Date(10, Month.Nov, 2017),
                new Date(13, Month.Nov, 2017),
                new Date(12, Month.Feb, 2018),
                new Date(10, Month.May, 2018),
                new Date(10, Month.Aug, 2018),
                new Date(12, Month.Nov, 2018),
                new Date(21, Month.Dec, 2018),
                new Date(15, Month.Jan, 2020),
                new Date(31, Month.Mar, 2021),
                new Date(28, Month.Feb, 2023),
                new Date(21, Month.Dec, 2026),
                new Date(31, Month.Jan, 2030),
                new Date(28, Month.Feb, 2031),
                new Date(31, Month.Mar, 2036),
                new Date(28, Month.Feb, 2041),
                new Date(28, Month.Feb, 2048),
                new Date(31, Month.Dec, 2141)
            };

            var rates = new List <double>
            {
                0.0655823213132524,
                0.0655823213132524,
                0.0699455024156877,
                0.0799107139233497,
                0.0813931951022577,
                0.0841615820666691,
                0.0501297919004145,
                0.0823483583439658,
                0.0860720030924466,
                0.0922887604375688,
                0.10588902278996,
                0.117021968693922,
                0.109824660896137,
                0.109231572878364,
                0.119218123236241,
                0.128647300167664,
                0.0506086995288751
            };

            var termStructure1 = new InterpolatedForwardCurve <BackwardFlat>(dates, rates, new Actual365Fixed(), new NullCalendar());

            // Second curve
            dates = new List <Date>();
            rates = new List <double>();

            dates.Add(new Date(10, Month.Nov, 2017));
            dates.Add(new Date(13, Month.Nov, 2017));
            dates.Add(new Date(11, Month.Dec, 2017));
            dates.Add(new Date(12, Month.Feb, 2018));
            dates.Add(new Date(10, Month.May, 2018));
            dates.Add(new Date(31, Month.Jan, 2022));
            dates.Add(new Date(7, Month.Dec, 2023));
            dates.Add(new Date(31, Month.Jan, 2025));
            dates.Add(new Date(31, Month.Mar, 2028));
            dates.Add(new Date(7, Month.Dec, 2033));
            dates.Add(new Date(1, Month.Feb, 2038));
            dates.Add(new Date(2, Month.Apr, 2046));
            dates.Add(new Date(2, Month.Jan, 2051));
            dates.Add(new Date(31, Month.Dec, 2141));

            rates.Add(0.056656806197189);
            rates.Add(0.056656806197189);
            rates.Add(0.0419541633454473);
            rates.Add(0.0286681050019797);
            rates.Add(0.0148840226959593);
            rates.Add(0.0246680238374363);
            rates.Add(0.0255349067810599);
            rates.Add(0.0298907184711927);
            rates.Add(0.0263943927922053);
            rates.Add(0.0291924526539802);
            rates.Add(0.0270049276163556);
            rates.Add(0.028775807327614);
            rates.Add(0.0293567711641792);
            rates.Add(0.010518655099659);

            var termStructure2 = new InterpolatedForwardCurve <BackwardFlat>(dates, rates, new Actual365Fixed(), new NullCalendar());

            var compoundCurve = new CompositeZeroYieldStructure
                                (
                new Handle <YieldTermStructure>(termStructure1),
                new Handle <YieldTermStructure>(termStructure2),
                sub
                                );

            // Expected values
            dates = new List <Date>();
            rates = new List <double>();

            dates.Add(new Date(10, Month.Nov, 2017));
            dates.Add(new Date(15, Month.Dec, 2017));
            dates.Add(new Date(15, Month.Jun, 2018));
            dates.Add(new Date(15, Month.Sep, 2029));
            dates.Add(new Date(15, Month.Sep, 2038));
            dates.Add(new Date(15, Month.Mar, 2046));
            dates.Add(new Date(15, Month.Dec, 2141));

            rates.Add(0.00892551511527986);
            rates.Add(0.0278755322562788);
            rates.Add(0.0512001768603456);
            rates.Add(0.0729941474263546);
            rates.Add(0.0778333309498459);
            rates.Add(0.0828451659139004);
            rates.Add(0.0503573807521742);

            double tolerance = 1.0e-10;

            for (var i = 0; i < dates.Count; ++i)
            {
                double actual   = compoundCurve.zeroRate(dates[i], new Actual365Fixed(), Compounding.Continuous).rate();
                double expected = rates[i];

                QAssert.IsTrue(Math.Abs(actual - expected) <= tolerance,
                               "unable to reproduce zero yield rate from composite input curve\n"
                               + "    calculated: " + actual + "\n"
                               + "    expected:   " + expected);
            }
        }
コード例 #21
0
ファイル: T_CmsSpread.cs プロジェクト: OpenDerivatives/QLCore
        public void testCouponPricing()
        {
            TestData d   = new TestData();
            double   tol = 1E-6; // abs tolerance coupon rate

            SwapIndex       cms10y   = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), d.yts2, d.yts2);
            SwapIndex       cms2y    = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), d.yts2, d.yts2);
            SwapSpreadIndex cms10y2y = new SwapSpreadIndex("cms10y2y", cms10y, cms2y);

            Date      valueDate = cms10y2y.valueDate(d.refDate);
            Date      payDate   = valueDate + new Period(1, TimeUnit.Years);
            CmsCoupon cpn1a     = new CmsCoupon(10000.0, payDate, valueDate, payDate, cms10y.fixingDays(), cms10y,
                                                1.0, 0.0, null, null, new Actual360(), false);
            CmsCoupon cpn1b = new CmsCoupon(10000.0, payDate, valueDate, payDate, cms2y.fixingDays(),
                                            cms2y, 1.0, 0.0, null, null, new Actual360(), false);
            CmsSpreadCoupon cpn1 = new CmsSpreadCoupon(
                10000.0, payDate, valueDate, payDate, cms10y2y.fixingDays(),
                cms10y2y, 1.0, 0.0, null, null, new Actual360(), false);

            QAssert.IsTrue(cpn1.fixingDate() == d.refDate);
            cpn1a.setPricer(d.cmsPricerLn);
            cpn1b.setPricer(d.cmsPricerLn);
            cpn1.setPricer(d.cmsspPricerLn);
            QAssert.IsTrue(cpn1.rate() == cpn1a.rate() - cpn1b.rate());
            cms10y.addFixing(d.refDate, 0.05);
            QAssert.IsTrue(cpn1.rate() == cpn1a.rate() - cpn1b.rate());
            cms2y.addFixing(d.refDate, 0.03);
            QAssert.IsTrue(cpn1.rate() == cpn1a.rate() - cpn1b.rate());
            IndexManager.Instance.clearHistories();

            CmsCoupon cpn2a = new CmsCoupon(10000.0, new Date(23, Month.February, 2029),
                                            new Date(23, Month.February, 2028), new Date(23, Month.February, 2029), 2,
                                            cms10y, 1.0, 0.0, null, null, new Actual360(), false);
            CmsCoupon cpn2b = new CmsCoupon(10000.0, new Date(23, Month.February, 2029),
                                            new Date(23, Month.February, 2028), new Date(23, Month.February, 2029), 2,
                                            cms2y, 1.0, 0.0, null, null, new Actual360(), false);

            CappedFlooredCmsSpreadCoupon plainCpn =
                new CappedFlooredCmsSpreadCoupon(
                    new Date(23, Month.February, 2029), 10000.0, new Date(23, Month.February, 2028),
                    new Date(23, Month.February, 2029), 2, cms10y2y, 1.0, 0.0, null,
                    null, null, null, new Actual360(), false);
            CappedFlooredCmsSpreadCoupon cappedCpn =
                new CappedFlooredCmsSpreadCoupon(
                    new Date(23, Month.February, 2029), 10000.0, new Date(23, Month.February, 2028),
                    new Date(23, Month.February, 2029), 2, cms10y2y, 1.0, 0.0, 0.03,
                    null, null, null, new Actual360(), false);
            CappedFlooredCmsSpreadCoupon flooredCpn =
                new CappedFlooredCmsSpreadCoupon(
                    new Date(23, Month.February, 2029), 10000.0, new Date(23, Month.February, 2028),
                    new Date(23, Month.February, 2029), 2, cms10y2y, 1.0, 0.0, null,
                    0.01, null, null, new Actual360(), false);
            CappedFlooredCmsSpreadCoupon collaredCpn =
                new CappedFlooredCmsSpreadCoupon(
                    new Date(23, Month.February, 2029), 10000.0, new Date(23, Month.February, 2028),
                    new Date(23, Month.February, 2029), 2, cms10y2y, 1.0, 0.0, 0.03, 0.01,
                    null, null, new Actual360(), false);

            cpn2a.setPricer(d.cmsPricerLn);
            cpn2b.setPricer(d.cmsPricerLn);
            plainCpn.setPricer(d.cmsspPricerLn);
            cappedCpn.setPricer(d.cmsspPricerLn);
            flooredCpn.setPricer(d.cmsspPricerLn);
            collaredCpn.setPricer(d.cmsspPricerLn);

            QAssert.IsTrue(
                Math.Abs(plainCpn.rate() - mcReferenceValue(cpn2a, cpn2b, Double.MaxValue,
                                                            -Double.MaxValue, d.swLn,
                                                            d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(
                Math.Abs(cappedCpn.rate() - mcReferenceValue(cpn2a, cpn2b, 0.03,
                                                             -Double.MaxValue, d.swLn,
                                                             d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(
                Math.Abs(flooredCpn.rate() -
                         mcReferenceValue(cpn2a, cpn2b, Double.MaxValue, 0.01, d.swLn,
                                          d.correlation.currentLink().value())) <

                tol);
            QAssert.IsTrue(
                Math.Abs(collaredCpn.rate() -
                         mcReferenceValue(cpn2a, cpn2b, 0.03, 0.01, d.swLn,
                                          d.correlation.currentLink().value())) <
                tol);

            cpn2a.setPricer(d.cmsPricerSln);
            cpn2b.setPricer(d.cmsPricerSln);
            plainCpn.setPricer(d.cmsspPricerSln);
            cappedCpn.setPricer(d.cmsspPricerSln);
            flooredCpn.setPricer(d.cmsspPricerSln);
            collaredCpn.setPricer(d.cmsspPricerSln);

            QAssert.IsTrue(
                Math.Abs(plainCpn.rate() - mcReferenceValue(cpn2a, cpn2b, Double.MaxValue,
                                                            -Double.MaxValue, d.swSln,
                                                            d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(
                Math.Abs(cappedCpn.rate() - mcReferenceValue(cpn2a, cpn2b, 0.03,
                                                             -Double.MaxValue, d.swSln,
                                                             d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(
                Math.Abs(flooredCpn.rate() -
                         mcReferenceValue(cpn2a, cpn2b, Double.MaxValue, 0.01, d.swSln,
                                          d.correlation.currentLink().value())) <

                tol);
            QAssert.IsTrue(
                Math.Abs(collaredCpn.rate() -
                         mcReferenceValue(cpn2a, cpn2b, 0.03, 0.01, d.swSln,
                                          d.correlation.currentLink().value())) <
                tol);

            cpn2a.setPricer(d.cmsPricerN);
            cpn2b.setPricer(d.cmsPricerN);
            plainCpn.setPricer(d.cmsspPricerN);
            cappedCpn.setPricer(d.cmsspPricerN);
            flooredCpn.setPricer(d.cmsspPricerN);
            collaredCpn.setPricer(d.cmsspPricerN);

            QAssert.IsTrue(
                Math.Abs(plainCpn.rate() - mcReferenceValue(cpn2a, cpn2b, Double.MaxValue,
                                                            -Double.MaxValue, d.swN,
                                                            d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(
                Math.Abs(cappedCpn.rate() - mcReferenceValue(cpn2a, cpn2b, 0.03,
                                                             -Double.MaxValue, d.swN,
                                                             d.correlation.currentLink().value())) <
                tol);
            QAssert.IsTrue(Math.Abs(flooredCpn.rate() -
                                    mcReferenceValue(cpn2a, cpn2b, Double.MaxValue, 0.01,
                                                     d.swN, d.correlation.currentLink().value())) <

                           tol);
            QAssert.IsTrue(Math.Abs(collaredCpn.rate() -
                                    mcReferenceValue(cpn2a, cpn2b, 0.03, 0.01, d.swN,
                                                     d.correlation.currentLink().value())) <
                           tol);
        }