67 {
68
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 "
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
83
84
85 Date referenceDate = npvCcyYts->referenceDate();
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
98
99
101 results_.valuationDate = referenceDate;
102 } else {
104 << ") cannot be before "
105 "discount curve reference date ("
106 << referenceDate << ")");
108 }
109
110
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 {
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
132 results_.errorEstimate = Null<Real>();
133
134
137 results_.inCcyLegNPV.resize(numLegs);
138 results_.inCcyLegBPS.resize(numLegs);
139 results_.startDiscounts.resize(numLegs);
140 results_.endDiscounts.resize(numLegs);
141
142 bool includeRefDateFlows =
144
146
147 for (Size i = 0; i < numLegs; ++i) {
148 try {
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
156 if (
results_.inCcyLegBPS[i] != Null<Real>()) {
158 }
159
160
161 Handle<Quote> fx =
fetchFX(ccy);
162
163 Real spotFXRate = fx->value();
164 if( spotFXSettleDateVec[i] != referenceDate ) {
165
166
167
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 }
175
176 if (
results_.inCcyLegBPS[i] != Null<Real>()) {
177
179 } else {
181 }
182
184
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_
Handle< Quote > fetchFX(Currency ccy) const
Handle< YieldTermStructure > fetchTS(Currency ccy) const
Swap::arguments * arguments_