cmsmarket.cpp
来自「有很多的函数库」· C++ 代码 · 共 459 行 · 第 1/2 页
CPP
459 行
Real CmsMarket::weightedError(const Matrix& weights){
priceSpotFromForwardStartingCms();
return weightedMean(spreadErrors_,weights);
}
Real CmsMarket::weightedPriceError(const Matrix& weights){
priceSpotFromForwardStartingCms();
return weightedMean(priceErrors_,weights);
}
Real CmsMarket::weightedForwardPriceError(const Matrix& weights){
return weightedMean(forwardPriceErrors_,weights);
}
// return an array of errors to be used for Levenberg-Marquardt optimization.
Disposable<Array> CmsMarket::weightedErrors(const Matrix& weights){
priceSpotFromForwardStartingCms();
return weightedMeans(spreadErrors_,weights);
}
Disposable<Array> CmsMarket::weightedPriceErrors(const Matrix& weights){
priceSpotFromForwardStartingCms();
return weightedMeans(priceErrors_,weights);
}
Disposable<Array> CmsMarket::weightedForwardPriceErrors(
const Matrix& weights){
return weightedMeans(forwardPriceErrors_,weights);
}
Real CmsMarket::weightedMean(const Matrix& var, const Matrix& weights){
Real mean=0.;
for(Size i=0;i<nExercise_;i++){
for(Size j=0;j<nSwapTenors_;j++){
mean += weights[i][j]*var[i][j]*var[i][j];
}
}
mean=std::sqrt(mean/(nExercise_*nSwapTenors_));
return mean;
}
Disposable<Array> CmsMarket::weightedMeans(const Matrix& var,
const Matrix& weights){
Array weightedVars(nExercise_*nSwapTenors_);
for(Size i=0; i<nExercise_; i++) {
for(Size j=0; j<nSwapTenors_; j++) {
weightedVars[i*nSwapTenors_+j] = std::sqrt(weights[i][j])*var[i][j];
}
}
return weightedVars;
}
Matrix CmsMarket::browse() const{
calculate();
Matrix result(nExercise_*nSwapTenors_,19,0.);
for(Size j=0;j<nSwapTenors_;j++){
for(Size i=0;i<nExercise_;i++){
result[j*nSwapTenors_+i][0]= swapTenors_[j].length();
result[j*nSwapTenors_+i][1]= expiries_[i].length();
// Spreads
result[j*nSwapTenors_+i][2]= bids_[i][j]*10000;
result[j*nSwapTenors_+i][3]= asks_[i][j]*10000;
result[j*nSwapTenors_+i][4]= mids_[i][j]*10000;
result[j*nSwapTenors_+i][5]= modelCmsSpreads_[i][j]*10000;
result[j*nSwapTenors_+i][6]= spreadErrors_[i][j]*10000;
if(modelCmsSpreads_[i][j]>asks_[i][j]){
result[j*nSwapTenors_+i][7]= (modelCmsSpreads_[i][j]-asks_[i][j])*10000;
}
else if(modelCmsSpreads_[i][j]<bids_[i][j]){
result[j*nSwapTenors_+i][7]= (bids_[i][j]-modelCmsSpreads_[i][j])*10000;
}
else{ result[j*nSwapTenors_+i][7]= 0.; }
// Prices of cms
result[j*nSwapTenors_+i][8]= marketBidCmsLegValues_[i][j];
result[j*nSwapTenors_+i][9]= marketAskCmsLegValues_[i][j];
result[j*nSwapTenors_+i][10]= marketMidCmsLegValues_[i][j];
result[j*nSwapTenors_+i][11]= modelCmsLegValues_[i][j];
result[j*nSwapTenors_+i][12]= priceErrors_[i][j];
// Prices of forward cms
result[j*nSwapTenors_+i][13]= marketBidForwardCmsLegValues_[i][j];
result[j*nSwapTenors_+i][14]= marketAskForwardCmsLegValues_[i][j];
result[j*nSwapTenors_+i][15]= marketMidForwardCmsLegValues_[i][j];
result[j*nSwapTenors_+i][16]= modelForwardCmsLegValues_[i][j];
result[j*nSwapTenors_+i][17]= forwardPriceErrors_[i][j];
// mean reversions
result[j*nSwapTenors_+i][18]= meanReversions_[i][j];
}
}
return result;
}
//===========================================================================//
// CmsMarketCalibration //
//===========================================================================//
CmsMarketCalibration::CmsMarketCalibration(
Handle<SwaptionVolatilityStructure>& volCube,
boost::shared_ptr<CmsMarket>& cmsMarket,
const Matrix& weights,
CalibrationType calibrationType):
volCube_(volCube),
cmsMarket_(cmsMarket),
weights_(weights),
calibrationType_(calibrationType){
}
Array CmsMarketCalibration::compute(
const boost::shared_ptr<EndCriteria>& endCriteria,
const boost::shared_ptr<OptimizationMethod>& method,
const Array& guess,
bool isMeanReversionFixed){
Array result;
if(isMeanReversionFixed){
Size nBeta = guess.size()-1;
ParametersConstraintWithFixedMeanReversion constraint(nBeta);
Real fixedMeanReversion = guess[nBeta];
Array betasGuess(nBeta);
for(Size i=0;i<nBeta;i++)
betasGuess[i] = guess[i];
ObjectiveFunctionWithFixedMeanReversion costFunction(this, fixedMeanReversion);
Problem problem(costFunction, constraint,betasGuess);
endCriteria_ = method->minimize(problem, *endCriteria);
result = problem.currentValue();
error_ = costFunction.value(result);
}
else {
ParametersConstraint constraint(guess.size()-1);
ObjectiveFunction costFunction(this);
Problem problem(costFunction, constraint,guess);
endCriteria_ = method->minimize(problem, *endCriteria);
result = problem.currentValue();
error_ = costFunction.value(result);
}
const boost::shared_ptr<SwaptionVolCube1> volCubeBySabr =
boost::dynamic_pointer_cast<SwaptionVolCube1>(volCube_.currentLink());
sparseSabrParameters_ = volCubeBySabr->sparseSabrParameters();
denseSabrParameters_ = volCubeBySabr->denseSabrParameters();
browseCmsMarket_ = cmsMarket_->browse();
return result;
}
//===========================================================================//
// CmsMarketCalibration::ObjectiveFunction //
//===========================================================================//
Real CmsMarketCalibration::ObjectiveFunction::value(const Array& x) const {
updateVolatilityCubeAndCmsMarket(x);
return switchErrorFunctionOnCalibrationType();
}
Disposable<Array> CmsMarketCalibration::ObjectiveFunction::values(const Array& x) const {
updateVolatilityCubeAndCmsMarket(x);
return switchErrorsFunctionOnCalibrationType();
}
void CmsMarketCalibration::ObjectiveFunction::
updateVolatilityCubeAndCmsMarket(const Array& x) const {
const Array y = x;
const std::vector<Period>& swapTenors = cmsMarket_->swapTenors();
Size nSwapTenors = swapTenors.size();
QL_REQUIRE(nSwapTenors+1 == x.size(),"bad calibration guess nSwapTenors+1 != x.size()");
const boost::shared_ptr<SwaptionVolCube1> volCubeBySabr =
boost::dynamic_pointer_cast<SwaptionVolCube1>(volCube_.currentLink());
for (Size i=0; i<nSwapTenors; i++){
Real beta = y[i];
volCubeBySabr->recalibration(beta, swapTenors[i]);
}
Real meanReversion = y[nSwapTenors];
cmsMarket_->reprice(volCube_, meanReversion);
}
Real CmsMarketCalibration::ObjectiveFunction::switchErrorFunctionOnCalibrationType() const {
switch (calibrationType_) {
case OnSpread:
return cmsMarket_->weightedError(weights_);
case OnPrice:
return cmsMarket_->weightedPriceError(weights_);
case OnForwardCmsPrice:
return cmsMarket_->weightedForwardPriceError(weights_);
default:
QL_FAIL("unknown/illegal calibration type");
}
}
Disposable<Array> CmsMarketCalibration::ObjectiveFunction::
switchErrorsFunctionOnCalibrationType() const {
switch (calibrationType_) {
case OnSpread:
return cmsMarket_->weightedErrors(weights_);
case OnPrice:
return cmsMarket_->weightedPriceErrors(weights_);
case OnForwardCmsPrice:
return cmsMarket_->weightedForwardPriceErrors(weights_);
default:
QL_FAIL("unknown/illegal calibration type");
}
}
//===========================================================================//
// CmsMarketCalibration::ObjectiveFunctionWithFixedMeanReversion //
//===========================================================================//
void CmsMarketCalibration::ObjectiveFunctionWithFixedMeanReversion::
updateVolatilityCubeAndCmsMarket(const Array& x) const {
const Array y = x;
const std::vector<Period>& swapTenors = cmsMarket_->swapTenors();
Size nSwapTenors = swapTenors.size();
QL_REQUIRE(nSwapTenors == x.size(),"bad calibration guess nSwapTenors != x.size()");
const boost::shared_ptr<SwaptionVolCube1> volCubeBySabr =
boost::dynamic_pointer_cast<SwaptionVolCube1>(volCube_.currentLink());
for (Size i=0; i<nSwapTenors; i++){
Real beta = y[i];
volCubeBySabr->recalibration(beta, swapTenors[i]);
}
cmsMarket_->reprice(volCube_, fixedMeanReversion_);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?