21#include <ql/cashflows/cashflows.hpp>
22#include <ql/cashflows/floatingratecoupon.hpp>
23#include <ql/exchangerate.hpp>
24#include <ql/utilities/dataformatters.hpp>
26#include <ql/cashflows/cashflows.hpp>
27#include <ql/errors.hpp>
32 const std::vector<Handle<YieldTermStructure> >& discountCurves,
const std::vector<Handle<Quote> >& fxQuotes,
33 const std::vector<Currency>& currencies,
const Currency& npvCurrency,
34 boost::optional<bool> includeSettlementDateFlows, Date settlementDate, Date npvDate,
35 const std::vector<Date>& spotFXSettleDateVec)
36 : discountCurves_(discountCurves), fxQuotes_(fxQuotes), currencies_(currencies), npvCurrency_(npvCurrency),
37 includeSettlementDateFlows_(includeSettlementDateFlows), settlementDate_(settlementDate), npvDate_(npvDate),
38 spotFXSettleDateVec_(spotFXSettleDateVec) {
41 "currencies does not match number of discount curves.");
43 "currencies does not match number of FX quotes.");
54 return Handle<YieldTermStructure>();
62 return Handle<Quote>();
69 Size numCurrencies =
arguments_.currency.size();
70 for (Size i = 0; i < numCurrencies; i++) {
72 Handle<YieldTermStructure> yts =
fetchTS(ccy);
73 QL_REQUIRE(!yts.empty(),
"Discounting term structure is "
76 Handle<Quote> fxQuote =
fetchFX(ccy);
77 QL_REQUIRE(!fxQuote.empty(),
"FX quote is empty "
85 Date referenceDate = npvCcyYts->referenceDate();
88 settlementDate = referenceDate;
90 QL_REQUIRE(settlementDate >= referenceDate,
"Settlement date (" << settlementDate
91 <<
") cannot be before discount curve "
93 << referenceDate <<
")");
101 results_.valuationDate = referenceDate;
104 <<
") cannot be before "
105 "discount curve reference date ("
106 << referenceDate <<
")");
112 if (spotFXSettleDateVec.size() == 0) {
113 spotFXSettleDateVec.resize(numCurrencies, referenceDate);
115 QL_REQUIRE(spotFXSettleDateVec.size() == numCurrencies,
"Number of "
116 "currencies does not match number of FX settlement dates.");
118 for (Size i = 0; i < numCurrencies; ++i) {
119 if (spotFXSettleDateVec[i] == Date()) {
120 spotFXSettleDateVec[i] = referenceDate;
123 QL_REQUIRE(spotFXSettleDateVec[i] >= referenceDate,
"FX settlement date (" << spotFXSettleDateVec[i]
124 <<
") for currency " << ccy <<
125 " cannot be before discount curve "
127 << referenceDate <<
")");
132 results_.errorEstimate = Null<Real>();
137 results_.inCcyLegNPV.resize(numLegs);
138 results_.inCcyLegBPS.resize(numLegs);
139 results_.startDiscounts.resize(numLegs);
140 results_.endDiscounts.resize(numLegs);
142 bool includeRefDateFlows =
147 for (Size i = 0; i < numLegs; ++i) {
150 Handle<YieldTermStructure> yts =
fetchTS(ccy);
152 std::tie(
results_.inCcyLegNPV[i],
results_.inCcyLegBPS[i]) = QuantLib::CashFlows::npvbps(
153 arguments_.legs[i], **yts, includeRefDateFlows, settlementDate,
results_.valuationDate);
156 if (
results_.inCcyLegBPS[i] != Null<Real>()) {
161 Handle<Quote> fx =
fetchFX(ccy);
163 Real spotFXRate = fx->value();
164 if( spotFXSettleDateVec[i] != referenceDate ) {
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;
176 if (
results_.inCcyLegBPS[i] != Null<Real>()) {
186 Date d1 = CashFlows::startDate(
arguments_.legs[i]);
187 if (d1 >= referenceDate)
188 results_.startDiscounts[i] = yts->discount(d1);
190 results_.startDiscounts[i] = Null<DiscountFactor>();
192 Date d2 = CashFlows::maturityDate(
arguments_.legs[i]);
193 if (d2 >= referenceDate)
194 results_.endDiscounts[i] = yts->discount(d2);
196 results_.endDiscounts[i] = Null<DiscountFactor>();
198 results_.startDiscounts[i] = Null<DiscountFactor>();
199 results_.endDiscounts[i] = Null<DiscountFactor>();
202 }
catch (std::exception& e) {
203 QL_FAIL(
"leg " << i <<
": " << e.what());
const Instrument::results * results_
Handle< Quote > fetchFX(Currency ccy) const
DiscountingCurrencySwapEngine(const std::vector< Handle< YieldTermStructure > > &discountCurves, const std::vector< Handle< Quote > > &fxQuotes, const std::vector< Currency > ¤cies, const Currency &npvCurrency, boost::optional< bool > includeSettlementDateFlows=boost::none, Date settlementDate=Date(), Date npvDate=Date(), const std::vector< Date > &spotFXSettleDateVec=std::vector< Date >())
Handle< YieldTermStructure > fetchTS(Currency ccy) const
std::vector< Date > spotFXSettleDateVec_
boost::optional< bool > includeSettlementDateFlows_
void calculate() const override
std::vector< Handle< YieldTermStructure > > discountCurves_
std::vector< Currency > currencies_
std::vector< Handle< Quote > > fxQuotes_
discounting currency swap engine
Swap::arguments * arguments_