41 {
42
44 "Discounting term structure handle is empty.");
45
46 QL_REQUIRE(!
spotFX_.empty(),
"FX spot quote handle is empty.");
47
49 "Term structures should have the same reference date.");
53 settlementDate = referenceDate;
54 } else {
55 QL_REQUIRE(settlementDate >= referenceDate, "Settlement date (" << settlementDate
56 << ") cannot be before discount curve "
57 "reference date ("
58 << referenceDate << ")");
59 }
60
62
64 results_.valuationDate = referenceDate;
65 } else {
67 << ") cannot be before "
68 "discount curve reference date ("
69 << referenceDate << ")");
71 }
72
75 spotFXSettleDate = referenceDate;
76 } else {
77 QL_REQUIRE(spotFXSettleDate >= referenceDate, "FX settlement date (" << spotFXSettleDate
78 << ") cannot be before discount curve "
79 "reference date ("
80 << referenceDate << ")");
81 }
82
84 results_.errorEstimate = Null<Real>();
85
88 results_.startDiscounts.resize(numLegs);
89 results_.endDiscounts.resize(numLegs);
90
91 results_.inCcyLegNPV.resize(numLegs);
92 results_.inCcyLegBPS.resize(numLegs);
93 results_.npvDateDiscounts.resize(numLegs);
94
95 bool includeReferenceDateFlows =
97
98 for (Size legNo = 0; legNo < numLegs; legNo++) {
99 try {
100
101 Handle<YieldTermStructure> legDiscountCurve;
104 } else {
106 <<
") must be ccy1 (" <<
ccy1_
107 <<
") or ccy2 (" <<
ccy2_ <<
")");
109 }
110 results_.npvDateDiscounts[legNo] = legDiscountCurve->discount(
results_.valuationDate);
111
112
114 CashFlows::npvbps(
arguments_.legs[legNo], **legDiscountCurve, includeReferenceDateFlows, settlementDate,
118
121
122
124
125
126 Real spotFXRate =
spotFX_->value();
127 if (spotFXSettleDate != referenceDate) {
128
129
130
133 QL_REQUIRE(ccy2DF != 0.0,
"Discount Factor associated with currency " <<
ccy2_
134 << " at maturity " << spotFXSettleDate << " cannot be zero");
135 spotFXRate *= ccy1DF / ccy2DF;
136 }
137 results_.legNPV[legNo] *= spotFXRate;
138 results_.legBPS[legNo] *= spotFXRate;
139 }
140
141
142 Date startDate = CashFlows::startDate(
arguments_.legs[legNo]);
144 results_.startDiscounts[legNo] = legDiscountCurve->discount(startDate);
145 } else {
146 results_.startDiscounts[legNo] = Null<DiscountFactor>();
147 }
148
149 Date maturityDate = CashFlows::maturityDate(
arguments_.legs[legNo]);
151 results_.endDiscounts[legNo] = legDiscountCurve->discount(maturityDate);
152 } else {
153 results_.endDiscounts[legNo] = Null<DiscountFactor>();
154 }
155
156 } catch (std::exception& e) {
157 QL_FAIL(io::ordinal(legNo + 1) << " leg: " << e.what());
158 }
159
161 }
162}
const Instrument::results * results_
Swap::arguments * arguments_