38 {
39
40 QL_REQUIRE(
arguments_.swap->protectionPaymentTime() == CreditDefaultSwap::ProtectionPaymentTime::atDefault,
41 "AnalyticLgmCdsOptionEngine: protection payment time must be atDefault");
42
43 Real w = (
arguments_.side == Protection::Buyer) ? -1.0 : 1.0;
44 Rate swapSpread =
arguments_.swap->runningSpread();
45 const Handle<YieldTermStructure>& yts =
47
48 Real riskyAnnuity = std::fabs(
arguments_.swap->couponLegNPV() / swapSpread);
49 results_.riskyAnnuity = riskyAnnuity;
50
51
52
53 swapSpread -= w *
arguments_.swap->upfrontNPV() / riskyAnnuity;
54
56 t_ = Array(n + 1, 0.0);
57 G_ = Array(n + 1, 0.0);
58 Array C(n, 0.0), D(n, 0.0);
59
60 if (
arguments_.exercise->date(0) <= yts->referenceDate()) {
62 return;
63 }
64
66 t_[0] = std::max(
tex_, yts->timeFromReference(
arguments_.swap->protectionStartDate()));
67
68 Real accrualSettlementAmount = 0.0;
69 for (Size i = 0; i < n; ++i) {
70 QuantLib::ext::shared_ptr<FixedRateCoupon> cpn =
71 QuantLib::ext::dynamic_pointer_cast<FixedRateCoupon>(
arguments_.swap->coupons()[i]);
72 QL_REQUIRE(cpn != NULL, "AnalyticLgmCdsOptionEngine: expected fixed rate coupon");
73 t_[i + 1] = yts->timeFromReference(cpn->date());
74 Real mid = (
t_[i] +
t_[i + 1]) / 2.0;
76 Real accStartTime = i == 0 ? yts->timeFromReference(cpn->accrualStartDate()) :
t_[i];
77
78 accrualSettlementAmount = mid > accStartTime ? swapSpread * cpn->accrualPeriod() * (mid - accStartTime) /
79 (
t_[i + 1] - accStartTime)
80 : 0.0;
81 }
82 C[i] = ((1.0 -
recoveryRate_) - accrualSettlementAmount) * yts->discount(mid) / yts->discount(
tex_);
83 D[i] = swapSpread * cpn->accrualPeriod() * yts->discount(
t_[i + 1]) / yts->discount(
tex_);
84 }
86 for (Size i = 0; i < n - 1; ++i) {
87 G_[i + 1] = C[i] + D[i] - C[i + 1];
88 }
89 G_[n] = C[n - 1] + D[n - 1];
90
91
92 Real frontEndProtection = 0.0;
96 }
97
98 Brent b;
99 Real lambdaStar;
100 try {
102 1.0E-6, 0.0, 0.01);
103 } catch (const std::exception& e) {
104 QL_FAIL("AnalyticLgmCdsOptionEngine, failed to compute lambdaStar, " << e.what());
105 }
106
108 for (Size i = 1; i <
G_.size(); ++i) {
111 sum +=
G_[i] *
Ei(w, strike, i) * yts->discount(
tex_);
112 }
113
115
116}
const Instrument::results * results_
Real Ei(const Real w, const Real strike, const Size i) const
Real lambdaStarHelper(const Real lambda) const
Real sum(const Cash &c, const Cash &d)
Swap::arguments * arguments_