Пример #1
0
        public XABRInterpolationImpl(List <double> xBegin, int size, List <double> yBegin, double t,
                                     double forward, List <double?> _params,
                                     List <bool> paramIsFixed, bool vegaWeighted,
                                     EndCriteria endCriteria,
                                     OptimizationMethod optMethod,
                                     double errorAccept, bool useMaxError, int maxGuesses, List <double?> addParams = null)
            : base(xBegin, size, yBegin)
        {
            // XABRCoeffHolder<Model>(t, forward, params, paramIsFixed),
            endCriteria_  = endCriteria;
            optMethod_    = optMethod;
            errorAccept_  = errorAccept;
            useMaxError_  = useMaxError;
            maxGuesses_   = maxGuesses;
            forward_      = forward;
            vegaWeighted_ = vegaWeighted;

            // if no optimization method or endCriteria is provided, we provide one
            if (optMethod_ == null)
            {
                optMethod_ = new LevenbergMarquardt(1e-8, 1e-8, 1e-8);
            }
            if (endCriteria_ == null)
            {
                endCriteria_ = new EndCriteria(60000, 100, 1e-8, 1e-8, 1e-8);
            }
            coeff_ = new XABRCoeffHolder <Model>(t, forward, _params, paramIsFixed, addParams);
            this.coeff_.weights_ = new InitializedList <double>(size, 1.0 / size);
        }
Пример #2
0
        // to constrained <- from unconstrained
        public AbcdCalibration(List <double> t,
                               List <double> blackVols,
                               double aGuess             = -0.06,
                               double bGuess             = 0.17,
                               double cGuess             = 0.54,
                               double dGuess             = 0.17,
                               bool aIsFixed             = false,
                               bool bIsFixed             = false,
                               bool cIsFixed             = false,
                               bool dIsFixed             = false,
                               bool vegaWeighted         = false,
                               EndCriteria endCriteria   = null,
                               OptimizationMethod method = null)
        {
            aIsFixed_        = aIsFixed;
            bIsFixed_        = bIsFixed;
            cIsFixed_        = cIsFixed;
            dIsFixed_        = dIsFixed;
            a_               = aGuess;
            b_               = bGuess;
            c_               = cGuess;
            d_               = dGuess;
            abcdEndCriteria_ = QLNet.EndCriteria.Type.None;
            endCriteria_     = endCriteria;
            optMethod_       = method;
            weights_         = new InitializedList <double>(blackVols.Count, 1.0 / blackVols.Count);
            vegaWeighted_    = vegaWeighted;
            times_           = t;
            blackVols_       = blackVols;


            AbcdMathFunction.validate(aGuess, bGuess, cGuess, dGuess);

            Utils.QL_REQUIRE(blackVols.Count == t.Count, () =>
                             "mismatch between number of times (" + t.Count + ") and blackVols (" + blackVols.Count + ")");

            // if no optimization method or endCriteria is provided, we provide one
            if (optMethod_ == null)
            {
                double epsfcn = 1.0e-8;
                double xtol   = 1.0e-8;
                double gtol   = 1.0e-8;
                bool   useCostFunctionsJacobian = false;
                optMethod_ = new LevenbergMarquardt(epsfcn, xtol, gtol, useCostFunctionsJacobian);
            }

            if (endCriteria_ == null)
            {
                int    maxIterations = 10000;
                int    maxStationaryStateIterations = 1000;
                double rootEpsilon         = 1.0e-8;
                double functionEpsilon     = 0.3e-4; // Why 0.3e-4 ?
                double gradientNormEpsilon = 0.3e-4; // Why 0.3e-4 ?
                endCriteria_ = new EndCriteria(maxIterations, maxStationaryStateIterations, rootEpsilon, functionEpsilon,
                                               gradientNormEpsilon);
            }
        }
Пример #3
0
 public void nestedOptimizationTest()
 {
     //("Testing nested optimizations...");
     OptimizationBasedCostFunction optimizationBasedCostFunction = new OptimizationBasedCostFunction();
     NoConstraint constraint = new NoConstraint();
     Vector initialValues = new Vector(1, 0.0);
     Problem problem = new Problem(optimizationBasedCostFunction, constraint, initialValues);
     LevenbergMarquardt optimizationMethod = new LevenbergMarquardt();
     //Simplex optimizationMethod(0.1);
     //ConjugateGradient optimizationMethod;
     //SteepestDescent optimizationMethod;
     EndCriteria endCriteria = new EndCriteria(1000, 100, 1e-5, 1e-5, 1e-5);
     optimizationMethod.minimize(problem, endCriteria);
 }
        static void CalibrateModel(ShortRateModel model,
                            List<CalibrationHelper> helpers)
        {
            if (model == null) throw new ArgumentNullException("model");
            var om = new LevenbergMarquardt();
            model.calibrate(helpers, om,
                             new EndCriteria(400, 100, 1.0e-8, 1.0e-8, 1.0e-8), new Constraint(),
                                    new List<double>());

            // Output the implied Black volatilities
            for (int i = 0; i < NumRows; i++)
            {
                int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int k = i * NumCols + j;
                double npv = helpers[i].modelValue();
                double implied = helpers[i].impliedVolatility(npv, 1e-4,
                                                                   1000, 0.05, 0.50);
                double diff = implied - SwaptionVols[k];
                Console.WriteLine("{0}x{1}: model {2:0.00000 %}, market {3:0.00000 %}, diff {4:0.00000 %} ",
                                    i + 1, SwapLenghts[j], implied, SwaptionVols[k], diff);
            }
        }
Пример #5
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 );
             }
        }
Пример #6
0
        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);
        }
