39 ext::shared_ptr<IrregularSwap>
swap,
42 : swap_(
std::move(
swap)), termStructure_(
std::move(termStructure)),
43 volatilityStructure_(
std::move(volatilityStructure)) {
53 const Leg& fixedLeg =
swap_->fixedLeg();
54 const Leg& floatLeg =
swap_->floatingLeg();
56 Leg fixedCFS, floatCFS;
58 for (
Size i = 0; i < fixedLeg.size(); ++i) {
60 ext::shared_ptr<FixedRateCoupon> coupon =
61 ext::dynamic_pointer_cast<FixedRateCoupon>(fixedLeg[i]);
62 QL_REQUIRE(coupon,
"dynamic cast of fixed leg coupon failed.");
66 ext::shared_ptr<FixedRateCoupon> newCpn = ext::make_shared<FixedRateCoupon>(
67 coupon->date(), 1.0, coupon->rate(), coupon->dayCounter(),
68 coupon->accrualStartDate(), coupon->accrualEndDate(),
69 coupon->referencePeriodStart(), coupon->referencePeriodEnd());
71 fixedCFS.push_back(newCpn);
77 for (
const auto& j : floatLeg) {
79 ext::shared_ptr<IborCoupon> coupon = ext::dynamic_pointer_cast<IborCoupon>(j);
80 QL_REQUIRE(coupon,
"dynamic cast of float leg coupon failed.");
83 ext::shared_ptr<IborCoupon> newCpn = ext::make_shared<IborCoupon>(
84 coupon->date(), 1.0, coupon->accrualStartDate(), coupon->accrualEndDate(),
85 coupon->fixingDays(), coupon->iborIndex(), 1.0, coupon->spread(),
86 coupon->referencePeriodStart(), coupon->referencePeriodEnd(),
87 coupon->dayCounter(), coupon->isInArrears());
90 if (!newCpn->isInArrears())
94 floatCFS.push_back(newCpn);
112 Size n = swap_->fixedLeg().size();
122 ext::shared_ptr<FixedRateCoupon> cpn_r =
123 ext::dynamic_pointer_cast<FixedRateCoupon>(swap_->fixedLeg()[
r]);
124 QL_REQUIRE(cpn_r,
"Cast to fixed rate coupon failed.");
127 for (
Size c =
r; c <
n; ++c) {
130 arr[
r][c] = (fairRates_[c] + lambda_) * cpn_r->accrualPeriod();
139 ext::shared_ptr<FixedRateCoupon> cpn_r =
140 ext::dynamic_pointer_cast<FixedRateCoupon>(swap_->fixedLeg()[
r]);
143 Real N_r = cpn_r->nominal();
147 ext::shared_ptr<FixedRateCoupon> cpn_rp1 =
148 ext::dynamic_pointer_cast<FixedRateCoupon>(swap_->fixedLeg()[
r + 1]);
150 Real N_rp1 = cpn_rp1->nominal();
152 rhs[
r] = N_r * (cpn_r->rate()) * cpn_r->accrualPeriod() + (N_r - N_rp1);
156 rhs[
r] = N_r * (cpn_r->rate()) * cpn_r->accrualPeriod() + N_r;
169 Array weights = compute(lambda);
171 Real defect = -targetNPV_;
173 for (
Size i = 0; i < weights.
size(); ++i)
183 ext::shared_ptr<IborCoupon> iborCpn =
184 ext::dynamic_pointer_cast<IborCoupon>(swap_->floatingLeg()[0]);
185 QL_REQUIRE(iborCpn,
"dynamic cast of float leg coupon failed. Can't find index.");
186 ext::shared_ptr<IborIndex> iborIndex = iborCpn->iborIndex();
191 ext::shared_ptr<VanillaSwap> memberSwap_ =
202 Rate transformedRate = (fairRates_[i] + lambda_) *
annuities_[i] / stdAnnuity;
204 memberSwap_ =
MakeVanillaSwap(dummySwapLength, iborIndex, transformedRate)
243 Leg fixedLeg = swap_->fixedLeg();
246 Leg floatLeg = swap_->floatingLeg();
251 Leg floatCFS, fixedCFS;
255 for (
auto& j : floatLeg) {
257 ext::shared_ptr<IborCoupon> coupon = ext::dynamic_pointer_cast<IborCoupon>(j);
258 QL_REQUIRE(coupon,
"dynamic cast of float leg coupon failed.");
260 ext::shared_ptr<IborCoupon> newCpn = ext::make_shared<IborCoupon>(
261 coupon->date(), coupon->nominal(), coupon->accrualStartDate(),
262 coupon->accrualEndDate(), coupon->fixingDays(), coupon->iborIndex(),
263 coupon->gearing(), 0.0, coupon->referencePeriodStart(),
264 coupon->referencePeriodEnd(), coupon->dayCounter(), coupon->isInArrears());
267 if (!newCpn->isInArrears())
271 floatCFS.push_back(newCpn);
276 Rate avgSpread = sprdLgNPV / fltLgBPS / 10000;
278 Rate cpn_adjustment = avgSpread * fltLgBPS / fxdLgBPS;
282 for (
auto& i : fixedLeg) {
284 ext::shared_ptr<FixedRateCoupon> coupon = ext::dynamic_pointer_cast<FixedRateCoupon>(i);
285 QL_REQUIRE(coupon,
"dynamic cast of fixed leg coupon failed.");
287 ext::shared_ptr<FixedRateCoupon> newCpn = ext::make_shared<FixedRateCoupon>(
288 coupon->date(), coupon->nominal(), coupon->rate() - cpn_adjustment,
289 coupon->dayCounter(), coupon->accrualStartDate(), coupon->accrualEndDate(),
290 coupon->referencePeriodStart(), coupon->referencePeriodEnd());
292 fixedCFS.push_back(newCpn);
297 swap_ = ext::make_shared<IrregularSwap>(
arguments_.
swap->type(), fixedCFS, floatCFS);
311 Rate minLambda = -0.5;
312 Rate maxLambda = 0.5;
316 s1d.
solve(basket, 1.0e-8, 0.01, minLambda, maxLambda);
335 ext::shared_ptr<Exercise>& exercise)
const {
339 "swaptionEngine: only normal volatility implemented.");
342 ext::shared_ptr<PricingEngine> swaptionEngine = ext::shared_ptr<PricingEngine>(
351 for (
Size i = 0; i < weights.
size(); ++i) {
352 ext::shared_ptr<VanillaSwap> pvSwap_ = basket.
component(i);
355 npv += weights[i] * swaption.
NPV();
Black-formula swaption engine.
Cash-flow analysis functions.
1-D array used in linear algebra.
Size size() const
dimension of the array
Normal Bachelier-formula swaption engine.
static Real npv(const Leg &leg, const YieldTermStructure &discountCurve, bool includeSettlementDateFlows, Date settlementDate=Date(), Date npvDate=Date())
NPV of the cash flows.
static Real bps(const Leg &leg, const YieldTermStructure &discountCurve, bool includeSettlementDateFlows, Date settlementDate=Date(), Date npvDate=Date())
Basis-point sensitivity of the cash flows.
Discounting engine for swaps.
IrregularSwaption::results results_
IrregularSwaption::arguments arguments_
Basket(ext::shared_ptr< IrregularSwap > swap, Handle< YieldTermStructure > termStructure, Handle< SwaptionVolatilityStructure > volatilityStructure)
std::vector< Real > annuities_
std::vector< Real > fairRates_
ext::shared_ptr< IrregularSwap > swap_
std::vector< Date > expiries_
Array compute(Rate lambda=0.0) const
ext::shared_ptr< VanillaSwap > component(Size i) const
ext::shared_ptr< PricingEngine > engine_
Handle< YieldTermStructure > termStructure_
Real operator()(Rate x) const
void calculate() const override
Real HKPrice(Basket &basket, ext::shared_ptr< Exercise > &exercise) const
Handle< SwaptionVolatilityStructure > volatilityStructure_
Handle< YieldTermStructure > termStructure_
HaganIrregularSwaptionEngine(Handle< SwaptionVolatilityStructure >, Handle< YieldTermStructure > termStructure=Handle< YieldTermStructure >())
Shared handle to an observable.
Real NPV() const
returns the net present value of the instrument.
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
ext::shared_ptr< IrregularSwap > swap
MakeVanillaSwap & withEffectiveDate(const Date &)
MakeVanillaSwap & withTerminationDate(const Date &)
MakeVanillaSwap & withDiscountingTermStructure(const Handle< YieldTermStructure > &discountCurve)
MakeVanillaSwap & withRule(DateGeneration::Rule r)
MakeVanillaSwap & withType(Swap::Type type)
Matrix used in linear algebra.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
ext::shared_ptr< Exercise > exercise
Singular value decomposition.
Array solveFor(const Array &) const
void setMaxEvaluations(Size evaluations)
void setLowerBound(Real lowerBound)
sets the lower bound for the function domain
Real solve(const F &f, Real accuracy, Real guess, Real step) const
void setUpperBound(Real upperBound)
sets the upper bound for the function domain
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Option exercise classes and payoff function.
QL_INTEGER Integer
integer number
std::size_t Size
size of a container
engine for pricing irregular swaptions via super-replication
linear interpolation between discrete points
void swap(Array &v, Array &w) noexcept
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
normal, cumulative and inverse cumulative distributions
const ParametricExercise & exercise_
ext::shared_ptr< YieldTermStructure > r
singular value decomposition
const std::vector< Real > & expiries_
const std::vector< Real > & annuities_