18#include <ql/cashflows/iborcoupon.hpp>
19#include <ql/utilities/null_deleter.hpp>
24#include <boost/make_shared.hpp>
29 const Handle<Quote>& spreadQuote,
const Handle<Quote>& spotFX, Natural settlementDays,
30 const Calendar& settlementCalendar,
const Period& swapTenor, BusinessDayConvention rollConvention,
31 const QuantLib::ext::shared_ptr<QuantLib::IborIndex>& flatIndex,
const QuantLib::ext::shared_ptr<QuantLib::IborIndex>& spreadIndex,
32 const Handle<YieldTermStructure>& flatDiscountCurve,
const Handle<YieldTermStructure>& spreadDiscountCurve,
33 bool eom,
bool flatIsDomestic, boost::optional<Period> flatTenor, boost::optional<Period> spreadTenor,
34 Real spreadOnFlatLeg, Real flatGearing, Real spreadGearing,
const Calendar& flatCalendar,
35 const Calendar& spreadCalendar,
const std::vector<Natural>& spotFXSettleDaysVec,
36 const std::vector<Calendar>& spotFXSettleCalendarVec, Size paymentLag, Size flatPaymentLag,
37 boost::optional<bool> includeSpread, boost::optional<Period> lookback, boost::optional<Size> fixingDays,
38 boost::optional<Size> rateCutoff, boost::optional<bool> isAveraged, boost::optional<bool> flatIncludeSpread,
39 boost::optional<Period> flatLookback, boost::optional<Size> flatFixingDays, boost::optional<Size> flatRateCutoff,
40 boost::optional<bool> flatIsAveraged,
const bool telescopicValueDates)
42 settlementCalendar_(settlementCalendar), swapTenor_(swapTenor), rollConvention_(rollConvention),
43 flatIndex_(flatIndex), spreadIndex_(spreadIndex), flatDiscountCurve_(flatDiscountCurve),
44 spreadDiscountCurve_(spreadDiscountCurve), eom_(eom), flatIsDomestic_(flatIsDomestic),
45 flatTenor_(flatTenor ? *flatTenor : flatIndex_->tenor()),
46 spreadTenor_(spreadTenor ? *spreadTenor : spreadIndex_->tenor()), spreadOnFlatLeg_(spreadOnFlatLeg),
47 flatGearing_(flatGearing), spreadGearing_(spreadGearing), flatCalendar_(flatCalendar),
48 spreadCalendar_(spreadCalendar), spotFXSettleDaysVec_(spotFXSettleDaysVec),
49 spotFXSettleCalendarVec_(spotFXSettleCalendarVec), paymentLag_(paymentLag), flatPaymentLag_(flatPaymentLag),
50 includeSpread_(includeSpread), lookback_(lookback), fixingDays_(fixingDays), rateCutoff_(rateCutoff),
51 isAveraged_(isAveraged), flatIncludeSpread_(flatIncludeSpread), flatLookback_(flatLookback),
52 flatFixingDays_(flatFixingDays), flatRateCutoff_(flatRateCutoff), flatIsAveraged_(flatIsAveraged),
53 telescopicValueDates_(telescopicValueDates) {
58 bool flatIndexHasCurve = !
flatIndex_->forwardingTermStructure().empty();
59 bool spreadIndexHasCurve = !
spreadIndex_->forwardingTermStructure().empty();
63 QL_REQUIRE(!(flatIndexHasCurve && spreadIndexHasCurve && haveFlatDiscountCurve && haveSpreadDiscountCurve),
65 "nothing to solve for.");
75 "Array size of spot fx settlement days must equal that of spot fx settlement calendars");
76 if (numSpotFXSettleDays == 0) {
83 if (flatIndexHasCurve && haveFlatDiscountCurve) {
84 if (!spreadIndexHasCurve) {
88 }
else if (spreadIndexHasCurve && haveSpreadDiscountCurve) {
89 if (!flatIndexHasCurve) {
94 QL_FAIL(
"Need one leg of the cross currency basis swap to "
95 "have all of its curves.");
109 Date refDate = evaluationDate_;
115 Date maturityDate = settlementDate +
swapTenor_;
118 Date spotFXSettleDate = refDate;
120 for (Size i = 0; i < numSpotFXSettleDays; i++) {
125 Schedule flatLegSchedule = MakeSchedule()
126 .from(settlementDate)
133 Schedule spreadLegSchedule = MakeSchedule()
134 .from(settlementDate)
141 Real flatLegNominal = 1.0;
142 Real spreadLegNominal = 1.0;
144 flatLegNominal =
spotFX_->value();
146 spreadLegNominal =
spotFX_->value();
150 swap_ = QuantLib::ext::make_shared<CrossCcyBasisSwap>(
156 QuantLib::ext::shared_ptr<PricingEngine> engine;
166 swap_->setPricingEngine(engine);
168 earliestDate_ =
swap_->startDate();
169 latestDate_ =
swap_->maturityDate();
173 if (!IborCoupon::Settings::instance().usingAtParCoupons()) {
175 Size numCashflows =
swap_->leg(0).size();
176 if (numCashflows > 2) {
177 QuantLib::ext::shared_ptr<FloatingRateCoupon> lastFloating =
178 QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(
swap_->leg(0)[numCashflows - 2]);
179 Date fixingValueDate =
spreadIndex_->valueDate(lastFloating->fixingDate());
180 Date endValueDate =
spreadIndex_->maturityDate(fixingValueDate);
181 latestDate_ = std::max(latestDate_, endValueDate);
185 Size numCashflows =
swap_->leg(1).size();
186 if (numCashflows > 2) {
187 QuantLib::ext::shared_ptr<FloatingRateCoupon> lastFloating =
188 QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(
swap_->leg(1)[numCashflows - 2]);
189 Date fixingValueDate =
flatIndex_->valueDate(lastFloating->fixingDate());
190 Date endValueDate =
flatIndex_->maturityDate(fixingValueDate);
191 latestDate_ = std::max(latestDate_, endValueDate);
199 bool observer =
false;
200 QuantLib::ext::shared_ptr<YieldTermStructure> temp(t, null_deleter());
214 RelativeDateRateHelper::setTermStructure(t);
218 QL_REQUIRE(termStructure_,
"Term structure needs to be set");
220 return swap_->fairPaySpread();
224 Visitor<CrossCcyBasisSwapHelper>* v1 =
dynamic_cast<Visitor<CrossCcyBasisSwapHelper>*
>(&v);
228 RateHelper::accept(v);
RelinkableHandle< YieldTermStructure > spreadDiscountRLH_
void setTermStructure(YieldTermStructure *) override
bool telescopicValueDates_
boost::optional< bool > flatIncludeSpread_
CrossCcyBasisSwapHelper(const Handle< Quote > &spreadQuote, const Handle< Quote > &spotFX, Natural settlementDays, const Calendar &settlementCalendar, const Period &swapTenor, BusinessDayConvention rollConvention, const QuantLib::ext::shared_ptr< QuantLib::IborIndex > &flatIndex, const QuantLib::ext::shared_ptr< QuantLib::IborIndex > &spreadIndex, const Handle< YieldTermStructure > &flatDiscountCurve, const Handle< YieldTermStructure > &spreadDiscountCurve, bool eom=false, bool flatIsDomestic=true, boost::optional< QuantLib::Period > flatTenor=boost::none, boost::optional< QuantLib::Period > spreadTenor=boost::none, Real spreadOnFlatLeg=0.0, Real flatGearing=1.0, Real spreadGearing=1.0, const Calendar &flatCalendar=Calendar(), const Calendar &spreadCalendar=Calendar(), const std::vector< Natural > &spotFXSettleDaysVec=std::vector< Natural >(), const std::vector< Calendar > &spotFXSettleCalendar=std::vector< Calendar >(), Size paymentLag=0, Size flatPaymentLag=0, boost::optional< bool > includeSpread=boost::none, boost::optional< Period > lookback=boost::none, boost::optional< Size > fixingDays=boost::none, boost::optional< Size > rateCutoff=boost::none, boost::optional< bool > isAveraged=boost::none, boost::optional< bool > flatIncludeSpread=boost::none, boost::optional< Period > flatLookback=boost::none, boost::optional< Size > flatFixingDays=boost::none, boost::optional< Size > flatRateCutoff=boost::none, boost::optional< bool > flatIsAveraged=boost::none, const bool telescopicValueDates=false)
Currency flatLegCurrency_
std::vector< Natural > spotFXSettleDaysVec_
RelinkableHandle< YieldTermStructure > termStructureHandle_
boost::optional< QuantLib::Size > fixingDays_
boost::optional< QuantLib::Size > flatFixingDays_
boost::optional< QuantLib::Period > lookback_
RelinkableHandle< YieldTermStructure > flatDiscountRLH_
boost::optional< bool > isAveraged_
boost::optional< Size > flatRateCutoff_
void accept(AcyclicVisitor &) override
boost::optional< Size > rateCutoff_
Calendar settlementCalendar_
QuantLib::ext::shared_ptr< QuantLib::IborIndex > spreadIndex_
Currency spreadLegCurrency_
Handle< YieldTermStructure > spreadDiscountCurve_
QuantLib::Period flatTenor_
QuantLib::ext::shared_ptr< CrossCcyBasisSwap > swap_
void initializeDates() override
boost::optional< QuantLib::Period > flatLookback_
Real impliedQuote() const override
QuantLib::ext::shared_ptr< QuantLib::IborIndex > flatIndex_
Handle< YieldTermStructure > flatDiscountCurve_
BusinessDayConvention rollConvention_
boost::optional< bool > includeSpread_
boost::optional< bool > flatIsAveraged_
QuantLib::Period spreadTenor_
std::vector< Calendar > spotFXSettleCalendarVec_
Cross currency basis swap helper.
Cross currency swap engine.