Пример #7
0
 public override Vector values(Vector x)
 {
     // dummy nested optimization
     Vector coefficients = new Vector(3, 1.0);
     OneDimensionalPolynomialDegreeN oneDimensionalPolynomialDegreeN = new OneDimensionalPolynomialDegreeN(coefficients);
     NoConstraint constraint = new NoConstraint();
     Vector initialValues = new Vector(1, 100.0);
     Problem problem = new Problem(oneDimensionalPolynomialDegreeN, constraint, initialValues);
     LevenbergMarquardt optimizationMethod = new LevenbergMarquardt();
     //Simplex optimizationMethod(0.1);
     //ConjugateGradient optimizationMethod;
     //SteepestDescent optimizationMethod;
     EndCriteria endCriteria = new EndCriteria(1000, 100, 1e-5, 1e-5, 1e-5);
     optimizationMethod.minimize(problem, endCriteria);
     // return dummy result
     Vector dummy = new Vector(1,0);
     return dummy;
 }
Пример #8
0
        public void calculate()
        {
            validCurve_ = false;
            int nInsts = ts_.instruments_.Count, i;

            // ensure rate helpers are sorted
            ts_.instruments_.Sort((x, y) => x.latestDate().CompareTo(y.latestDate()));

            // check that there is no instruments with the same maturity
            for (i = 1; i < nInsts; ++i)
            {
                Date m1 = ts_.instruments_[i - 1].latestDate(),
                     m2 = ts_.instruments_[i].latestDate();
                if (m1 == m2)
                {
                    throw new ArgumentException("two instruments have the same maturity (" + m1 + ")");
                }
            }

            // check that there is no instruments with invalid quote
            if ((i = ts_.instruments_.FindIndex(x => !x.quoteIsValid())) != -1)
            {
                throw new ArgumentException("instrument " + i + " (maturity: " + ts_.instruments_[i].latestDate() +
                                            ") has an invalid quote");
            }

            // setup instruments and register with them
            ts_.instruments_.ForEach((x, j) => ts_.setTermStructure(j));

            // set initial guess only if the current curve cannot be used as guess
            if (validCurve_)
            {
                if (ts_.data_.Count != nInsts + 1)
                {
                    throw new ArgumentException("dimension mismatch: expected " + nInsts + 1 + ", actual " + ts_.data_.Count);
                }
            }
            else
            {
                ts_.data_    = new InitializedList <double>(nInsts + 1);
                ts_.data_[0] = ts_.initialValue();
            }

            // calculate dates and times
            ts_.dates_    = new InitializedList <Date>(nInsts + 1);
            ts_.times_    = new InitializedList <double>(nInsts + 1);
            ts_.dates_[0] = ts_.initialDate();
            ts_.times_[0] = ts_.timeFromReference(ts_.dates_[0]);
            for (i = 0; i < nInsts; ++i)
            {
                ts_.dates_[i + 1] = ts_.instruments_[i].latestDate();
                ts_.times_[i + 1] = ts_.timeFromReference(ts_.dates_[i + 1]);
                if (!validCurve_)
                {
                    ts_.data_[i + 1] = ts_.data_[i];
                }
            }

            LevenbergMarquardt solver           = new LevenbergMarquardt(ts_.accuracy_, ts_.accuracy_, ts_.accuracy_);
            EndCriteria        endCriteria      = new EndCriteria(100, 10, 0.00, ts_.accuracy_, 0.00);
            PositiveConstraint posConstraint    = new PositiveConstraint();
            NoConstraint       noConstraint     = new NoConstraint();
            Constraint         solverConstraint = forcePositive_ ? (Constraint)posConstraint : (Constraint)noConstraint;

            // now start the bootstrapping.
            int iInst = localisation_ - 1;

            int dataAdjust = (ts_.interpolator_ as ConvexMonotone).dataSizeAdjustment;

            do
            {
                int    initialDataPt = iInst + 1 - localisation_ + dataAdjust;
                Vector startArray    = new Vector(localisation_ + 1 - dataAdjust);
                for (int j = 0; j < startArray.size() - 1; ++j)
                {
                    startArray[j] = ts_.data_[initialDataPt + j];
                }

                // here we are extending the interpolation a point at a
                // time... but the local interpolator can make an
                // approximation for the final localisation period.
                // e.g. if the localisation is 2, then the first section
                // of the curve will be solved using the first 2
                // instruments... with the local interpolator making
                // suitable boundary conditions.
                ts_.interpolation_ = (ts_.interpolator_ as ConvexMonotone).localInterpolate(ts_.times_, iInst + 2, ts_.data_,
                                                                                            localisation_, ts_.interpolation_ as ConvexMonotoneInterpolation, nInsts + 1);

                if (iInst >= localisation_)
                {
                    startArray[localisation_ - dataAdjust] = ts_.guess(iInst, ts_, false, 0);
                }
                else
                {
                    startArray[localisation_ - dataAdjust] = ts_.data_[0];
                }

                var currentCost = new PenaltyFunction <T, U>(ts_, initialDataPt, ts_.instruments_,
                                                             iInst - localisation_ + 1, iInst + 1);
                Problem          toSolve = new Problem(currentCost, solverConstraint, startArray);
                EndCriteria.Type endType = solver.minimize(toSolve, endCriteria);

                // check the end criteria
                if (!(endType == EndCriteria.Type.StationaryFunctionAccuracy ||
                      endType == EndCriteria.Type.StationaryFunctionValue))
                {
                    throw new Exception("Unable to strip yieldcurve to required accuracy ");
                }
                ++iInst;
            } while (iInst < nInsts);

            validCurve_ = true;
        }