void FittedBondDiscountCurve::FittingMethod::calculate() { FittingCost& costFunction = *costFunction_; Constraint constraint = NoConstraint(); // start with the guess solution, if it exists Array x(size(), 0.0); if (!curve_->guessSolution_.empty()) { x = curve_->guessSolution_; } Simplex simplex(curve_->simplexLambda_); Problem problem(costFunction, constraint, x); Natural maxStationaryStateIterations = 100; Real rootEpsilon = curve_->accuracy_; Real functionEpsilon = curve_->accuracy_; Real gradientNormEpsilon = curve_->accuracy_; EndCriteria endCriteria(curve_->maxEvaluations_, maxStationaryStateIterations, rootEpsilon, functionEpsilon, gradientNormEpsilon); simplex.minimize(problem,endCriteria); solution_ = problem.currentValue(); numberOfIterations_ = problem.functionEvaluation(); costValue_ = problem.functionValue(); // save the results as the guess solution, in case of recalculation curve_->guessSolution_ = solution_; }
HullWhiteTimeDependentParameters calibration_hull_white( const Date& evalDate, const CapVolData& volData ) { boost::shared_ptr<IborIndex> index = volData.index; Frequency fixedFreq = volData.fixedFreq; DayCounter fixedDC = volData.fixedDC; Real FixedA = volData.fixedA; std::vector<Real> initialSigma = volData.initialSigma; Settings::instance().evaluationDate() = Date( evalDate.serialNumber() ); Date today = Settings::instance().evaluationDate(); std::vector<Date> dates; for (Size i=0; i<volData.tenors.size(); ++i){ dates.push_back(today+volData.tenors[i]*Years); } dates.back() = today+50*Years; std::set<Date> temp(dates.begin(), dates.end()); dates = std::vector<Date>(temp.begin(), temp.end()); Handle<YieldTermStructure> rts_hw(index->forwardingTermStructure().currentLink()); boost::shared_ptr<Generalized_HullWhite> model(new Generalized_HullWhite(rts_hw, dates, initialSigma, FixedA)); boost::shared_ptr<PricingEngine> engine_hw(new AnalyticCapFloorEngine(model)); //boost::shared_ptr<PricingEngine> engine_hw(new TreeCapFloorEngine(model, 80)); std::vector<boost::shared_ptr<CalibrationHelper> > caps; for (Size i=0; i<volData.tenors.size(); ++i) { boost::shared_ptr<CalibrationHelper> helper( new CapHelper(Period(volData.tenors[i], Years), Handle<Quote>(boost::shared_ptr<Quote>(new SimpleQuote(volData.vols[i]))), index, fixedFreq, fixedDC, false, rts_hw, CalibrationHelper::PriceError)); helper->setPricingEngine(engine_hw); caps.push_back(helper); } LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8); EndCriteria endCriteria(5000, 1000, 1e-8, 1e-8, 1e-8); Constraint c = BoundaryConstraint(0.01, 3.0); model->calibrate(caps, optimizationMethod, endCriteria, c); EndCriteria::Type ecType = model->endCriteria(); Array xMinCalculated = model->params(); //Real a = xMinCalculated[0]; //Real sigmar = xMinCalculated[1]; std::vector<Real> sigma; for (Size i=0; i<xMinCalculated.size(); ++i) { sigma.push_back(xMinCalculated[i]); } return HullWhiteTimeDependentParameters(FixedA, dates, sigma, model, caps); }
void FluctuatingChargePropagator::initialize() { if (info_->usesFluctuatingCharges()) { if (info_->getNFluctuatingCharges() > 0) { hasFlucQ_ = true; fqConstraints_ = new FluctuatingChargeConstraints(info_); fqConstraints_->setConstrainRegions(fqParams_->getConstrainRegions()); } } if (!hasFlucQ_) { initialized_ = true; return; } // SimInfo::MoleculeIterator i; // Molecule::FluctuatingChargeIterator j; // Molecule* mol; // Atom* atom; // // For single-minima flucq, this ensures a net neutral system, but // for multiple minima, this is no longer the right thing to do: // // for (mol = info_->beginMolecule(i); mol != NULL; // mol = info_->nextMolecule(i)) { // for (atom = mol->beginFluctuatingCharge(j); atom != NULL; // atom = mol->nextFluctuatingCharge(j)) { // atom->setFlucQPos(0.0); // atom->setFlucQVel(0.0); // } // } FluctuatingChargeObjectiveFunction flucQobjf(info_, forceMan_, fqConstraints_); DynamicVector<RealType> initCoords = flucQobjf.setInitialCoords(); Problem problem(flucQobjf, *(new NoConstraint()), *(new NoStatus()), initCoords); EndCriteria endCriteria(1000, 100, 1e-5, 1e-5, 1e-5); OptimizationMethod* minim = OptimizationFactory::getInstance()->createOptimization("SD", info_); DumpStatusFunction dsf(info_); // we want a dump file written // every iteration minim->minimize(problem, endCriteria); cerr << "back from minim\n"; initialized_ = true; }
void FittedBondDiscountCurve::FittingMethod::calculate() { FittingCost& costFunction = *costFunction_; Constraint constraint = NoConstraint(); // start with the guess solution, if it exists Array x(size(), 0.0); if (!curve_->guessSolution_.empty()) { x = curve_->guessSolution_; } if(curve_->maxEvaluations_ == 0) { //Don't calculate, simply use given parameters to provide a fitted curve. //This turns the fittedbonddiscountcurve into an evaluator of the parametric //curve, for example allowing to use the parameters for a credit spread curve //calculated with bonds in one currency to be coupled to a discount curve in //another currency. return; } //workaround for backwards compatibility ext::shared_ptr<OptimizationMethod> optimization = optimizationMethod_; if(!optimization){ optimization = ext::make_shared<Simplex>(curve_->simplexLambda_); } Problem problem(costFunction, constraint, x); Real rootEpsilon = curve_->accuracy_; Real functionEpsilon = curve_->accuracy_; Real gradientNormEpsilon = curve_->accuracy_; EndCriteria endCriteria(curve_->maxEvaluations_, curve_->maxStationaryStateIterations_, rootEpsilon, functionEpsilon, gradientNormEpsilon); optimization->minimize(problem,endCriteria); solution_ = problem.currentValue(); numberOfIterations_ = problem.functionEvaluation(); costValue_ = problem.functionValue(); // save the results as the guess solution, in case of recalculation curve_->guessSolution_ = solution_; }
// [[Rcpp::export]] Rcpp::List calibrateHullWhiteUsingSwapsEngine(SEXP termStrcDateVec, SEXP termStrcZeroVec, SEXP swapDataDF, SEXP iborDateVec, SEXP iborZeroVec, std::string iborType, QuantLib::Date evalDate) { QuantLib::Settings::instance().evaluationDate() = evalDate; //set up the HullWhite model QuantLib::Handle<QuantLib::YieldTermStructure> term(rebuildCurveFromZeroRates(termStrcDateVec, termStrcZeroVec)); boost::shared_ptr<QuantLib::HullWhite> model(new QuantLib::HullWhite(term)); //set up ibor index QuantLib::Handle<QuantLib::YieldTermStructure> indexStrc(rebuildCurveFromZeroRates(iborDateVec, iborZeroVec)); boost::shared_ptr<QuantLib::IborIndex> index = buildIborIndex(iborType, indexStrc); //process capDataDF boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::JamshidianSwaptionEngine(model)); std::vector<boost::shared_ptr <QuantLib::CalibrationHelper> > swaps; Rcpp::DataFrame swapDF(swapDataDF); Rcpp::NumericVector i0v = swapDF[0]; Rcpp::CharacterVector s1v = swapDF[1]; Rcpp::NumericVector i2v = swapDF[2]; Rcpp::CharacterVector s3v = swapDF[3]; Rcpp::NumericVector d4v = swapDF[4]; Rcpp::NumericVector i5v = swapDF[5]; Rcpp::CharacterVector s6v = swapDF[6]; Rcpp::NumericVector i7v = swapDF[7]; Rcpp::NumericVector i8v = swapDF[8]; //std::vector<std::vector<ColDatum> > table = swapDF.getTableData(); //int nrow = table.size(); int nrow = i0v.size(); for (int row=0; row<nrow;row++) { QuantLib::Period maturity = periodByTimeUnit(i0v[row], Rcpp::as<std::string>(s1v[row])); QuantLib::Period length = periodByTimeUnit(i0v[row], Rcpp::as<std::string>(s3v[row])); boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(d4v[row])); QuantLib::Period fixedLegTenor = periodByTimeUnit(i5v[row], Rcpp::as<std::string>(s6v[row])); QuantLib::DayCounter fixedLegDayCounter = getDayCounter(i7v[row]); QuantLib::DayCounter floatingLegDayCounter = getDayCounter(i8v[row]); boost::shared_ptr<QuantLib::CalibrationHelper> helper(new QuantLib::SwaptionHelper(maturity, length, QuantLib::Handle<QuantLib::Quote>(vol), index, fixedLegTenor, fixedLegDayCounter, floatingLegDayCounter, term)); helper->setPricingEngine(engine); swaps.push_back(helper); } //calibrate the data QuantLib::LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8); QuantLib::EndCriteria endCriteria(10000, 100, 1e-6, 1e-8, 1e-8); model->calibrate(swaps, optimizationMethod, endCriteria); //EndCriteria::Type ecType = model->endCriteria(); //return the result QuantLib::Array xMinCalculated = model->params(); return Rcpp::List::create(Rcpp::Named("alpha") = xMinCalculated[0], Rcpp::Named("sigma") = xMinCalculated[1]); }
// [[Rcpp::export]] Rcpp::List calibrateHullWhiteUsingCapsEngine(SEXP termStrcDateVec, SEXP termStrcZeroVec, SEXP capDataDF, SEXP iborDateVec, SEXP iborZeroVec, std::string iborType, QuantLib::Date evalDate) { QuantLib::Settings::instance().evaluationDate() = evalDate; QuantLib::Handle<QuantLib::YieldTermStructure> term(rebuildCurveFromZeroRates(termStrcDateVec, termStrcZeroVec)); //set up ibor index QuantLib::Handle<QuantLib::YieldTermStructure> indexStrc(rebuildCurveFromZeroRates(iborDateVec, iborZeroVec)); boost::shared_ptr<QuantLib::IborIndex> index = buildIborIndex(iborType, indexStrc); //process capDataDF std::vector<boost::shared_ptr <QuantLib::CalibrationHelper> > caps; Rcpp::DataFrame capDF(capDataDF); Rcpp::NumericVector i0v = capDF[0]; Rcpp::CharacterVector s1v = capDF[1]; Rcpp::NumericVector d2v = capDF[2]; Rcpp::NumericVector i3v = capDF[3]; Rcpp::NumericVector i4v = capDF[4]; Rcpp::NumericVector i5v = capDF[5]; //std::vector<std::vector<ColDatum> > table = capDF.getTableData(); //int nrow = table.size(); int nrow = i0v.size(); for (int row=0; row<nrow;row++) { QuantLib::Period p = periodByTimeUnit(i0v[row], Rcpp::as<std::string>(s1v[row])); boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(d2v[row])); QuantLib::DayCounter dc = getDayCounter(i4v[row]); boost::shared_ptr<QuantLib::CalibrationHelper> helper(new QuantLib::CapHelper(p, QuantLib::Handle<QuantLib::Quote>(vol), index, getFrequency(i3v[row]), dc, (i5v[row]==1) ? true : false, term)); boost::shared_ptr<QuantLib::BlackCapFloorEngine> engine(new QuantLib::BlackCapFloorEngine(term, d2v[row])); helper->setPricingEngine(engine); caps.push_back(helper); } //set up the HullWhite model boost::shared_ptr<QuantLib::HullWhite> model(new QuantLib::HullWhite(term)); //calibrate the data QuantLib::LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8); QuantLib::EndCriteria endCriteria(10000, 100, 1e-6, 1e-8, 1e-8); model->calibrate(caps, optimizationMethod, endCriteria); //EndCriteria::Type ecType = model->endCriteria(); //return the result QuantLib::Array xMinCalculated = model->params(); return Rcpp::List::create(Rcpp::Named("alpha") = xMinCalculated[0], Rcpp::Named("sigma") = xMinCalculated[1]); }
HullWhiteTimeDependentParameters calibration_hull_white( const Date& evalDate, const SwaptionVolData& volData ) { boost::shared_ptr<IborIndex> index = volData.index; Frequency fixedFreq = volData.fixedFreq; DayCounter fixedDC = volData.fixedDC; DayCounter floatingDC = volData.floatingDC; Real FixedA = volData.fixedA; std::vector<Real> initialSigma = volData.initialSigma; Settings::instance().evaluationDate() = Date( evalDate.serialNumber() ); Date today = Settings::instance().evaluationDate(); std::vector<Date> tmpdates; for (Size i=0; i<volData.maturities.size(); ++i){ tmpdates.push_back(today+volData.maturities[i]); } tmpdates.back() = today+50*Years; std::set<Date> dateSet( tmpdates.begin(), tmpdates.end() ); std::vector<Date> dates( dateSet.begin(), dateSet.end() ); Handle<YieldTermStructure> rts_hw(index->forwardingTermStructure().currentLink()); //boost::shared_ptr<GeneralizedHullWhite> model(new GeneralizedHullWhite(rts_hw, dates, dates, std::vector<Real>(1, FixedA), initialSigma)); boost::shared_ptr<Generalized_HullWhite> model(new Generalized_HullWhite(rts_hw, dates, initialSigma, FixedA)); //boost::shared_ptr<PricingEngine> engine_hw(new AnalyticCapFloorEngine(model)); //boost::shared_ptr<PricingEngine> engine_hw(new TreeSwaptionEngine(model, 100)); boost::shared_ptr<PricingEngine> engine_hw(new JamshidianSwaptionEngine(model)); std::vector<boost::shared_ptr<CalibrationHelper> > swaptions; for (Size i=0; i<volData.maturities.size(); ++i) { boost::shared_ptr<CalibrationHelper> helper( new SwaptionHelper(volData.maturities[i], volData.lengths[i], Handle<Quote>(boost::shared_ptr<Quote>(new SimpleQuote(volData.vols[i]))), index, Period(fixedFreq), fixedDC, floatingDC, rts_hw, CalibrationHelper::PriceError)); helper->setPricingEngine(engine_hw); swaptions.push_back(helper); } LevenbergMarquardt optimizationMethod(1.0e-8,1.0e-8,1.0e-8); EndCriteria endCriteria(50000, 1000, 1e-8, 1e-8, 1e-8); model->calibrate(swaptions, optimizationMethod, endCriteria); EndCriteria::Type ecType = model->endCriteria(); Array xMinCalculated = model->params(); //Real a = xMinCalculated[0]; //Real sigmar = xMinCalculated[1]; std::vector<Real> sigma; for (Size i=0; i<xMinCalculated.size(); ++i) { sigma.push_back(xMinCalculated[i]); } return HullWhiteTimeDependentParameters(FixedA, dates, sigma, model, swaptions); }
SwaptionVolCube1::Cube SwaptionVolCube1::sabrCalibration(const Cube& marketVolCube) const { const std::vector<Time>& optionTimes = marketVolCube.optionTimes(); const std::vector<Time>& swapLengths = marketVolCube.swapLengths(); const std::vector<Date>& optionDates = marketVolCube.optionDates(); const std::vector<Period>& swapTenors = marketVolCube.swapTenors(); Matrix alphas(optionTimes.size(), swapLengths.size(),0.); Matrix betas(alphas); Matrix nus(alphas); Matrix rhos(alphas); Matrix forwards(alphas); Matrix errors(alphas); Matrix maxErrors(alphas); Matrix endCriteria(alphas); const std::vector<Matrix>& tmpMarketVolCube = marketVolCube.points(); std::vector<Real> strikes(strikeSpreads_.size()); std::vector<Real> volatilities(strikeSpreads_.size()); for (Size j=0; j<optionTimes.size(); j++) { for (Size k=0; k<swapLengths.size(); k++) { Rate atmForward = atmStrike(optionDates[j], swapTenors[k]); strikes.clear(); volatilities.clear(); for (Size i=0; i<nStrikes_; i++){ Real strike = atmForward+strikeSpreads_[i]; if(strike>=MINSTRIKE) { strikes.push_back(strike); volatilities.push_back(tmpMarketVolCube[i][j][k]); } } const std::vector<Real>& guess = parametersGuess_.operator()( optionTimes[j], swapLengths[k]); const boost::shared_ptr<SABRInterpolation> sabrInterpolation = boost::shared_ptr<SABRInterpolation>(new SABRInterpolation(strikes.begin(), strikes.end(), volatilities.begin(), optionTimes[j], atmForward, guess[0], guess[1], guess[2], guess[3], isParameterFixed_[0], isParameterFixed_[1], isParameterFixed_[2], isParameterFixed_[3], vegaWeightedSmileFit_, endCriteria_, optMethod_, errorAccept_, useMaxError_, maxGuesses_)); sabrInterpolation->update(); Real rmsError = sabrInterpolation->rmsError(); Real maxError = sabrInterpolation->maxError(); alphas [j][k] = sabrInterpolation->alpha(); betas [j][k] = sabrInterpolation->beta(); nus [j][k] = sabrInterpolation->nu(); rhos [j][k] = sabrInterpolation->rho(); forwards [j][k] = atmForward; errors [j][k] = rmsError; maxErrors [j][k] = maxError; endCriteria[j][k] = sabrInterpolation->endCriteria(); QL_ENSURE(endCriteria[j][k]!=EndCriteria::MaxIterations, "global swaptions calibration failed: " "MaxIterations reached: " << "\n" << "option maturity = " << optionDates[j] << ", \n" << "swap tenor = " << swapTenors[k] << ", \n" << "error = " << io::rate(errors[j][k]) << ", \n" << "max error = " << io::rate(maxErrors[j][k]) << ", \n" << " alpha = " << alphas[j][k] << "n" << " beta = " << betas[j][k] << "\n" << " nu = " << nus[j][k] << "\n" << " rho = " << rhos[j][k] << "\n" ); QL_ENSURE(useMaxError_ ? maxError : rmsError < maxErrorTolerance_, "global swaptions calibration failed: " "option tenor " << optionDates[j] << ", swap tenor " << swapTenors[k] << (useMaxError_ ? ": max error " : ": error") << (useMaxError_ ? maxError : rmsError) << " alpha = " << alphas[j][k] << "n" << " beta = " << betas[j][k] << "\n" << " nu = " << nus[j][k] << "\n" << " rho = " << rhos[j][k] << "\n" << (useMaxError_ ? ": error" : ": max error ") << (useMaxError_ ? rmsError :maxError) ); } } Cube sabrParametersCube(optionDates, swapTenors, optionTimes, swapLengths, 8); sabrParametersCube.setLayer(0, alphas); sabrParametersCube.setLayer(1, betas); sabrParametersCube.setLayer(2, nus); sabrParametersCube.setLayer(3, rhos); sabrParametersCube.setLayer(4, forwards); sabrParametersCube.setLayer(5, errors); sabrParametersCube.setLayer(6, maxErrors); sabrParametersCube.setLayer(7, endCriteria); return sabrParametersCube; }
void LocalBootstrap<Curve>::calculate() const { validCurve_ = false; Size nInsts = ts_->instruments_.size(); // ensure rate helpers are sorted std::sort(ts_->instruments_.begin(), ts_->instruments_.end(), detail::BootstrapHelperSorter()); // check that there is no instruments with the same maturity for (Size i=1; i<nInsts; ++i) { Date m1 = ts_->instruments_[i-1]->latestDate(), m2 = ts_->instruments_[i]->latestDate(); QL_REQUIRE(m1 != m2, "two instruments have the same maturity ("<< m1 <<")"); } // check that there is no instruments with invalid quote for (Size i=0; i<nInsts; ++i) QL_REQUIRE(ts_->instruments_[i]->quote()->isValid(), io::ordinal(i+1) << " instrument (maturity: " << ts_->instruments_[i]->latestDate() << ") has an invalid quote"); // setup instruments for (Size i=0; i<nInsts; ++i) { // don't try this at home! // This call creates instruments, and removes "const". // There is a significant interaction with observability. ts_->instruments_[i]->setTermStructure(const_cast<Curve*>(ts_)); } // set initial guess only if the current curve cannot be used as guess if (validCurve_) QL_ENSURE(ts_->data_.size() == nInsts+1, "dimension mismatch: expected " << nInsts+1 << ", actual " << ts_->data_.size()); else { ts_->data_ = std::vector<Rate>(nInsts+1); ts_->data_[0] = Traits::initialValue(ts_); } // calculate dates and times ts_->dates_ = std::vector<Date>(nInsts+1); ts_->times_ = std::vector<Time>(nInsts+1); ts_->dates_[0] = Traits::initialDate(ts_); ts_->times_[0] = ts_->timeFromReference(ts_->dates_[0]); for (Size 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(ts_->accuracy_, ts_->accuracy_, ts_->accuracy_); EndCriteria endCriteria(100, 10, 0.00, ts_->accuracy_, 0.00); PositiveConstraint posConstraint; NoConstraint noConstraint; Constraint& solverConstraint = forcePositive_ ? static_cast<Constraint&>(posConstraint) : static_cast<Constraint&>(noConstraint); // now start the bootstrapping. Size iInst = localisation_-1; Size dataAdjust = Curve::interpolator_type::dataSizeAdjustment; do { Size initialDataPt = iInst+1-localisation_+dataAdjust; Array startArray(localisation_+1-dataAdjust); for (Size 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_.localInterpolate( ts_->times_.begin(), ts_->times_.begin()+(iInst + 2), ts_->data_.begin(), localisation_, ts_->interpolation_, nInsts+1); if (iInst >= localisation_) { startArray[localisation_-dataAdjust] = Traits::guess(iInst, ts_, false, 0); // ? } else { startArray[localisation_-dataAdjust] = ts_->data_[0]; } PenaltyFunction<Curve> currentCost( ts_, initialDataPt, ts_->instruments_.begin() + (iInst - localisation_+1), ts_->instruments_.begin() + (iInst+1)); Problem toSolve(currentCost, solverConstraint, startArray); EndCriteria::Type endType = solver.minimize(toSolve, endCriteria); // check the end criteria QL_REQUIRE(endType == EndCriteria::StationaryFunctionAccuracy || endType == EndCriteria::StationaryFunctionValue, "Unable to strip yieldcurve to required accuracy " ); ++iInst; } while ( iInst < nInsts ); validCurve_ = true; }