Inheritance: QLNet.CalibrationHelper
Exemple #1
0
        public void testCachedHullWhite()
        {
            //("Testing Hull-White calibration against cached values...");

             Date today=new Date(15, Month.February, 2002);
             Date settlement=new Date(19, Month.February, 2002);
             Settings.setEvaluationDate(today);
             Handle<YieldTermStructure> termStructure=
             new Handle<YieldTermStructure>(Utilities.flatRate(settlement, 0.04875825, new Actual365Fixed()));
             //termStructure.link
             HullWhite model=new HullWhite(termStructure);

             CalibrationData[] data = { new CalibrationData( 1, 5, 0.1148 ),
                                    new CalibrationData( 2, 4, 0.1108 ),
                                    new CalibrationData( 3, 3, 0.1070 ),
                                    new CalibrationData( 4, 2, 0.1021 ),
                                    new CalibrationData( 5, 1, 0.1000 )};
             IborIndex index = new Euribor6M(termStructure);

             IPricingEngine engine = new JamshidianSwaptionEngine(model);

             List<CalibrationHelper> swaptions = new List<CalibrationHelper>();
             for (int i=0; i<data.Length; i++) {
               Quote vol = new SimpleQuote(data[i].volatility);
               CalibrationHelper helper =
                                    new SwaptionHelper(new Period(data[i].start,TimeUnit.Years),
                                                      new Period(data[i].length, TimeUnit.Years),
                                                      new Handle<Quote>(vol),
                                                      index,
                                                      new Period(1, TimeUnit.Years),
                                                      new Thirty360(),
                                                      new Actual360(),
                                                      termStructure);
               helper.setPricingEngine(engine);
               swaptions.Add(helper);
             }

             // Set up the optimization problem
             // Real simplexLambda = 0.1;
             // Simplex optimizationMethod(simplexLambda);
             LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(1.0e-8,1.0e-8,1.0e-8);
             EndCriteria endCriteria = new EndCriteria(10000, 100, 1e-6, 1e-8, 1e-8);

             //Optimize
             model.calibrate(swaptions, optimizationMethod, endCriteria, new Constraint(),new List<double>());
             EndCriteria.Type ecType = model.endCriteria();

             // Check and print out results
             #if QL_USE_INDEXED_COUPON
             double cachedA = 0.0488199, cachedSigma = 0.00593579;
             #else
             double cachedA = 0.0488565, cachedSigma = 0.00593662;
             #endif
             double tolerance = 1.120e-5;
             //double tolerance = 1.0e-6;
             Vector xMinCalculated = model.parameters();
             double yMinCalculated = model.value(xMinCalculated, swaptions);
             Vector xMinExpected = new Vector(2);
             xMinExpected[0]= cachedA;
             xMinExpected[1]= cachedSigma;
             double yMinExpected = model.value(xMinExpected, swaptions);
             if (Math.Abs(xMinCalculated[0]-cachedA) > tolerance
               || Math.Abs(xMinCalculated[1]-cachedSigma) > tolerance) {
               Assert.Fail ("Failed to reproduce cached calibration results:\n"
                           + "calculated: a = " + xMinCalculated[0] + ", "
                           + "sigma = " + xMinCalculated[1] + ", "
                           + "f(a) = " + yMinCalculated + ",\n"
                           + "expected:   a = " + xMinExpected[0] + ", "
                           + "sigma = " + xMinExpected[1] + ", "
                           + "f(a) = " + yMinExpected + ",\n"
                           + "difference: a = " + (xMinCalculated[0]-xMinExpected[0]) + ", "
                           + "sigma = " + (xMinCalculated[1]-xMinExpected[1]) + ", "
                           + "f(a) = " + (yMinCalculated - yMinExpected) + ",\n"
                           + "end criteria = " + ecType );
             }
        }
        public void testCalibration()
        {
            //("Testing calibration of a Libor forward model...");

            //SavedSettings backup;

            const int size = 14;
            const double tolerance = 8e-3;

            double[] capVols = {0.145708,0.158465,0.166248,0.168672,
                                    0.169007,0.167956,0.166261,0.164239,
                                    0.162082,0.159923,0.157781,0.155745,
                                    0.153776,0.151950,0.150189,0.148582,
                                    0.147034,0.145598,0.144248};

            double[] swaptionVols = {0.170595, 0.166844, 0.158306, 0.147444,
                                         0.136930, 0.126833, 0.118135, 0.175963,
                                         0.166359, 0.155203, 0.143712, 0.132769,
                                         0.122947, 0.114310, 0.174455, 0.162265,
                                         0.150539, 0.138734, 0.128215, 0.118470,
                                         0.110540, 0.169780, 0.156860, 0.144821,
                                         0.133537, 0.123167, 0.114363, 0.106500,
                                         0.164521, 0.151223, 0.139670, 0.128632,
                                         0.119123, 0.110330, 0.103114, 0.158956,
                                         0.146036, 0.134555, 0.124393, 0.115038,
                                         0.106996, 0.100064};

            IborIndex index = makeIndex();
            LiborForwardModelProcess process = new LiborForwardModelProcess(size, index);
            Handle<YieldTermStructure> termStructure = index.forwardingTermStructure();

            // set-up the model
            LmVolatilityModel volaModel = new LmExtLinearExponentialVolModel(process.fixingTimes(),
                                                                             0.5,0.6,0.1,0.1);

            LmCorrelationModel corrModel = new LmLinearExponentialCorrelationModel(size, 0.5, 0.8);

            LiborForwardModel  model = new LiborForwardModel(process, volaModel, corrModel);

            int swapVolIndex = 0;
            DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter();

            // set-up calibration helper
            List<CalibrationHelper> calibrationHelper = new List<CalibrationHelper>();

            int i;
            for (i=2; i < size; ++i) {
                Period maturity = i*index.tenor();
                Handle<Quote> capVol = new Handle<Quote>(new SimpleQuote(capVols[i-2]));

                CalibrationHelper caphelper = new CapHelper(maturity, capVol, index,Frequency.Annual,
                                  index.dayCounter(), true, termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError);

                caphelper.setPricingEngine(new AnalyticCapFloorEngine(model, termStructure));

                calibrationHelper.Add(caphelper);

                if (i<= size/2) {
                    // add a few swaptions to test swaption calibration as well
                    for (int j=1; j <= size/2; ++j) {
                        Period len = j*index.tenor();
                        Handle<Quote> swaptionVol =  new Handle<Quote>(
                                                         new SimpleQuote(swaptionVols[swapVolIndex++]));

                        CalibrationHelper swaptionHelper =
                            new SwaptionHelper(maturity, len, swaptionVol, index,
                                               index.tenor(), dayCounter,
                                               index.dayCounter(),
                                                              termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError );

                        swaptionHelper.setPricingEngine(new LfmSwaptionEngine(model,termStructure));

                        calibrationHelper.Add(swaptionHelper);
                    }
                }
            }

            LevenbergMarquardt om = new LevenbergMarquardt(1e-6, 1e-6, 1e-6);
            //ConjugateGradient gc = new ConjugateGradient();

            model.calibrate(calibrationHelper,
                            om,
                            new EndCriteria(2000, 100, 1e-6, 1e-6, 1e-6),
                            new Constraint(),
                            new List<double>());

            // measure the calibration error
            double calculated = 0.0;
            for (i=0; i<calibrationHelper.Count ; ++i) {
                double diff = calibrationHelper[i].calibrationError();
                calculated += diff*diff;
            }

            if (Math.Sqrt(calculated) > tolerance)
                Assert.Fail("Failed to calibrate libor forward model"
                            + "\n    calculated diff: " + Math.Sqrt(calculated)
                            + "\n    expected : smaller than  " + tolerance);
        }