19#include <ql/cashflows/cashflows.hpp>
20#include <ql/exchangerate.hpp>
21#include <ql/utilities/dataformatters.hpp>
28 const Currency& ccy2,
const Handle<YieldTermStructure>& currency2Discountcurve,
29 const Handle<Quote>& spotFX, boost::optional<bool> includeSettlementDateFlows,
30 const Date& settlementDate,
const Date& npvDate,
const Date& spotFXSettleDate)
31 : ccy1_(ccy1), currency1Discountcurve_(currency1Discountcurve), ccy2_(ccy2),
32 currency2Discountcurve_(currency2Discountcurve), spotFX_(spotFX),
33 includeSettlementDateFlows_(includeSettlementDateFlows), settlementDate_(settlementDate), npvDate_(npvDate),
34 spotFXSettleDate_(spotFXSettleDate) {
44 "Discounting term structure handle is empty.");
46 QL_REQUIRE(!
spotFX_.empty(),
"FX spot quote handle is empty.");
49 "Term structures should have the same reference date.");
53 settlementDate = referenceDate;
55 QL_REQUIRE(settlementDate >= referenceDate,
"Settlement date (" << settlementDate
56 <<
") cannot be before discount curve "
58 << referenceDate <<
")");
64 results_.valuationDate = referenceDate;
67 <<
") cannot be before "
68 "discount curve reference date ("
69 << referenceDate <<
")");
75 spotFXSettleDate = referenceDate;
77 QL_REQUIRE(spotFXSettleDate >= referenceDate,
"FX settlement date (" << spotFXSettleDate
78 <<
") cannot be before discount curve "
80 << referenceDate <<
")");
84 results_.errorEstimate = Null<Real>();
88 results_.startDiscounts.resize(numLegs);
89 results_.endDiscounts.resize(numLegs);
91 results_.inCcyLegNPV.resize(numLegs);
92 results_.inCcyLegBPS.resize(numLegs);
93 results_.npvDateDiscounts.resize(numLegs);
95 bool includeReferenceDateFlows =
98 for (Size legNo = 0; legNo < numLegs; legNo++) {
101 Handle<YieldTermStructure> legDiscountCurve;
106 <<
") must be ccy1 (" <<
ccy1_
107 <<
") or ccy2 (" <<
ccy2_ <<
")");
110 results_.npvDateDiscounts[legNo] = legDiscountCurve->discount(
results_.valuationDate);
114 CashFlows::npvbps(
arguments_.legs[legNo], **legDiscountCurve, includeReferenceDateFlows, settlementDate,
126 Real spotFXRate =
spotFX_->value();
127 if (spotFXSettleDate != referenceDate) {
133 QL_REQUIRE(ccy2DF != 0.0,
"Discount Factor associated with currency " <<
ccy2_
134 <<
" at maturity " << spotFXSettleDate <<
" cannot be zero");
135 spotFXRate *= ccy1DF / ccy2DF;
137 results_.legNPV[legNo] *= spotFXRate;
138 results_.legBPS[legNo] *= spotFXRate;
142 Date startDate = CashFlows::startDate(
arguments_.legs[legNo]);
144 results_.startDiscounts[legNo] = legDiscountCurve->discount(startDate);
146 results_.startDiscounts[legNo] = Null<DiscountFactor>();
149 Date maturityDate = CashFlows::maturityDate(
arguments_.legs[legNo]);
151 results_.endDiscounts[legNo] = legDiscountCurve->discount(maturityDate);
153 results_.endDiscounts[legNo] = Null<DiscountFactor>();
156 }
catch (std::exception& e) {
157 QL_FAIL(io::ordinal(legNo + 1) <<
" leg: " << e.what());
const Instrument::results * results_
boost::optional< bool > includeSettlementDateFlows_
void calculate() const override
CrossCcySwapEngine(const Currency &ccy1, const Handle< YieldTermStructure > ¤cy1DiscountCurve, const Currency &ccy2, const Handle< YieldTermStructure > ¤cy2DiscountCurve, const Handle< Quote > &spotFX, boost::optional< bool > includeSettlementDateFlows=boost::none, const Date &settlementDate=Date(), const Date &npvDate=Date(), const Date &spotFXSettleDate=Date())
Handle< YieldTermStructure > currency2Discountcurve_
Handle< YieldTermStructure > currency1Discountcurve_
Cross currency swap engine.
Swap::arguments * arguments_