21#include <boost/math/distributions.hpp>
22#include <boost/math/distributions/non_central_chi_squared.hpp>
23#include <ql/math/interpolations/loginterpolation.hpp>
24#include <ql/termstructures/credit/interpolatedsurvivalprobabilitycurve.hpp>
25#include <ql/time/daycounters/actualactual.hpp>
32Real nccs(
const Real df,
const Real ncp,
const Real x,
const bool cumulative) {
33 QL_REQUIRE(std::isfinite(df) && df > 0,
"CrCirpp::density(): illegal df=" << df);
35 boost::math::non_central_chi_squared_distribution<> d(df, ncp);
36 return cumulative ? cdf(d, x) : pdf(d, x);
43 const QuantLib::ext::shared_ptr<CrCirppParametrization>& parametrization)
44 : parametrization_(parametrization) {
49 QL_REQUIRE(
stateProcess_ != NULL,
"stateProcess has null pointer in CrCirpp ctor!");
61 QL_REQUIRE(!
parametrization_->termStructure().empty(),
"default curve not set");
62 QL_REQUIRE(dateGrid.size() == 0,
"dateGrid without effect for shifted model");
66 Date today = Settings::instance().evaluationDate();
67 std::vector<Real> survivalProbabilities(1, 1.0);
68 std::vector<Date> dates;
69 DayCounter tsDayCounter = Actual365Fixed();
70 if (dateGrid.size() > 0) {
71 QL_REQUIRE(dateGrid.front() == today,
"front date must be today");
74 dates.push_back(today);
76 for (Size i = 1; i <= 12; i++)
77 dates.push_back(today + i * Months);
79 for (Size i = 2; i <= 10; i++)
80 dates.push_back(today + i * Years);
82 for (Size i = 1; i < dates.size(); i++) {
83 Real t = tsDayCounter.yearFraction(today, dates[i]);
86 QuantLib::ext::shared_ptr<DefaultProbabilityTermStructure>
defaultCurve(
89 return Handle<DefaultProbabilityTermStructure>(
defaultCurve);
97 Real sigma2 = sigma * sigma;
98 Real h =
sqrt(kappa * kappa + 2.0 * sigma2);
100 Real nominator = 2.0 * h *
exp((kappa + h) * (T - t) / 2.0);
101 Real denominator = 2.0 * h + (kappa + h) * (
exp((T - t) * h) - 1.0);
102 Real exponent = 2.0 * kappa * theta / sigma2;
104 Real
value = std::pow((nominator / denominator), exponent);
113 Real sigma2 = sigma * sigma;
114 Real h =
sqrt(kappa * kappa + 2.0 * sigma2);
116 Real nominator = 2.0 * (
exp((T - t) * h) - 1.0);
117 Real denominator = 2.0 * h + (kappa + h) * (
exp((T - t) * h) - 1.0);
119 Real
value = nominator / denominator;
129 Probability SP_t =
parametrization_->termStructure()->survivalProbability(t);
131 Probability SP_T =
parametrization_->termStructure()->survivalProbability(T);
137 return A_bar * P_Cir;
148 Real sigma2 = sigma * sigma;
150 Real c = 4 * kappa / (sigma2 * (1 -
exp(-kappa * t)));
152 Real df = 4 * kappa * theta / (sigma2);
154 Real ncp = c * y0 *
exp(-kappa * t);
156 return c * nccs(df, ncp, c * x,
false);
165 Real sigma2 = sigma * sigma;
167 Real c = 4 * kappa / (sigma2 * (1 -
exp(-kappa * t)));
169 Real df = 4 * kappa * theta / (sigma2);
171 Real ncp = c * y0 *
exp(-kappa * t);
173 return c * nccs(df, ncp, c * x,
true);
182 Real sigma2 = sigma * sigma;
184 Real h =
sqrt(kappa * kappa + 2.0 * sigma2);
185 Real rho = 2 * h / (sigma2 * (
exp(h * t) - 1));
187 Real c = 2 * (rho + (kappa + h) / sigma2 + 0.0);
189 Real df = 4 * kappa * theta / (sigma2);
192 Real ncp = 4 * (rho * rho * y0 *
exp(h * t)) / c;
194 return c * nccs(df, ncp, c * x,
false);
204 Real sigma2 = sigma * sigma;
205 Real h =
sqrt(kappa * kappa + 2.0 * sigma2);
206 Real rho = 2 * h / (sigma2 * (
exp(h * t) - 1));
209 Real c = 2 * (rho + (kappa + h) / sigma2 + 0.0);
211 Real df = 4 * kappa * theta / (sigma2);
214 Real ncp = 4 * (rho * rho * y0 *
exp(h * t)) / c;
216 return c * nccs(df, ncp, c * x,
true);
228 Real sigma2 = sigma * sigma;
230 Real h =
sqrt(kappa * kappa + 2.0 * sigma2);
231 Real rho = 2.0 * h / (sigma2 * (
exp(h * (expiry_T - eval_t)) - 1.0));
232 Real Psi = (kappa + h) / sigma2;
237 SP_T =
parametrization()->termStructure()->survivalProbability(expiry_T);
238 SP_tau =
parametrization()->termStructure()->survivalProbability(maturity_tau);
244 Real r_hat = 1.0 /
B(expiry_T, maturity_tau) *
245 (
log(
A(expiry_T, maturity_tau) / strike_k) -
246 log((SP_T *
A(0.0, maturity_tau) *
exp(-
B(0.0, maturity_tau) * y0)) /
247 (SP_tau *
A(0.0, expiry_T) *
exp(-
B(0.0, expiry_T) * y0))));
249 Real denom = rho + Psi +
B(expiry_T, maturity_tau);
250 Real df = 4.0 * kappa * theta / sigma2;
251 Real ncp = 2.0 * rho * rho * y_t *
exp(h * (expiry_T - eval_t)) / denom;
252 QL_REQUIRE(std::isfinite(df) && df > 0,
"CrCirpp::zeroBondOption(): illegal df="
253 << df <<
", kappa=" << kappa <<
", theta= " << theta
254 <<
", sigma=" << sigma);
256 value += nccs(df, ncp, 2 * r_hat * denom,
true) * SP_tau;
260 ncp = 2 * rho * rho * y_t *
exp(h * (expiry_T - eval_t)) / denom;
262 value -= nccs(df, ncp, 2 * r_hat * denom,
true) * SP_T * strike_k;
268 value -= SP_tau - SP_T * strike_k;
Real density(Real x, Real t)
Real zeroBondOption(Real eval_t, Real expiry_T, Real maturity_tau, Real strike_k, Real y_t, Real w)
Real A(Real t, Real T) const
Real densityForwardMeasure(Real x, Real t)
Real cumulativeForwardMeasure(Real x, Real t)
Real zeroBond(Real t, Real T, Real y) const
Real cumulative(Real x, Real t)
QuantLib::ext::shared_ptr< CrCirppParametrization > parametrization_
QuantLib::ext::shared_ptr< CrCirppStateProcess > stateProcess_
Handle< DefaultProbabilityTermStructure > defaultCurve(std::vector< Date > dateGrid=std::vector< Date >()) const
Real B(Real t, Real T) const
CrCirpp(const QuantLib::ext::shared_ptr< CrCirppParametrization > ¶metrization)
Real survivalProbability(Real t, Real T, Real y) const
const QuantLib::ext::shared_ptr< CrCirppParametrization > parametrization() const
DefaultProbabilityTermStructure based on interpolation of survival probabilities.
std::vector< QuantLib::ext::shared_ptr< Parameter > > arguments_
Real value(const Array ¶ms, const std::vector< QuantLib::ext::shared_ptr< CalibrationHelper > > &)
CIR++ credit model class.
RandomVariable sqrt(RandomVariable x)
CompiledFormula exp(CompiledFormula x)
CompiledFormula log(CompiledFormula x)