26#include <ql/cashflows/cashflows.hpp>
27#include <ql/cashflows/couponpricer.hpp>
28#include <ql/cashflows/fixedratecoupon.hpp>
29#include <ql/cashflows/iborcoupon.hpp>
30#include <ql/cashflows/simplecashflow.hpp>
31#include <ql/exercise.hpp>
32#include <ql/instruments/makevanillaswap.hpp>
33#include <ql/math/optimization/costfunction.hpp>
34#include <ql/math/optimization/levenbergmarquardt.hpp>
35#include <ql/pricingengines/swap/discountingswapengine.hpp>
36#include <ql/termstructures/yield/flatforward.hpp>
37#include <ql/time/daycounters/actualactual.hpp>
42 const std::vector<Leg>& underlying,
const std::vector<bool>& isPayer,
43 const QuantLib::ext::shared_ptr<SwapIndex>& swapIndexBase,
const bool useUnderlyingIborIndex,
44 const Handle<YieldTermStructure>& discountCurve,
const Real reversion,
const Real volatility,
const Real flatRate)
45 : underlying_(underlying), isPayer_(isPayer), swapIndexBase_(swapIndexBase),
46 useUnderlyingIborIndex_(useUnderlyingIborIndex), discountCurve_(discountCurve), reversion_(reversion),
47 volatility_(volatility), flatRate_(flatRate) {
50 Handle<YieldTermStructure> flatCurve;
51 if (flatRate != Null<Real>()) {
53 Handle<YieldTermStructure>(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(),
flatRate_, ActualActual(ActualActual::ISDA)));
57 Date maturityDate = Date::minDate();
58 for (
auto const& l : underlying)
59 for (
auto const& c : l)
60 maturityDate = std::max(c->date(), maturityDate);
61 QL_REQUIRE(maturityDate > discountCurve->referenceDate(),
"underlying maturity ("
62 << maturityDate <<
") must be gt reference date ("
66 model_ = QuantLib::ext::make_shared<LGM>(QuantLib::ext::make_shared<IrLgm1fPiecewiseConstantHullWhiteAdaptor>(
71 QuantLib::ext::shared_ptr<IborIndex> modelIborIndexToUse, iborIndexToUse;
74 if (
auto i = QuantLib::ext::dynamic_pointer_cast<IborCoupon>(c)) {
76 QL_REQUIRE(!i->isInArrears(),
"RepresentativeSwaptionMatcher: can not handle in arrears fixing");
77 QuantLib::ext::shared_ptr<LgmImpliedYtsFwdFwdCorrected> y;
82 y = QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(
83 model_, flatCurve.empty() ? i->iborIndex()->forwardingTermStructure() : flatCurve);
86 auto iborIndexLinkedToModelCurve = i->iborIndex()->clone(Handle<YieldTermStructure>(y));
87 auto tmp = QuantLib::ext::make_shared<IborCoupon>(
88 i->date(), i->nominal(), i->accrualStartDate(), i->accrualEndDate(), i->fixingDays(),
89 iborIndexLinkedToModelCurve, i->gearing(), i->spread(), i->referencePeriodStart(),
90 i->referencePeriodEnd(), i->dayCounter(),
false);
91 tmp->setPricer(QuantLib::ext::make_shared<BlackIborCouponPricer>());
93 if (modelIborIndexToUse ==
nullptr) {
94 modelIborIndexToUse = iborIndexLinkedToModelCurve;
95 iborIndexToUse = i->iborIndex();
97 }
else if (
auto o = QuantLib::ext::dynamic_pointer_cast<QuantExt::OvernightIndexedCoupon>(c)) {
98 auto onIndex = o->overnightIndex();
99 QL_REQUIRE(onIndex,
"internal error: could not cast o->index() to overnightIndex");
100 QuantLib::ext::shared_ptr<LgmImpliedYtsFwdFwdCorrected> y;
105 y = QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(
106 model_, flatCurve.empty() ? onIndex->forwardingTermStructure() : flatCurve);
109 auto onIndexLinkedToModelCurve =
110 QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(onIndex->clone(Handle<YieldTermStructure>(y)));
111 QL_REQUIRE(onIndexLinkedToModelCurve,
112 "internal error: could not cast onIndex->clone() to OvernightIndex");
113 auto tmp = QuantLib::ext::make_shared<QuantExt::OvernightIndexedCoupon>(
114 o->date(), o->nominal(), o->accrualStartDate(), o->accrualEndDate(), onIndexLinkedToModelCurve,
115 o->gearing(), o->spread(), o->referencePeriodStart(), o->referencePeriodEnd(), o->dayCounter(),
116 false, o->includeSpread(), o->lookback(), o->rateCutoff(), o->fixingDays(),
117 o->rateComputationStartDate(), o->rateComputationEndDate());
118 tmp->setPricer(QuantLib::ext::make_shared<OvernightIndexedCouponPricer>());
120 if (modelIborIndexToUse ==
nullptr) {
121 modelIborIndexToUse = onIndexLinkedToModelCurve;
122 iborIndexToUse = o->overnightIndex();
124 }
else if (
auto o = QuantLib::ext::dynamic_pointer_cast<QuantExt::AverageONIndexedCoupon>(c)) {
125 auto onIndex = o->overnightIndex();
126 QL_REQUIRE(onIndex,
"internal error: could not cast o->index() to overnightIndex");
127 QuantLib::ext::shared_ptr<LgmImpliedYtsFwdFwdCorrected> y;
132 y = QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(
133 model_, flatCurve.empty() ? onIndex->forwardingTermStructure() : flatCurve);
136 auto onIndexLinkedToModelCurve =
137 QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(onIndex->clone(Handle<YieldTermStructure>(y)));
138 QL_REQUIRE(onIndexLinkedToModelCurve,
139 "internal error: could not cast onIndex->clone() to OvernightIndex");
140 auto tmp = QuantLib::ext::make_shared<QuantExt::AverageONIndexedCoupon>(
141 o->date(), o->nominal(), o->accrualStartDate(), o->accrualEndDate(), onIndexLinkedToModelCurve,
142 o->gearing(), o->spread(), o->rateCutoff(), o->dayCounter(), o->lookback(), o->fixingDays(),
143 o->rateComputationStartDate(), o->rateComputationEndDate());
144 tmp->setPricer(QuantLib::ext::make_shared<AverageONIndexedCouponPricer>());
146 if (modelIborIndexToUse ==
nullptr) {
147 modelIborIndexToUse = onIndexLinkedToModelCurve;
148 iborIndexToUse = o->overnightIndex();
150 }
else if (QuantLib::ext::dynamic_pointer_cast<FixedRateCoupon>(c) ||
151 QuantLib::ext::dynamic_pointer_cast<SimpleCashFlow>(c)) {
155 QL_FAIL(
"RepresentativeSwaptionMatcher: unsupported coupon type");
163 QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(
model_, flatCurve.empty() ?
discountCurve_ : flatCurve);
169 modelIborIndexToUse =
swapIndexBase_->iborIndex()->clone(Handle<YieldTermStructure>(fc->second));
172 Handle<YieldTermStructure>(QuantLib::ext::make_shared<LgmImpliedYtsFwdFwdCorrected>(
173 model_, flatCurve.empty() ?
swapIndexBase_->iborIndex()->forwardingTermStructure() : flatCurve)));
179 QuantLib::ext::dynamic_pointer_cast<LgmImpliedYtsFwdFwdCorrected>(*modelIborIndexToUse->forwardingTermStructure());
181 "internal error: could not cast modelIborIndexToUse->forwardingTermStructure() to "
182 "LgmImpliedYtsFwdFwdCorrected");
185 ? modelIborIndexToUse->forwardingTermStructure()
203bool includeCashflow(
const QuantLib::ext::shared_ptr<CashFlow>& f,
const Date& exerciseDate,
207 if (
auto c = QuantLib::ext::dynamic_pointer_cast<Coupon>(f))
208 return c->accrualStartDate() >= exerciseDate;
210 return f->date() > exerciseDate;
212 QL_FAIL(
"unknown inclusiong criterion");
221 "exerciseDate (" << exerciseDate <<
") must be greater than reference date ("
226 constexpr static Real h = 1.0E-4;
232 Real additionalDeterministicNpv = 0.0;
233 std::vector<bool> effectiveIsPayer;
236 if (!includeCashflow(cf, exerciseDate, criterion))
238 if (
auto i = QuantLib::ext::dynamic_pointer_cast<IborCoupon>(cf)) {
239 if (today <= i->fixingDate() && i->fixingDate() < exerciseDate) {
246 Calendar cal = i->iborIndex()->fixingCalendar();
247 Date newAccrualStart = cal.advance(cal.adjust(exerciseDate), i->fixingDays() * Days);
248 Date newAccrualEnd = std::max(i->accrualEndDate(), newAccrualStart + 1);
249 Real newAccrualTime = i->dayCounter().yearFraction(newAccrualStart, newAccrualEnd);
250 Real oldAccrualTime = i->dayCounter().yearFraction(i->accrualStartDate(), i->accrualEndDate());
251 auto tmp = QuantLib::ext::make_shared<IborCoupon>(
252 i->date(), i->nominal() * oldAccrualTime / newAccrualTime, newAccrualStart, newAccrualEnd,
253 i->fixingDays(), i->iborIndex(), i->gearing(), i->spread(), i->referencePeriodStart(),
254 i->referencePeriodEnd(), i->dayCounter(),
false);
255 tmp->setPricer(QuantLib::ext::make_shared<BlackIborCouponPricer>());
256 effectiveLeg.push_back(tmp);
260 effectiveLeg.push_back(cf);
263 }
else if (
auto o = QuantLib::ext::dynamic_pointer_cast<OvernightIndexedCoupon>(cf)) {
265 if (o->fixingDates().empty())
270 if (o->fixingDates().front() >= exerciseDate) {
271 o->setPricer(QuantLib::ext::make_shared<QuantExt::OvernightIndexedCouponPricer>());
272 effectiveLeg.push_back(o);
283 Real accrualToRatePeriodRatio = 1.0;
284 if (o->rateComputationStartDate() != Null<Date>() && o->rateComputationEndDate() != Null<Date>()) {
285 accrualToRatePeriodRatio =
286 o->dayCounter().yearFraction(o->accrualStartDate(), o->accrualEndDate()) /
287 o->dayCounter().yearFraction(o->rateComputationStartDate(), o->rateComputationEndDate());
289 Date firstFixingDate = o->fixingDates().front();
290 if (firstFixingDate < today) {
291 Date firstValueDate =
valueDate(firstFixingDate, o);
292 Date lastFixingDateBeforeToday =
293 *std::next(std::lower_bound(o->fixingDates().begin(), o->fixingDates().end(), today), -1);
294 Date lastValueDateBeforeToday =
valueDate(lastFixingDateBeforeToday, o);
295 if (lastValueDateBeforeToday > firstValueDate) {
296 auto tmp = QuantLib::ext::make_shared<OvernightIndexedCoupon>(
297 o->date(), o->nominal() * accrualToRatePeriodRatio, firstValueDate,
298 lastValueDateBeforeToday, o->overnightIndex(), o->gearing(), o->spread(),
299 o->referencePeriodStart(), o->referencePeriodEnd(), o->dayCounter(),
false,
300 o->includeSpread(), 0 * Days, o->rateCutoff(), o->fixingDays());
301 tmp->setPricer(QuantLib::ext::make_shared<QuantExt::OvernightIndexedCouponPricer>());
302 additionalDeterministicNpv +=
discountCurve_->discount(tmp->date()) * tmp->amount();
305 if (o->fixingDates().back() >= today) {
306 Date firstFixingDateGeqToday =
307 *std::lower_bound(o->fixingDates().begin(), o->fixingDates().end(), today);
308 Date firstValueDateGeqToday =
valueDate(firstFixingDateGeqToday, o);
309 Date lastValueDate =
valueDate(o->fixingDates().back(), o);
310 Date startDate = o->index()->fixingCalendar().adjust(exerciseDate);
311 Date endDate = std::max(lastValueDate, startDate + 1);
312 Real factor = o->dayCounter().yearFraction(firstValueDateGeqToday, lastValueDate) /
313 o->dayCounter().yearFraction(startDate, endDate);
314 auto tmp = QuantLib::ext::make_shared<OvernightIndexedCoupon>(
315 o->date(), o->nominal() * accrualToRatePeriodRatio * factor, startDate, endDate,
316 o->overnightIndex(), o->gearing(), o->spread(), o->referencePeriodStart(),
317 o->referencePeriodEnd(), o->dayCounter(),
false, o->includeSpread(), 0 * Days, o->rateCutoff(),
319 tmp->setPricer(QuantLib::ext::make_shared<OvernightIndexedCouponPricer>());
320 effectiveLeg.push_back(tmp);
324 }
else if (
auto o = QuantLib::ext::dynamic_pointer_cast<AverageONIndexedCoupon>(cf)) {
326 if (o->fixingDates().empty())
329 if (o->fixingDates().front() >= exerciseDate) {
330 o->setPricer(QuantLib::ext::make_shared<QuantExt::AverageONIndexedCouponPricer>());
331 effectiveLeg.push_back(o);
335 Real accrualToRatePeriodRatio = 1.0;
336 if (o->rateComputationStartDate() != Null<Date>() && o->rateComputationEndDate() != Null<Date>()) {
337 accrualToRatePeriodRatio =
338 o->dayCounter().yearFraction(o->accrualStartDate(), o->accrualEndDate()) /
339 o->dayCounter().yearFraction(o->rateComputationStartDate(), o->rateComputationEndDate());
341 Date firstFixingDate = o->fixingDates().front();
342 if (firstFixingDate < today) {
343 Date firstValueDate =
valueDate(firstFixingDate, o);
344 Date lastFixingDateBeforeToday =
345 *std::next(std::lower_bound(o->fixingDates().begin(), o->fixingDates().end(), today), -1);
346 Date lastValueDateBeforeToday =
valueDate(lastFixingDateBeforeToday, o);
347 if (lastValueDateBeforeToday > firstValueDate) {
348 auto tmp = QuantLib::ext::make_shared<AverageONIndexedCoupon>(
349 o->date(), o->nominal() * accrualToRatePeriodRatio, firstValueDate,
350 lastValueDateBeforeToday, o->overnightIndex(), o->gearing(), o->spread(), o->rateCutoff(),
351 o->dayCounter(), 0 * Days, o->fixingDays());
352 tmp->setPricer(QuantLib::ext::make_shared<QuantExt::AverageONIndexedCouponPricer>());
353 additionalDeterministicNpv +=
discountCurve_->discount(tmp->date()) * tmp->amount();
356 if (o->fixingDates().back() >= today) {
357 Date firstFixingDateGeqToday =
358 *std::lower_bound(o->fixingDates().begin(), o->fixingDates().end(), today);
359 Date firstValueDateGeqToday =
valueDate(firstFixingDateGeqToday, o);
360 Date lastValueDate =
valueDate(o->fixingDates().back(), o);
361 Date startDate = o->index()->fixingCalendar().adjust(exerciseDate);
362 Date endDate = std::max(lastValueDate, startDate + 1);
363 Real factor = o->dayCounter().yearFraction(firstValueDateGeqToday, lastValueDate) /
364 o->dayCounter().yearFraction(startDate, endDate);
365 auto tmp = QuantLib::ext::make_shared<AverageONIndexedCoupon>(
366 o->date(), o->nominal() * accrualToRatePeriodRatio * factor, startDate, endDate,
367 o->overnightIndex(), o->gearing(), o->spread(), o->rateCutoff(), o->dayCounter(), 0 * Days,
369 tmp->setPricer(QuantLib::ext::make_shared<AverageONIndexedCouponPricer>());
370 effectiveLeg.push_back(tmp);
374 }
else if (QuantLib::ext::dynamic_pointer_cast<FixedRateCoupon>(cf) !=
nullptr ||
375 QuantLib::ext::dynamic_pointer_cast<SimpleCashFlow>(cf) !=
nullptr) {
376 effectiveLeg.push_back(cf);
379 QL_FAIL(
"internal error: coupon type in modelLinkedUnderlying_ not supported in representativeSwaption()");
383 if (effectiveLeg.empty())
384 return QuantLib::ext::shared_ptr<Swaption>();
387 exerciseDate =
swapIndexBase_->fixingCalendar().adjust(exerciseDate);
393 model_->parametrization()->shift() = -
model_->parametrization()->H(t_ex);
396 Real nominalSum = 0.0, nominalSumAbs = 0.0, strikeGuess = 0.0;
400 strikeGuess += f->rate() * std::abs(f->nominal());
402 nominalSumAbs += std::abs(f->nominal());
406 Real nominalGuess = nominalSum /
static_cast<Real
>(nCpns);
410 strikeGuess /= nominalSumAbs;
413 Real maturityGuess = ActualActual(ActualActual::ISDA).yearFraction(exerciseDate, CashFlows::maturityDate(
modelLinkedUnderlying_));
416 struct Matcher :
public CostFunction {
417 QuantLib::ext::shared_ptr<VanillaSwap> underlyingSwap(
const QuantLib::ext::shared_ptr<SwapIndex> swapIndexBase,
418 const Period& maturity)
const {
420 return MakeVanillaSwap(maturity, swapIndexBase->iborIndex(), 0.0)
421 .withEffectiveDate(swapIndexBase->valueDate(exerciseDate))
422 .withFixedLegCalendar(swapIndexBase->fixingCalendar())
423 .withFixedLegDayCount(swapIndexBase->dayCounter())
424 .withFixedLegTenor(swapIndexBase->fixedLegTenor())
425 .withFixedLegConvention(swapIndexBase->fixedLegConvention())
426 .withFixedLegTerminationDateConvention(swapIndexBase->fixedLegConvention())
430 void setState(
const Real state)
const {
431 for (
auto const& c : modelCurves)
434 std::tuple<Size, Real> periodFromTime(Real t)
const {
436 Size months =
static_cast<Size
>(std::floor(t));
437 Real alpha = t -
static_cast<Real
>(months);
438 return std::make_tuple(months, alpha);
440 Array values(
const Array& x)
const override {
441 Real maturityTime = std::min(x[2] * x[2], maxMaturityTime);
446 std::tie(months, alpha) = periodFromTime(maturityTime);
449 auto res = cachedRawResults.find(months);
450 if (res != cachedRawResults.end()) {
451 rawResult = res->second;
453 Period lowerMaturity = months * Months;
454 Period upperMaturity = lowerMaturity + 1 * Months;
456 QuantLib::ext::shared_ptr<VanillaSwap> underlyingLower, underlyingUpper;
457 if (lowerMaturity > 0 * Months)
458 underlyingLower = underlyingSwap(modelSwapIndexBase, lowerMaturity);
459 underlyingUpper = underlyingSwap(modelSwapIndexBase, upperMaturity);
461 underlyingLower->setPricingEngine(engine);
462 underlyingUpper->setPricingEngine(engine);
464 rawResult.npv0_l = underlyingLower ? underlyingLower->NPV() : 0.0;
465 rawResult.bps0_l = underlyingLower ? underlyingLower->fixedLegBPS() * 1.0E4 : 0.0;
466 rawResult.npv0_u = underlyingUpper->NPV();
467 rawResult.bps0_u = underlyingUpper->fixedLegBPS() * 1.0E4;
469 rawResult.npvu_l = underlyingLower ? underlyingLower->NPV() : 0.0;
470 rawResult.bpsu_l = underlyingLower ? underlyingLower->fixedLegBPS() * 1.0E4 : 0.0;
471 rawResult.npvu_u = underlyingUpper->NPV();
472 rawResult.bpsu_u = underlyingUpper->fixedLegBPS() * 1.0E4;
474 rawResult.npvd_l = underlyingLower ? underlyingLower->NPV() : 0.0;
475 rawResult.bpsd_l = underlyingLower ? underlyingLower->fixedLegBPS() * 1.0E4 : 0.0;
476 rawResult.npvd_u = underlyingUpper->NPV();
477 rawResult.bpsd_u = underlyingUpper->fixedLegBPS() * 1.0E4;
478 cachedRawResults[months] = rawResult;
481 Real v0_l = x[0] * (rawResult.npv0_l + rawResult.bps0_l * x[1]);
482 Real v0_u = x[0] * (rawResult.npv0_u + rawResult.bps0_u * x[1]);
483 Real vu_l = x[0] * (rawResult.npvu_l + rawResult.bpsu_l * x[1]);
484 Real vu_u = x[0] * (rawResult.npvu_u + rawResult.bpsu_u * x[1]);
485 Real vd_l = x[0] * (rawResult.npvd_l + rawResult.bpsd_l * x[1]);
486 Real vd_u = x[0] * (rawResult.npvd_u + rawResult.bpsd_u * x[1]);
488 Real v0 = v0_l * (1.0 - alpha) + v0_u * alpha;
489 Real vu = vu_l * (1.0 - alpha) + vu_u * alpha;
490 Real vd = vd_l * (1.0 - alpha) + vd_u * alpha;
492 Real delta = (vu - vd) / (2.0 * h);
493 Real gamma = (vu + vd) / (h * h);
495 Array target{(v0 - npv_target) / delta_target, (delta - delta_target) / delta_target,
496 (gamma - gamma_target) / gamma_target};
502 Real maxMaturityTime;
503 QuantLib::ext::shared_ptr<SwapIndex> modelSwapIndexBase;
504 QuantLib::ext::shared_ptr<PricingEngine> engine;
505 std::set<QuantLib::ext::shared_ptr<LgmImpliedYtsFwdFwdCorrected>> modelCurves;
506 Real npv_target, delta_target, gamma_target;
509 double npv0_l, npvu_l, npvd_l, bps0_l, bpsu_l, bpsd_l;
510 double npv0_u, npvu_u, npvd_u, bps0_u, bpsu_u, bpsd_u;
512 mutable std::map<Size, RawResult> cachedRawResults;
519 matcher.maxMaturityTime =
discountCurve_->dayCounter().yearFraction(exerciseDate, Date::maxDate() - 365);
520 matcher.exerciseDate = exerciseDate;
522 matcher.engine = QuantLib::ext::make_shared<DiscountingSwapEngine>(Handle<YieldTermStructure>(
modelDiscountCurve_),
false,
523 exerciseDate, exerciseDate);
525 matcher.modelCurves.insert(c.second);
531 for (
auto const& c : matcher.modelCurves)
532 c->referenceDate(exerciseDate);
536 for (Size c = 0; c < effectiveLeg.size(); ++c) {
537 if (effectiveIsPayer[c])
538 pay.push_back(effectiveLeg[c]);
540 rec.push_back(effectiveLeg[c]);
542 Swap exotic(pay, rec);
543 exotic.setPricingEngine(matcher.engine);
544 Real v0 = exotic.NPV();
546 Real vu = exotic.NPV();
547 matcher.setState(-h);
548 Real vd = exotic.NPV();
549 matcher.npv_target = v0 + additionalDeterministicNpv;
550 matcher.delta_target = (vu - vd) / (2.0 * h);
551 matcher.gamma_target = (vu + vd) / (h * h);
554 NoConstraint constraint;
555 Array guess{nominalGuess, strikeGuess, std::sqrt(maturityGuess)};
556 Problem problem(matcher, constraint, guess);
557 LevenbergMarquardt opt;
558 EndCriteria ec(1000, 20, 1E-8, 1E-8, 1E-8);
559 opt.minimize(problem, ec);
562 Array x = problem.currentValue();
567 std::tie(months, alpha) = matcher.periodFromTime(std::min(x[2] * x[2], matcher.maxMaturityTime));
568 Size nMonths = std::max<Size>(1, (months +
static_cast<Size
>(std::round(alpha))));
569 Period maturity = nMonths * Months;
571 nominal *= x[2] * x[2] * 12.0 /
static_cast<Real
>(nMonths);
572 QuantLib::ext::shared_ptr<VanillaSwap> underlying =
580 .receiveFixed(nominal > 0.0)
581 .withNominal(std::abs(nominal));
582 underlying->setPricingEngine(QuantLib::ext::make_shared<DiscountingSwapEngine>(
discountCurve_));
583 return QuantLib::ext::make_shared<Swaption>(underlying, QuantLib::ext::make_shared<EuropeanExercise>(exerciseDate));
588 const QuantLib::ext::shared_ptr<QuantLib::FloatingRateCoupon>& cpn)
const {
589 return cpn->index()->fixingCalendar().advance(fixingDate, cpn->fixingDays(), Days, Following);
coupon paying the weighted average of the daily overnight rate
Pricer for average overnight indexed coupons.
QuantLib::ext::shared_ptr< SwapIndex > modelSwapIndexBase_
const Handle< YieldTermStructure > discountCurve_
QuantLib::ext::shared_ptr< Swaption > representativeSwaption(Date exerciseDate, const InclusionCriterion criterion=InclusionCriterion::AccrualStartGeqExercise)
const std::vector< Leg > underlying_
std::vector< bool > modelLinkedUnderlyingIsPayer_
QuantLib::ext::shared_ptr< SwapIndex > swapIndexBaseFinal_
QuantLib::ext::shared_ptr< LgmImpliedYtsFwdFwdCorrected > modelSwapIndexDiscountCurve_
QuantLib::ext::shared_ptr< LgmImpliedYtsFwdFwdCorrected > modelDiscountCurve_
QuantLib::ext::shared_ptr< LGM > model_
std::map< std::string, QuantLib::ext::shared_ptr< LgmImpliedYtsFwdFwdCorrected > > modelForwardCurves_
Leg modelLinkedUnderlying_
const QuantLib::ext::shared_ptr< SwapIndex > swapIndexBase_
QuantLib::ext::shared_ptr< LgmImpliedYtsFwdFwdCorrected > modelSwapIndexForwardCurve_
const bool useUnderlyingIborIndex_
RepresentativeSwaptionMatcher(const std::vector< Leg > &underlying, const std::vector< bool > &isPayer, const QuantLib::ext::shared_ptr< SwapIndex > &standardSwapIndexBase, const bool useUnderlyingIborIndex, const Handle< YieldTermStructure > &discountCurve, const Real reversion, const Real volatility=0.0050, const Real flatRate=Null< Real >())
@ AccrualStartGeqExercise
QuantLib::Date valueDate(const QuantLib::Date &fixingDate, const QuantLib::ext::shared_ptr< QuantLib::FloatingRateCoupon > &cpn) const
adaptor to emulate piecewise constant Hull White parameters
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
coupon paying the compounded daily overnight rate, copy of QL class, added includeSpread flag
representative swaption matcher