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
DiscountingCurrencySwapEngine Class Reference

Discounting CurrencySwap Engine More...

#include <qle/pricingengines/discountingcurrencyswapengine.hpp>

+ Inheritance diagram for DiscountingCurrencySwapEngine:
+ Collaboration diagram for DiscountingCurrencySwapEngine:

Public Member Functions

 DiscountingCurrencySwapEngine (const std::vector< Handle< YieldTermStructure > > &discountCurves, const std::vector< Handle< Quote > > &fxQuotes, const std::vector< Currency > &currencies, const Currency &npvCurrency, boost::optional< bool > includeSettlementDateFlows=boost::none, Date settlementDate=Date(), Date npvDate=Date(), const std::vector< Date > &spotFXSettleDateVec=std::vector< Date >())
 
void calculate () const override
 
std::vector< Handle< YieldTermStructure > > discountCurves ()
 
std::vector< Currency > currencies ()
 
Currency npvCurrency ()
 

Private Member Functions

Handle< YieldTermStructure > fetchTS (Currency ccy) const
 
Handle< Quote > fetchFX (Currency ccy) const
 

Private Attributes

std::vector< Handle< YieldTermStructure > > discountCurves_
 
std::vector< Handle< Quote > > fxQuotes_
 
std::vector< Currency > currencies_
 
Currency npvCurrency_
 
boost::optional< boolincludeSettlementDateFlows_
 
Date settlementDate_
 
Date npvDate_
 
std::vector< Date > spotFXSettleDateVec_
 

Detailed Description

Discounting CurrencySwap Engine

This class generalizes QuantLib's DiscountingSwapEngine. It takes leg currencies into account and converts into the provided "npv currency", which must be one of the leg currencies. The evaluation date is the reference date of either of the discounting curves (which must be equal).

    \ingroup engines

Definition at line 46 of file discountingcurrencyswapengine.hpp.

Constructor & Destructor Documentation

◆ DiscountingCurrencySwapEngine()

DiscountingCurrencySwapEngine ( const std::vector< Handle< YieldTermStructure > > &  discountCurves,
const std::vector< Handle< Quote > > &  fxQuotes,
const std::vector< Currency > &  currencies,
const Currency &  npvCurrency,
boost::optional< bool includeSettlementDateFlows = boost::none,
Date  settlementDate = Date(),
Date  npvDate = Date(),
const std::vector< Date > &  spotFXSettleDateVec = std::vector<Date>() 
)

The FX spots must be given as units of npvCurrency per respective currency. The spots must be given w.r.t. a settlement date equal to the npv date.

Definition at line 31 of file discountingcurrencyswapengine.cpp.

37 includeSettlementDateFlows_(includeSettlementDateFlows), settlementDate_(settlementDate), npvDate_(npvDate),
38 spotFXSettleDateVec_(spotFXSettleDateVec) {
39
40 QL_REQUIRE(discountCurves_.size() == currencies_.size(), "Number of "
41 "currencies does not match number of discount curves.");
42 QL_REQUIRE(fxQuotes_.size() == currencies_.size(), "Number of "
43 "currencies does not match number of FX quotes.");
44
45 for (Size i = 0; i < discountCurves_.size(); i++) {
46 registerWith(discountCurves_[i]);
47 registerWith(fxQuotes_[i]);
48 }
49}
std::vector< Handle< YieldTermStructure > > discountCurves_
std::vector< Handle< YieldTermStructure > > discountCurves()

Member Function Documentation

◆ calculate()

void calculate ( ) const
override

Definition at line 67 of file discountingcurrencyswapengine.cpp.

