56 {
57
58
59
60 if (optionDate <= valuationDate)
61 return QuantLib::ext::make_shared<LinearAnnuityMapping>(0.0, 0.0);
62
63
64
65 if (
a_ != Null<Real>() &&
b_ != Null<Real>()) {
66 return QuantLib::ext::make_shared<LinearAnnuityMapping>(
a_,
b_);
68 Real atmForward = underlying.fairRate();
69 Real gx = 0.0, gy = 0.0;
70 for (Size i = 0; i < underlying.fixedLeg().size(); i++) {
71 QuantLib::ext::shared_ptr<Coupon> c = QuantLib::ext::dynamic_pointer_cast<Coupon>(underlying.fixedLeg()[i]);
72 Real yf = c->accrualPeriod();
73 Real pv = yf * discountCurve->discount(c->date());
74 gx += pv * GsrG(discountCurve->dayCounter().yearFraction(optionDate, c->date()),
reversion_->value());
75 gy += pv;
76 }
77 Real gamma = gx / gy;
78 Date lastd = underlying.fixedLeg().back()->date();
79 Real a =
80 discountCurve->discount(paymentDate) *
81 (gamma - GsrG(discountCurve->dayCounter().yearFraction(optionDate, paymentDate),
reversion_->value())) /
82 (discountCurve->discount(lastd) *
83 GsrG(discountCurve->dayCounter().yearFraction(optionDate, lastd),
reversion_->value()) +
84 atmForward * gy * gamma);
85 Real b = discountCurve->discount(paymentDate) / gy - a * atmForward;
86 return QuantLib::ext::make_shared<LinearAnnuityMapping>(a, b);
87 } else {
88 QL_FAIL("LinearAnnuityMapping::build(): failed, because neither a, b nor a reversion is given");
89 }
90}