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; }
// [[Rcpp::export]] SEXP rcpp_bcpM(SEXP pdata, SEXP pid, SEXP pmcmcreturn, SEXP pburnin, SEXP pmcmc, SEXP pa, SEXP pw) { NumericMatrix data(pdata); int mcmcreturn = INTEGER_DATA(pmcmcreturn)[0]; int burnin = INTEGER_DATA(pburnin)[0]; int mcmc = INTEGER_DATA(pmcmc)[0]; // INITIALIZATION OF LOCAL VARIABLES int i, j, m, k; double wstar, xmax; // INITIALIZATION OF OTHER OBJECTS HelperVariables helpers(data, pid); Params params(pw, helpers.cumksize.size(), data.nrow(), pa, false, false, 0, 0, data.ncol()); //params.print(); //helpers.print(); int MM = burnin + mcmc; //helpers.print(); //params.print(); MCMCStepSeq step(helpers, params); int MM2, nn2; if (mcmcreturn == 0) { MM2 = 1; nn2 = 1; } else { nn2 = params.nn; MM2 = MM; } // Things to be returned to R: NumericMatrix pmean(params.nn, params.kk); NumericMatrix ss(params.nn, params.kk); NumericMatrix pvar(params.nn, params.kk); NumericVector pchange(params.nn); NumericVector blocks(burnin + mcmc); NumericMatrix rhos(nn2, MM2); // NumericVector liks(MM2); NumericMatrix results(nn2*MM2,params.kk); double tmpMean; // Rprintf("starting\n"); GetRNGstate(); // Consider Dirk's comment on this. // step.print(); for (i = 0; i < params.nn; i++) { pchange[i] = 0; for (j = 0; j < params.kk; j++) { pmean(i, j) = 0; } } for (m = 0; m < MM; m++) { // Rprintf("Step %d -- ", m); step = pass(step, helpers, params); // Rprintf("blocks:%d, B:%0.2f\n", step.b, step.B); blocks[m] = step.b; if (m >= burnin || mcmcreturn == 1) { // compute posteriors if (step.B == 0) { wstar = params.w[0] * (step.b*params.kk + 1) / (step.b * params.kk +3); } else { xmax = step.B * params.w[0] / step.W / (1 + step.B * params.w[0] / step.W); // Rprintf("xmax:%0.2f\n", xmax); // wstar = log(step.W) - log(step.B) // + Rf_lbeta((double) (step.b* params.kk + 3) / 2, (double) ((params.nn2 - step.b)*params.kk - 4) / 2) // + Rf_pbeta(xmax, (double) (step.b*params.kk + 3) / 2, (double) ((params.nn2 - step.b)*params.kk - 4) / 2, 1, 1) // - Rf_lbeta((double) (step.b*params.kk + 1) / 2, (double) ((params.nn2 - step.b)*params.kk - 2) / 2) // - Rf_pbeta(xmax, (double) (step.b * params.kk+ 1) / 2, (double) ((params.nn2 - step.b)*params.kk - 2) / 2, 1, 1); // wstar = exp(wstar); wstar = (step.W/step.B)* Rf_beta((double) (step.b* params.kk + 3) / 2, (double) ((params.nn2 - step.b)*params.kk - 4) / 2) * Rf_pbeta(xmax, (double) (step.b*params.kk + 3) / 2, (double) ((params.nn2 - step.b)*params.kk - 4) / 2, 1, 0) / Rf_beta((double) (step.b*params.kk + 1) / 2, (double) ((params.nn2 - step.b)*params.kk - 2) / 2) / Rf_pbeta(xmax, (double) (step.b * params.kk+ 1) / 2, (double) ((params.nn2 - step.b)*params.kk - 2) / 2, 1, 0); // Rprintf("wstar:%0.2f\n", wstar); } // for posterior estimate of overall noise variance // if (m >= burnin) // pvar += (step.W + wstar*step.B)/(params.nn2 * params.kk-3); k = 0; for (j = 0; j < params.nn; j++) { // Rprintf("j:%d out of %d (%d, %d) | ", j, params.nn, pchange.size(), step.rho.size()); // Rprintf("pchange[%d]: %0.2f, step.rho:%d\n", j, pchange[j], step.rho[j]); if (m >= burnin) pchange[j] += (double) step.rho[j]; for (i = 0; i < params.kk; i++) { tmpMean = step.bmean[k][i] * (1 - wstar) + helpers.ybar * wstar; // Rprintf("i:%d -- tmpMean:%0.2f, wstar:%0.2f, bmean:%0.2f, ybar:%0.2f\n", // i, tmpMean, wstar, step.bmean[k][i], helpers.ybar); if (m >= burnin) { pmean(j, i) += tmpMean; ss(j, i) += tmpMean * tmpMean; // Rprintf("pmean:%0.2f, ss:%0.2f\n", pmean(j,i), ss(j,i)); } if (mcmcreturn == 1) results(m*params.nn+j, i) = tmpMean; } if (mcmcreturn == 1) rhos(j, m) = step.rho[j]; if (step.rho[j] == 1) k++; } } } // Rprintf("post processing\n"); // step.print(); // post processing for (j = 0; j < params.nn; j++) { pchange[j] /= mcmc; for (i = 0; i < params.kk; i++) { pmean(j, i) /= mcmc; pvar(j, i) = (ss(j, i) / mcmc - pmean(j,i)*pmean(j,i))*(mcmc/(mcmc-1)); } } // Rprintf("ending\n"); PutRNGstate(); List z; z["posterior.mean"] = pmean; z["posterior.var"] = pvar; z["posterior.prob"] = pchange; z["blocks"] = blocks; z["mcmc.rhos"] = rhos; z["mcmc.means"] = results; // z["lik"] = liks; return z; } /* END MAIN */