67 {
68
69 Size numCurrencies = arguments_.currency.size();
70 for (Size i = 0; i < numCurrencies; i++) {
71 Currency ccy = arguments_.currency[i];
72 Handle<YieldTermStructure> yts = fetchTS(ccy);
73 QL_REQUIRE(!yts.empty(), "Discounting term structure is "
74 "empty for "
75 << ccy.name());
76 Handle<Quote> fxQuote = fetchFX(ccy);
77 QL_REQUIRE(!fxQuote.empty(), "FX quote is empty "
78 "for "
79 << ccy.name());
80 }
81
82 Handle<YieldTermStructure> npvCcyYts = fetchTS(npvCurrency_);
83
84 // Instrument settlement date
85 Date referenceDate = npvCcyYts->referenceDate();
86 Date settlementDate = settlementDate_;
87 if (settlementDate_ == Date()) {
88 settlementDate = referenceDate;
89 } else {
90 QL_REQUIRE(settlementDate >= referenceDate, "Settlement date (" << settlementDate
91 << ") cannot be before discount curve "
92 "reference date ("
93 << referenceDate << ")");
94 }
95
96 // Prepare the results containers
97 Size numLegs = arguments_.legs.size();
98
99 // - Instrument::results
100 if (npvDate_ == Date()) {
101 results_.valuationDate = referenceDate;
102 } else {
103 QL_REQUIRE(npvDate_ >= referenceDate, "NPV date (" << npvDate_
104 << ") cannot be before "
105 "discount curve reference date ("
106 << referenceDate << ")");
107 results_.valuationDate = npvDate_;
108 }
109
110 //check spotFXSettleDateVec_
111 std::vector<Date> spotFXSettleDateVec = spotFXSettleDateVec_;
112 if (spotFXSettleDateVec.size() == 0) {
113 spotFXSettleDateVec.resize(numCurrencies, referenceDate);
114 } else {
115 QL_REQUIRE(spotFXSettleDateVec.size() == numCurrencies, "Number of "
116 "currencies does not match number of FX settlement dates.");
117 }
118 for (Size i = 0; i < numCurrencies; ++i) {
119 if (spotFXSettleDateVec[i] == Date()) {
120 spotFXSettleDateVec[i] = referenceDate;
121 } else {
122 Currency ccy = arguments_.currency[i];
123 QL_REQUIRE(spotFXSettleDateVec[i] >= referenceDate, "FX settlement date (" << spotFXSettleDateVec[i]
124 << ") for currency " << ccy <<
125 " cannot be before discount curve "
126 "reference date ("
127 << referenceDate << ")");
128 }
129 }
130
131 results_.value = 0.0;
132 results_.errorEstimate = Null<Real>();
133
134 // - CurrencySwap::results
135 results_.legNPV.resize(numLegs);
136 results_.legBPS.resize(numLegs);
137 results_.inCcyLegNPV.resize(numLegs);
138 results_.inCcyLegBPS.resize(numLegs);
139 results_.startDiscounts.resize(numLegs);
140 results_.endDiscounts.resize(numLegs);
141
142 bool includeRefDateFlows =
143 includeSettlementDateFlows_ ? *includeSettlementDateFlows_ : Settings::instance().includeReferenceDateEvents();
144
145 results_.npvDateDiscount = npvCcyYts->discount(results_.valuationDate);
146
147 for (Size i = 0; i < numLegs; ++i) {
148 try {
149 Currency ccy = arguments_.currency[i];
150 Handle<YieldTermStructure> yts = fetchTS(ccy);
151
152 std::tie(results_.inCcyLegNPV[i], results_.inCcyLegBPS[i]) = QuantLib::CashFlows::npvbps(
153 arguments_.legs[i], **yts, includeRefDateFlows, settlementDate, results_.valuationDate);
154
155 results_.inCcyLegNPV[i] *= arguments_.payer[i];
156 if (results_.inCcyLegBPS[i] != Null<Real>()) {
157 results_.inCcyLegBPS[i] *= arguments_.payer[i];
158 }
159
160 // Converts into base currency and adds.
161 Handle<Quote> fx = fetchFX(ccy);
162 //results_.legNPV[i] = results_.inCcyLegNPV[i] * fx->value();
163 Real spotFXRate = fx->value();
164 if( spotFXSettleDateVec[i] != referenceDate ) {
165 // Use the parity relation between discount factors and fx rates to compute spotFXRate
166 // Generic formula: fx(T1)/fx(T2) = FwdDF_Quote(T1->T2) / FwdDF_Base(T1->T2),
167 // where fx represents the currency ratio Base/Quote
168 Real npvCcyDF = npvCcyYts->discount(spotFXSettleDateVec[i]);
169 Real ccyDF = yts->discount(spotFXSettleDateVec[i]);
170 QL_REQUIRE(ccyDF != 0.0, "Discount Factor associated with currency " << ccy
171 << " at maturity " << spotFXSettleDateVec[i] << " cannot be zero");
172 spotFXRate *= npvCcyDF / ccyDF;
173 }
174 results_.legNPV[i] = results_.inCcyLegNPV[i] * spotFXRate;
175
176 if (results_.inCcyLegBPS[i] != Null<Real>()) {
177 //results_.legBPS[i] = results_.inCcyLegBPS[i] * fx->value();
178 results_.legBPS[i] = results_.inCcyLegBPS[i] * spotFXRate;
179 } else {
180 results_.legBPS[i] = Null<Real>();
181 }
182
183 results_.value += results_.legNPV[i];
184
185 if (!arguments_.legs[i].empty()) {
186 Date d1 = CashFlows::startDate(arguments_.legs[i]);
187 if (d1 >= referenceDate)
188 results_.startDiscounts[i] = yts->discount(d1);
189 else
190 results_.startDiscounts[i] = Null<DiscountFactor>();
191
192 Date d2 = CashFlows::maturityDate(arguments_.legs[i]);
193 if (d2 >= referenceDate)
194 results_.endDiscounts[i] = yts->discount(d2);
195 else
196 results_.endDiscounts[i] = Null<DiscountFactor>();
197 } else {
198 results_.startDiscounts[i] = Null<DiscountFactor>();
199 results_.endDiscounts[i] = Null<DiscountFactor>();
200 }
201
202 } catch (std::exception& e) {
203 QL_FAIL("leg " << i << ": " << e.what());
204 }
205 }
206}
const Instrument::results * results_
Definition: cdsoption.cpp:81
Handle< YieldTermStructure > fetchTS(Currency ccy) const
Swap::arguments * arguments_
+ Here is the call graph for this function:

