Esempio n. 1
0
        public void testCachedValues()
        {
            //("Testing Bermudan swaption against cached values...");

            CommonVars vars = new CommonVars();

            vars.today = new Date(15, Month.February, 2002);

            Settings.setEvaluationDate(vars.today);

            vars.settlement = new Date(19, Month.February, 2002);
            // flat yield term structure impling 1x5 swap at 5%
            vars.termStructure.linkTo(Utilities.flatRate(vars.settlement,
                                                         0.04875825,
                                                         new Actual365Fixed()));

            double atmRate = vars.makeSwap(0.0).fairRate();

            VanillaSwap itmSwap = vars.makeSwap(0.8 * atmRate);
            VanillaSwap atmSwap = vars.makeSwap(atmRate);
            VanillaSwap otmSwap = vars.makeSwap(1.2 * atmRate);

            double          a = 0.048696, sigma = 0.0058904;
            ShortRateModel  model         = new HullWhite(vars.termStructure, a, sigma);
            List <Date>     exerciseDates = new List <Date>();
            List <CashFlow> leg           = atmSwap.fixedLeg();

            for (int i = 0; i < leg.Count; i++)
            {
                Coupon coupon = (Coupon)(leg[i]);
                exerciseDates.Add(coupon.accrualStartDate());
            }

            Exercise       exercise   = new BermudanExercise(exerciseDates);
            IPricingEngine treeEngine = new TreeSwaptionEngine(model, 50);
            IPricingEngine fdmEngine  = new FdHullWhiteSwaptionEngine(model as HullWhite);

#if QL_USE_INDEXED_COUPON
            double itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759;
            double itmValueFdm = 42.2111, atmValueFdm = 12.8879, otmValueFdm = 2.44443;
#else
            double itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769;
            double itmValueFdm = 42.2091, atmValueFdm = 12.8864, otmValueFdm = 2.4437;
#endif

            double tolerance = 1.0e-4;

            Swaption swaption = new Swaption(itmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - itmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + itmValue);
            }

            swaption.setPricingEngine(fdmEngine);
            if (Math.Abs(swaption.NPV() - itmValueFdm) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + itmValueFdm);
            }

            swaption = new Swaption(atmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - atmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + atmValue);
            }
            swaption.setPricingEngine(fdmEngine);
            if (Math.Abs(swaption.NPV() - atmValueFdm) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + atmValueFdm);
            }

            swaption = new Swaption(otmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - otmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached out-of-the-money "
                             + "swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + otmValue);
            }
            swaption.setPricingEngine(fdmEngine);
            if (Math.Abs(swaption.NPV() - otmValueFdm) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached out-of-the-money "
                             + "swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + otmValueFdm);
            }

            for (int j = 0; j < exerciseDates.Count; j++)
            {
                exerciseDates[j] = vars.calendar.adjust(exerciseDates[j] - 10);
            }
            exercise = new BermudanExercise(exerciseDates);

#if QL_USE_INDEXED_COUPON
            itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388;
#else
            itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399;
