30#ifndef quantlib_pricers_black_swaption_hpp
31#define quantlib_pricers_black_swaption_hpp
33#include <ql/cashflows/cashflows.hpp>
34#include <ql/cashflows/fixedratecoupon.hpp>
35#include <ql/exercise.hpp>
36#include <ql/indexes/iborindex.hpp>
37#include <ql/instruments/swaption.hpp>
38#include <ql/pricingengines/blackformula.hpp>
39#include <ql/pricingengines/swap/discountingswapengine.hpp>
40#include <ql/termstructures/volatility/swaption/swaptionconstantvol.hpp>
41#include <ql/termstructures/volatility/swaption/swaptionvolstructure.hpp>
42#include <ql/time/calendars/nullcalendar.hpp>
60 Real displacement = 0.0,
65 Real displacement = 0.0,
84 const Real atmForward,
const Real stdDev,
const Real annuity,
85 const Real displacement) {
90 const Real exerciseTime,
const Real annuity,
91 const Real displacement) {
92 return std::sqrt(exerciseTime) *
94 annuity, displacement);
97 const Real atmForward,
const Real stdDev,
const Real annuity,
98 const Real displacement) {
100 annuity, displacement);
108 const Real atmForward,
const Real stdDev,
const Real annuity,
114 const Real exerciseTime,
const Real annuity,
const Real) {
115 return std::sqrt(exerciseTime) *
117 strike, atmForward, stdDev, annuity);
120 const Real atmForward,
const Real stdDev,
const Real annuity,
123 type, strike, atmForward, stdDev, annuity);
142 Real displacement = 0.0,
147 Real displacement = 0.0,
181 template <
class Spec>
188 : discountCurve_(
std::move(discountCurve)),
195 template <
class Spec>
202 : discountCurve_(
std::move(discountCurve)),
210 template <
class Spec>
215 : discountCurve_(
std::move(discountCurve)), vol_(
std::move(volatility)), model_(model) {
222 static const Spread basisPoint = 1.0e-4;
224 Date exerciseDate = arguments_.exercise->date(0);
230 const Leg& fixedLeg =
swap.fixedLeg();
231 ext::shared_ptr<FixedRateCoupon> firstCoupon =
232 ext::dynamic_pointer_cast<FixedRateCoupon>(fixedLeg[0]);
233 QL_REQUIRE(firstCoupon->accrualStartDate() >= exerciseDate,
234 "swap start (" << firstCoupon->accrualStartDate() <<
") before exercise date ("
235 << exerciseDate <<
") not supported in Black swaption engine");
241 swap.setPricingEngine(ext::shared_ptr<PricingEngine>(
new
248 if (
swap.spread()!=0.0) {
250 std::fabs(
swap.floatingLegBPS()/
swap.fixedLegBPS());
251 strike -= correction;
252 atmForward -= correction;
253 results_.additionalResults[
"spreadCorrection"] = correction;
255 results_.additionalResults[
"spreadCorrection"] =
Real(0.0);
257 results_.additionalResults[
"strike"] = strike;
258 results_.additionalResults[
"atmForward"] = atmForward;
261 swap.setPricingEngine(ext::shared_ptr<PricingEngine>(
266 arguments_.settlementMethod ==
268 annuity = std::fabs(
swap.fixedLegBPS()) / basisPoint;
271 DayCounter dayCount = firstCoupon->dayCounter();
275 ? firstCoupon->accrualStartDate()
276 : discountCurve_->referenceDate();
281 annuity = std::fabs(fixedLegCashBPS / basisPoint) *
282 discountCurve_->discount(discountDate);
284 QL_FAIL(
"invalid (settlementType, settlementMethod) pair");
286 results_.additionalResults[
"annuity"] = annuity;
288 Time swapLength = vol_->swapLength(
swap.floatingSchedule().dates().front(),
289 swap.floatingSchedule().dates().back());
293 swapLength = std::max(swapLength, 1.0 / 12.0);
294 results_.additionalResults[
"swapLength"] = swapLength;
296 Real variance = vol_->blackVariance(exerciseDate, swapLength, strike);
300 vol_->shift(exerciseDate, swapLength) : 0.0;
302 Real stdDev = std::sqrt(variance);
303 results_.additionalResults[
"stdDev"] = stdDev;
305 results_.value = Spec().value(w, strike, atmForward, stdDev, annuity, displacement);
307 Time exerciseTime = vol_->timeFromReference(exerciseDate);
308 results_.additionalResults[
"vega"] = Spec().vega(
309 strike, atmForward, stdDev, exerciseTime, annuity, displacement);
310 results_.additionalResults[
"delta"] = Spec().delta(
311 w, strike, atmForward, stdDev, annuity, displacement);
312 results_.additionalResults[
"timeToExpiry"] = exerciseTime;
313 results_.additionalResults[
"impliedVolatility"] =
Real(stdDev / std::sqrt(exerciseTime));
Actual/365 (Fixed) day count convention.
Normal Bachelier-formula swaption engine.
Shifted Lognormal Black-formula swaption engine.
static Real bps(const Leg &leg, const YieldTermStructure &discountCurve, bool includeSettlementDateFlows, Date settlementDate=Date(), Date npvDate=Date())
Basis-point sensitivity of the cash flows.
Constant swaption volatility, no time-strike dependence.
Shared handle to an observable.
Concrete interest rate class.
YieldTermStructure based on interpolation of discount factors.
Calendar for reproducing theoretical calculations.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
base class for swaption engines
Swaption-volatility structure
Plain-vanilla swap: fix vs ibor leg.
Handle< YieldTermStructure > discountCurve_
BlackStyleSwaptionEngine(Handle< YieldTermStructure > discountCurve, Volatility vol, const DayCounter &dc=Actual365Fixed(), Real displacement=0.0, CashAnnuityModel model=DiscountCurve)
Handle< SwaptionVolatilityStructure > volatility()
BlackStyleSwaptionEngine(Handle< YieldTermStructure > discountCurve, const Handle< Quote > &vol, const DayCounter &dc=Actual365Fixed(), Real displacement=0.0, CashAnnuityModel model=DiscountCurve)
BlackStyleSwaptionEngine(Handle< YieldTermStructure > discountCurve, Handle< SwaptionVolatilityStructure > vol, CashAnnuityModel model=DiscountCurve)
void calculate() const override
Handle< SwaptionVolatilityStructure > vol_
Handle< YieldTermStructure > termStructure()
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
Real Spread
spreads on interest rates
Real bachelierBlackFormulaStdDevDerivative(Rate strike, Rate forward, Real stdDev, Real discount)
Real bachelierBlackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount)
void swap(Array &v, Array &w) noexcept
Real blackFormulaForwardDerivative(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
Real bachelierBlackFormulaForwardDerivative(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount)
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
Real blackFormulaStdDevDerivative(Rate strike, Rate forward, Real stdDev, Real discount, Real displacement)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
@ CollateralizedCashPrice
Real vega(const Real strike, const Real atmForward, const Real stdDev, const Real exerciseTime, const Real annuity, const Real)
Real value(const Option::Type type, const Real strike, const Real atmForward, const Real stdDev, const Real annuity, const Real)
Real delta(const Option::Type type, const Real strike, const Real atmForward, const Real stdDev, const Real annuity, const Real)
static const VolatilityType type
Real value(const Option::Type type, const Real strike, const Real atmForward, const Real stdDev, const Real annuity, const Real displacement)
Real vega(const Real strike, const Real atmForward, const Real stdDev, const Real exerciseTime, const Real annuity, const Real displacement)
static const VolatilityType type
Real delta(const Option::Type type, const Real strike, const Real atmForward, const Real stdDev, const Real annuity, const Real displacement)