◆ discountCurves()

std::vector< Handle< YieldTermStructure > > discountCurves ( )

Definition at line 58 of file discountingcurrencyswapengine.hpp.

58{ return discountCurves_; }

◆ currencies()

std::vector< Currency > currencies ( )

Definition at line 59 of file discountingcurrencyswapengine.hpp.

59{ return currencies_; }

◆ npvCurrency()

Currency npvCurrency ( )

Definition at line 60 of file discountingcurrencyswapengine.hpp.

60{ return npvCurrency_; }

◆ fetchTS()

Handle< YieldTermStructure > fetchTS ( Currency  ccy) const
private

Definition at line 51 of file discountingcurrencyswapengine.cpp.

51 {
52 std::vector<Currency>::const_iterator i = std::find(currencies_.begin(), currencies_.end(), ccy);
53 if (i == currencies_.end())
54 return Handle<YieldTermStructure>();
55 else
56 return discountCurves_[i - currencies_.begin()];
57}
+ Here is the caller graph for this function:

◆ fetchFX()

Handle< Quote > fetchFX ( Currency  ccy) const
private

Definition at line 59 of file discountingcurrencyswapengine.cpp.

59 {
60 std::vector<Currency>::const_iterator i = std::find(currencies_.begin(), currencies_.end(), ccy);
61 if (i == currencies_.end())
62 return Handle<Quote>();
63 else
64 return fxQuotes_[i - currencies_.begin()];
65}
+ Here is the caller graph for this function:

Member Data Documentation

◆ discountCurves_

std::vector<Handle<YieldTermStructure> > discountCurves_
private

Definition at line 66 of file discountingcurrencyswapengine.hpp.

◆ fxQuotes_

std::vector<Handle<Quote> > fxQuotes_
private

Definition at line 67 of file discountingcurrencyswapengine.hpp.

◆ currencies_

std::vector<Currency> currencies_
private

Definition at line 68 of file discountingcurrencyswapengine.hpp.

◆ npvCurrency_

Currency npvCurrency_
private

Definition at line 69 of file discountingcurrencyswapengine.hpp.

◆ includeSettlementDateFlows_

boost::optional<bool> includeSettlementDateFlows_
private

Definition at line 70 of file discountingcurrencyswapengine.hpp.

◆ settlementDate_

Date settlementDate_
private

Definition at line 71 of file discountingcurrencyswapengine.hpp.

◆ npvDate_

Date npvDate_
private

Definition at line 72 of file discountingcurrencyswapengine.hpp.

◆ spotFXSettleDateVec_

std::vector<Date> spotFXSettleDateVec_
private

Definition at line 73 of file discountingcurrencyswapengine.hpp.