Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
AnalyticLgmCdsOptionEngine Class Reference

#include <qle/pricingengines/analyticlgmcdsoptionengine.hpp>

+ Inheritance diagram for AnalyticLgmCdsOptionEngine:
+ Collaboration diagram for AnalyticLgmCdsOptionEngine:

Public Member Functions

 AnalyticLgmCdsOptionEngine (const QuantLib::ext::shared_ptr< CrossAssetModel > &model, const Size index, const Size ccy, const Real recoveryRate, const Handle< YieldTermStructure > &termStructure=Handle< YieldTermStructure >())
 
void calculate () const override
 

Private Member Functions

Real Ei (const Real w, const Real strike, const Size i) const
 
Real lambdaStarHelper (const Real lambda) const
 

Private Attributes

const QuantLib::ext::shared_ptr< CrossAssetModelmodel_
 
const Size index_
 
const Size ccy_
 
const Real recoveryRate_
 
const Handle< YieldTermStructure > termStructure_
 
Array G_
 
Array t_
 
Real tex_
 

Detailed Description

analytic lgm cds option engine

Reference: Modern Derivatives Pricing and Credit Exposure Analysis by Lichters, Stamm and Gallagher, 15.1

Definition at line 34 of file analyticlgmcdsoptionengine.hpp.

Constructor & Destructor Documentation

◆ AnalyticLgmCdsOptionEngine()

AnalyticLgmCdsOptionEngine ( const QuantLib::ext::shared_ptr< CrossAssetModel > &  model,
const Size  index,
const Size  ccy,
const Real  recoveryRate,
const Handle< YieldTermStructure > &  termStructure = Handle<YieldTermStructure>() 
)

Definition at line 28 of file analyticlgmcdsoptionengine.cpp.

31 : QuantExt::CdsOption::engine(), model_(model), index_(index), ccy_(ccy), recoveryRate_(recoveryRate),
32 termStructure_(termStructure) {
33 registerWith(model);
34 if (!termStructure.empty())
35 registerWith(termStructure);
36}
const QuantLib::ext::shared_ptr< CrossAssetModel > model_
const Handle< YieldTermStructure > termStructure_
base class for swaption engines
Definition: cdsoption.hpp:130

Member Function Documentation

◆ calculate()

void calculate ( ) const
override

Definition at line 38 of file analyticlgmcdsoptionengine.cpp.

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 =
46 termStructure_.empty() ? model_->irlgm1f(0)->termStructure() : termStructure_;
47
48 Real riskyAnnuity = std::fabs(arguments_.swap->couponLegNPV() / swapSpread);
49 results_.riskyAnnuity = riskyAnnuity;
50
51 // incorporate upfront amount
52
53 swapSpread -= w * arguments_.swap->upfrontNPV() / riskyAnnuity;
54
55 Size n = arguments_.swap->coupons().size();
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()) {
61 results_.value = 0.0;
62 return;
63 }
64
65 tex_ = yts->timeFromReference(arguments_.exercise->date(0));
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;
75 if (arguments_.swap->settlesAccrual()) {
76 Real accStartTime = i == 0 ? yts->timeFromReference(cpn->accrualStartDate()) : t_[i];
77 // mid > accStartTime practically always the case?
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 }
85 G_[0] = -C[0];
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 // if a non knock-out payer option, add front end protection value
92 Real frontEndProtection = 0.0;
93 if (arguments_.side == Protection::Buyer && !arguments_.knocksOut) {
94 frontEndProtection = arguments_.swap->notional() * (1. - recoveryRate_) *
95 model_->crlgm1f(index_)->termStructure()->defaultProbability(tex_) * yts->discount(tex_);
96 }
97
98 Brent b;
99 Real lambdaStar;
100 try {
101 lambdaStar = b.solve(QuantLib::ext::bind(&AnalyticLgmCdsOptionEngine::lambdaStarHelper, this, QuantLib::ext::placeholders::_1),
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
107 Real sum = 0.0;
108 for (Size i = 1; i < G_.size(); ++i) {
109 Real strike = model_->crlgm1fS(index_, ccy_, tex_, t_[i], lambdaStar, 0.0).second /
110 model_->crlgm1fS(index_, ccy_, tex_, t_[0], lambdaStar, 0.0).second;
111 sum += G_[i] * Ei(w, strike, i) * yts->discount(tex_);
112 }
113
114 results_.value = arguments_.swap->notional() * sum + frontEndProtection;
115
116} // calculate
const Instrument::results * results_
Definition: cdsoption.cpp:81
Real Ei(const Real w, const Real strike, const Size i) const
Real sum(const Cash &c, const Cash &d)
Definition: bondbasket.cpp:107
Swap::arguments * arguments_
+ Here is the call graph for this function:

◆ Ei()

Real Ei ( const Real  w,
const Real  strike,
const Size  i 
) const
private

Definition at line 118 of file analyticlgmcdsoptionengine.cpp.

118 {
119 Real pS = model_->crlgm1f(index_)->termStructure()->survivalProbability(t_[0]);
120 Real pT = model_->crlgm1f(index_)->termStructure()->survivalProbability(t_[i]);
121 // slight generalization of Lichters, Stamm, Gallagher 11.2.1
122 // with t < S, SSRN: https://ssrn.com/abstract=2246054
123 Real sigma = sqrt(model_->crlgm1f(index_)->zeta(tex_)) *
124 (model_->crlgm1f(index_)->H(t_[i]) - model_->crlgm1f(index_)->H(t_[0]));
125 Real dp = (std::log(pT / (strike * pS)) / sigma + 0.5 * sigma);
126 Real dm = dp - sigma;
127 CumulativeNormalDistribution N;
128 return w * (pT * N(w * dp) - pS * strike * N(w * dm));
129}
RandomVariable sqrt(RandomVariable x)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ lambdaStarHelper()

Real lambdaStarHelper ( const Real  lambda) const
private

Definition at line 131 of file analyticlgmcdsoptionengine.cpp.

131 {
132 Real sum = 0.0;
133 for (Size i = 0; i < G_.size(); ++i) {
134 Real S = model_->crlgm1fS(index_, ccy_, tex_, t_[i], lambda, 0.0).second /
135 model_->crlgm1fS(index_, ccy_, tex_, t_[0], lambda, 0.0).second;
136 sum += G_[i] * S;
137 }
138 return sum;
139}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ model_

const QuantLib::ext::shared_ptr<CrossAssetModel> model_
private

Definition at line 44 of file analyticlgmcdsoptionengine.hpp.

◆ index_

const Size index_
private

Definition at line 45 of file analyticlgmcdsoptionengine.hpp.

◆ ccy_

const Size ccy_
private

Definition at line 45 of file analyticlgmcdsoptionengine.hpp.

◆ recoveryRate_

const Real recoveryRate_
private

Definition at line 46 of file analyticlgmcdsoptionengine.hpp.

◆ termStructure_

const Handle<YieldTermStructure> termStructure_
private

Definition at line 47 of file analyticlgmcdsoptionengine.hpp.

◆ G_

Array G_
mutableprivate

Definition at line 48 of file analyticlgmcdsoptionengine.hpp.

◆ t_

Array t_
private

Definition at line 48 of file analyticlgmcdsoptionengine.hpp.

◆ tex_

Real tex_
mutableprivate

Definition at line 49 of file analyticlgmcdsoptionengine.hpp.