#endif

            swaption = new Swaption(itmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - itmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + itmValue);
            }

            swaption = new Swaption(atmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - atmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + atmValue);
            }

            swaption = new Swaption(otmSwap, exercise);
            swaption.setPricingEngine(treeEngine);
            if (Math.Abs(swaption.NPV() - otmValue) > tolerance)
            {
                QAssert.Fail("failed to reproduce cached out-of-the-money "
                             + "swaption value:\n"
                             + "calculated: " + swaption.NPV() + "\n"
                             + "expected:   " + otmValue);
            }
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            Date     todaysDate     = new Date(15, 2, 2002);
            Calendar calendar       = new TARGET();
            Date     settlementDate = new Date(19, 2, 2002);

            Settings.setEvaluationDate(todaysDate);

            // flat yield term structure impling 1x5 swap at 5%
            Quote flatRate = new SimpleQuote(0.04875825);
            Handle <YieldTermStructure> rhTermStructure = new Handle <YieldTermStructure>(
                new FlatForward(settlementDate, new Handle <Quote>(flatRate),
                                new Actual365Fixed()));

            // Define the ATM/OTM/ITM swaps
            Frequency             fixedLegFrequency     = Frequency.Annual;
            BusinessDayConvention fixedLegConvention    = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter    = new Thirty360(Thirty360.Thirty360Convention.European);
            Frequency             floatingLegFrequency  = Frequency.Semiannual;

            VanillaSwap.Type type           = VanillaSwap.Type.Payer;
            double           dummyFixedRate = 0.03;
            IborIndex        indexSixMonths = new Euribor6M(rhTermStructure);

            Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years,
                                              floatingLegConvention);
            Date maturity = calendar.advance(startDate, 5, TimeUnit.Years,
                                             floatingLegConvention);
            Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency),
                                                  calendar, fixedLegConvention, fixedLegConvention,
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency),
                                                  calendar, floatingLegConvention, floatingLegConvention,
                                                  DateGeneration.Rule.Forward, false);

            VanillaSwap swap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, dummyFixedRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure));
            double fixedAtmRate = swap.fairRate();
            double fixedOtmRate = fixedAtmRate * 1.2;
            double fixedItmRate = fixedAtmRate * 0.8;

            VanillaSwap atmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedAtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap otmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedOtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap itmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedItmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            // defining the swaptions to be used in model calibration
            List <Period> swaptionMaturities = new List <Period>(5);

            swaptionMaturities.Add(new Period(1, TimeUnit.Years));
            swaptionMaturities.Add(new Period(2, TimeUnit.Years));
            swaptionMaturities.Add(new Period(3, TimeUnit.Years));
            swaptionMaturities.Add(new Period(4, TimeUnit.Years));
            swaptionMaturities.Add(new Period(5, TimeUnit.Years));

            List <CalibrationHelper> swaptions = new List <CalibrationHelper>();

            // List of times that have to be included in the timegrid
            List <double> times = new List <double>();

            for (int i = 0; i < NumRows; i++)
            {
                int   j   = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int   k   = i * NumCols + j;
                Quote vol = new SimpleQuote(SwaptionVols[k]);
                swaptions.Add(new SwaptionHelper(swaptionMaturities[i],
                                                 new Period(SwapLenghts[j], TimeUnit.Years),
                                                 new Handle <Quote>(vol),
                                                 indexSixMonths,
                                                 indexSixMonths.tenor(),
                                                 indexSixMonths.dayCounter(),
                                                 indexSixMonths.dayCounter(),
                                                 rhTermStructure, false));
                swaptions.Last().addTimesTo(times);
            }

            // Building time-grid
            TimeGrid grid = new TimeGrid(times, 30);


            // defining the models
            G2              modelG2  = new G2(rhTermStructure);
            HullWhite       modelHw  = new HullWhite(rhTermStructure);
            HullWhite       modelHw2 = new HullWhite(rhTermStructure);
            BlackKarasinski modelBk  = new BlackKarasinski(rhTermStructure);


            // model calibrations

            Console.WriteLine("G2 (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16));
            }
            CalibrateModel(modelG2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a     = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n" +
                              "b     = {2:0.000000}, " +
                              "eta   = {3:0.0000000}\n" +
                              "rho   = {4:0.00000}\n",
                              modelG2.parameters()[0],
                              modelG2.parameters()[1],
                              modelG2.parameters()[2],
                              modelG2.parameters()[3],
                              modelG2.parameters()[4]);

            Console.WriteLine("Hull-White (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw));
            }
            CalibrateModel(modelHw, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw.parameters()[0],
                              modelHw.parameters()[1]);

            Console.WriteLine("Hull-White (numerical) calibration");
            for (int i = 0; i < swaptions.Count(); i++)
            {
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid));
            }
            CalibrateModel(modelHw2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw2.parameters()[0],
                              modelHw2.parameters()[1]);

            Console.WriteLine("Black-Karasinski (numerical) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid));
            }
            CalibrateModel(modelBk, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.00000}\n",
                              modelBk.parameters()[0],
                              modelBk.parameters()[1]);


            // ATM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ATM)",
                              fixedAtmRate);

            List <Date>     bermudanDates = new List <Date>();
            List <CashFlow> leg           = swap.fixedLeg();

            for (int i = 0; i < leg.Count; i++)
            {
                Coupon coupon = (Coupon)leg[i];
                bermudanDates.Add(coupon.accrualStartDate());
            }

            Exercise bermudanExercise = new BermudanExercise(bermudanDates);

            Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise);

            // Do the pricing for each model

            // G2 price the European swaption here, it should switch to bermudan
            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.00}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", bermudanSwaption.NPV());


            // OTM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (OTM)",
                              fixedOtmRate);

            Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise);

            // Do the pricing for each model
            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.0000}", otmBermudanSwaption.NPV());

            // ITM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ITM)",
                              fixedItmRate);

            Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise);

            // Do the pricing for each model
            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", itmBermudanSwaption.NPV());


            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }