24#ifndef quantlib_zabr_smile_section_hpp
25#define quantlib_zabr_smile_section_hpp
50 std::vector<Real> zabrParameters,
51 const std::vector<Real>& moneyness = std::vector<Real>(),
52 Size fdRefinement = 5);
55 std::vector<Real> zabrParameters,
57 const std::vector<Real>& moneyness = std::vector<Real>(),
58 Size fdRefinement = 5);
65 return optionPrice(strike, type, discount, Evaluation());
76 void init(
const std::vector<Real> &moneyness) {
77 init(moneyness, Evaluation());
115template <
typename Evaluation>
118 std::vector<Real> zabrParams,
119 const std::vector<Real>& moneyness,
120 const Size fdRefinement)
122 fdRefinement_(fdRefinement) {
126template <
typename Evaluation>
129 std::vector<Real> zabrParams,
131 const std::vector<Real>& moneyness,
132 const Size fdRefinement)
134 fdRefinement_(fdRefinement) {
138template <
typename Evaluation>
142 model_ = ext::make_shared<ZabrModel>(
143 exerciseTime(), forward_, params_[0], params_[1],
144 params_[2], params_[3], params_[4]);
147template <
typename Evaluation>
153template <
typename Evaluation>
158 "zabr expects 5 parameters (alpha,beta,nu,rho,gamma) but ("
159 << params_.size() <<
") given");
161 model_ = ext::make_shared<ZabrModel>(
162 exerciseTime(), forward_, params_[0], params_[1],
163 params_[2], params_[3], params_[4]);
167 static const Real defaultMoney[] = {
168 0.0, 0.01, 0.05, 0.10, 0.25, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90,
169 1.0, 1.25, 1.5, 1.75, 2.0, 5.0, 7.5, 10.0, 15.0, 20.0};
170 std::vector<Real> tmp;
171 if (moneyness.empty())
172 tmp = std::vector<Real>(defaultMoney, defaultMoney + 21);
174 tmp = std::vector<Real>(moneyness);
178 bool firstStrike =
true;
180 Real f = i * forward_;
183 for (
Size j = 1; j <= fdRefinement_; ++j) {
184 strikes_.push_back(lastF +
185 ((
double)j) * (
f - lastF) /
186 (fdRefinement_ + 1));
191 strikes_.push_back(
f);
196template <
typename Evaluation>
202template <
typename Evaluation>
205template <
typename Evaluation>
208template <
typename Evaluation>
210 callPrices_ = model_->fdPrice(strikes_);
213template <
typename Evaluation>
215 callPrices_.resize(strikes_.size());
216#pragma omp parallel for
217 for (
long i = 0; i < (long)strikes_.size(); i++) {
218 callPrices_[i] = model_->fullFdPrice(strikes_[i]);
222template <
typename Evaluation>
225template <
typename Evaluation>
228template <
typename Evaluation>
230 strikes_.insert(strikes_.begin(), 0.0);
231 callPrices_.insert(callPrices_.begin(), forward_);
234 strikes_.begin(), strikes_.end(), callPrices_.begin(),
241 callPriceFct_->enableExtrapolation();
246 static const Real eps = 1E-5;
248 Real c0 = (*callPriceFct_)(strikes_.back());
249 Real c0p = ((*callPriceFct_)(strikes_.back() - eps) - c0) / eps;
252 b_ = std::log(c0) +
a_ * strikes_.back();
255template <
typename Evaluation>
260template <
typename Evaluation>
268template <
typename Evaluation>
273 type, strike, forward_,
274 model_->normalVolatility(strike) * std::sqrt(exerciseTime()), discount);
277template <
typename Evaluation>
281 Real call = strike <= strikes_.back() ? (*callPriceFct_)(strike)
282 : exp(-
a_ * strike +
b_);
284 return call * discount;
286 return (call - (forward_ - strike)) * discount;
289template <
typename Evaluation>
296template <
typename Evaluation>
300 strike = std::max(1E-6, strike);
301 return model_->lognormalVolatility(strike);
304template <
typename Evaluation>
308 Real impliedVol = 0.0;
311 if (strike >= model_->forward())
317 optionPrice(strike, type, 1.0), 1.0) /
318 std::sqrt(exerciseTime());
324template <
typename Evaluation>
330template <
typename Evaluation>
Actual/365 (Fixed) day counter.
Actual/365 (Fixed) day count convention.
Cubic interpolation between discrete points.
@ SecondDerivative
Match value of second derivative at end.
interest rate volatility smile section
virtual Real optionPrice(Rate strike, Option::Type type=Option::Call, Real discount=1.0) const
std::vector< Real > callPrices_
ext::shared_ptr< ZabrModel > model()
void init(const std::vector< Real > &moneyness)
Real atmLevel() const override
std::vector< Real > strikes_
void init3(ZabrShortMaturityLognormal)
void init2(ZabrShortMaturityLognormal)
ext::shared_ptr< ZabrModel > model_
Real minStrike() const override
ext::shared_ptr< Interpolation > callPriceFct_
ZabrSmileSection(Time timeToExpiry, Rate forward, std::vector< Real > zabrParameters, const std::vector< Real > &moneyness=std::vector< Real >(), Size fdRefinement=5)
std::vector< Real > params_
Volatility volatilityImpl(Rate strike) const override
Real optionPrice(Rate strike, Option::Type type=Option::Call, Real discount=1.0) const override
Real maxStrike() const override
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
std::size_t Size
size of a container
Real bachelierBlackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount)
Real blackFormulaImpliedStdDev(Option::Type optionType, Real strike, Real forward, Real blackPrice, Real discount, Real displacement, Real guess, Real accuracy, Natural maxIterations)
Smile section base class.
Additional utilities for smile sections.
ZABR functions Reference: Andreasen, Huge: ZABR - Expansions for the masses, Preliminary Version,...