42 const Real A = std::pow(forward*strike, oneMinusBeta);
43 const Real sqrtA= std::sqrt(A);
45 if (!
close(forward, strike))
46 logM = std::log(forward/strike);
48 const Real epsilon = (forward-strike)/strike;
49 logM = epsilon - .5 * epsilon * epsilon ;
52 const Real B = 1.0-2.0*
rho*z+z*z;
53 const Real C = oneMinusBeta*oneMinusBeta*logM*logM;
54 const Real tmp = (std::sqrt(B)+z-
rho)/(1.0-
rho);
55 const Real xx = std::log(tmp);
56 const Real D = sqrtA*(1.0+C/24.0+C*C/1920.0);
57 const Real d = 1.0 + expiryTime *
58 (oneMinusBeta*oneMinusBeta*
alpha*
alpha/(24.0*A)
65 static const Real m = 10;
69 multiplier = 1.0 - 0.5*
rho*z - (3.0*
rho*
rho-2.0)*z*z/12.0;
71 return (
alpha/D)*multiplier*
d;
92 const Real oneMinusBeta = 1.0 -
beta;
94 const Real A = std::pow(forward * strike, oneMinusBeta);
95 const Real sqrtA = std::sqrt(A);
97 if (!
close(forward, strike))
98 logM = std::log(forward / strike);
100 const Real epsilon = (forward - strike) / strike;
101 logM = epsilon - .5 * epsilon * epsilon;
104 const Real B = 1.0 - 2.0 *
rho * z + z * z;
105 const Real C = oneMinusBeta * oneMinusBeta * logM * logM;
106 const Real D = logM * logM;
107 const Real tmp = (std::sqrt(B) + z -
rho) / (1.0 -
rho);
108 const Real xx = std::log(tmp);
109 const Real E_1 = (1.0 + D / 24.0 + D * D / 1920.0);
110 const Real E_2 = (1.0 + C / 24.0 + C * C / 1920.0);
111 const Real E = E_1 / E_2;
119 static const Real m = 10;
123 multiplier = 1.0 - 0.5 *
rho * z - (3.0 *
rho *
rho - 2.0) * z * z / 12.0;
127 return F * E * multiplier *
d;
150 <<
alpha <<
" not allowed");
152 <<
beta <<
" not allowed");
154 <<
nu <<
" not allowed");
156 <<
rho <<
" not allowed");
167 QL_REQUIRE(strike>0.0,
"strike must be positive: "
168 <<
io::rate(strike) <<
" not allowed");
169 QL_REQUIRE(forward>0.0,
"at the money forward rate must be "
170 "positive: " <<
io::rate(forward) <<
" not allowed");
171 QL_REQUIRE(expiryTime>=0.0,
"expiry time must be non-negative: "
172 << expiryTime <<
" not allowed");
187 QL_REQUIRE(strike + shift > 0.0,
"strike+shift must be positive: "
189 QL_REQUIRE(forward + shift > 0.0,
"at the money forward rate + shift must be "
190 "positive: " <<
io::rate(forward) <<
" " <<
io::rate(shift) <<
" not allowed");
191 QL_REQUIRE(expiryTime>=0.0,
"expiry time must be non-negative: "
192 << expiryTime <<
" not allowed");
199 struct SabrFlochKennedyVolatility {
203 return -1.0/(1.0-
beta)*(std::pow(
F,1-
beta)-std::pow(k,1-
beta));
207 return 1/
nu*std::log( ( std::sqrt(1+2*rho*nu/alpha*
y(k)
209 - rho - nu/alpha*
y(k) ) / (1-rho) );
213 return std::sqrt(alpha*alpha+2*alpha*rho*nu*
y(k)
214 +
squared(nu*
y(k)))*std::pow(k,beta);
218 return std::log(F/k)/Dint(k);
223 if (m > 1.0025 || m < 0.9975) {
225 (std::pow(k,beta)-std::pow(F,beta))/(k-F)*
t)
226 -omega0(k)/
squared(Dint(k))*(std::log(
227 omega0(k)) + 0.5*std::log((F*k/(D(F)*D(k))) ))*t;
230 return taylorExpansion(k);
234 Real taylorExpansion(
Real k)
const {
239 (alpha*std::pow(F,-3 + beta)*(alpha2*
squared(-1 + beta)*std::pow(F,2*beta)*t + 6*alpha*beta*nu*std::pow(F,1 + beta)*rho*t +
240 F2*(24 + nu*nu*(2 - 3*rho2)*t)))/24.0 +
241 (3*alpha2*
alpha*std::pow(-1 + beta,3)*std::pow(F,3*beta)*
t +
242 3*alpha2*(-1 +
beta)*(-1 + 5*beta)*
nu*std::pow(F,1 + 2*beta)*
rho*
t +
nu*F2*
F*
rho*(24 +
nu*
nu*(-4 + 3*rho2)*t) +
243 alpha*std::pow(F,2 + beta)*(24*(-1 +
beta) + nu*nu*(2*(-1 + beta) + 3*(1 +
beta)*rho2)*
t))/(48.*F2*F2) * (k-F) +
244 (std::pow(F,-5 - beta)*(alpha2*alpha2*std::pow(-1 + beta,3)*(-209 + 119*
beta)*std::pow(F,4*beta)*
t + 30*alpha2*
alpha*(-1 +
beta)*(9 + beta*(-37 + 18*beta))*nu*std::pow(F,1 + 3*beta)*
rho*
t -
245 30*
alpha*
nu*std::pow(F,3 + beta)*
rho*(24 +
nu*
nu*(-4*(1 +
beta) + 3*(1 + 2*beta)*rho2)*t) +
246 10*alpha2*std::pow(F,2 + 2*beta)*(24*(-4 +
beta)*(-1 + beta) +
nu*
nu*(2*(-1 +
beta)*(-7 + 4*beta) + 3*(-4 +
beta*(-7 + 5*
beta))*rho2)*t) +
247 nu*
nu*F2*F2*(480 - 720*rho2 +
nu*
nu*(-64 + 75*rho2*(4 - 3*rho2))*
t)))/(2880*alpha) * (k-
F)*(k-F);
259 const SabrFlochKennedyVolatility
v =
floating-point comparisons
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
detail::percent_holder rate(Rate)
output rates and spreads as percentages
Real Time
continuous quantity with 1-year units
functionals and combinators not included in the STL
Real sabrVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho, VolatilityType volatilityType)
Real unsafeShiftedSabrVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho, Real shift, VolatilityType volatilityType)
Real unsafeSabrVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho, VolatilityType volatilityType)
Real sabrFlochKennedyVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho)
Real unsafeSabrNormalVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho)
Real unsafeSabrLogNormalVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho)
bool close(const Quantity &m1, const Quantity &m2, Size n)
void validateSabrParameters(Real alpha, Real beta, Real nu, Real rho)
Real shiftedSabrVolatility(Rate strike, Rate forward, Time expiryTime, Real alpha, Real beta, Real nu, Real rho, Real shift, VolatilityType volatilityType)
ext::shared_ptr< BlackVolTermStructure > v