32 Schedule legSchedule(
const Date& evaluationDate,
34 const Period& frequency,
36 const Calendar& calendar,
40 "XCCY instrument tenor should not be smaller than coupon frequency.");
42 Date referenceDate = calendar.adjust(evaluationDate);
43 Date earliestDate = calendar.advance(referenceDate, fixingDays *
Days, convention);
44 Date maturity = earliestDate + tenor;
49 .withCalendar(calendar)
50 .withConvention(convention)
51 .endOfMonth(endOfMonth)
55 Leg buildFloatingLeg(
const Date& evaluationDate,
58 const Calendar& calendar,
61 const ext::shared_ptr<IborIndex>& idx,
64 auto overnightIndex = ext::dynamic_pointer_cast<OvernightIndex>(idx);
68 QL_REQUIRE(!overnightIndex,
"Require payment frequency for overnight indices.");
69 freqPeriod = idx->tenor();
71 freqPeriod = Period(paymentFrequency);
74 Schedule sch = legSchedule(evaluationDate, tenor, freqPeriod, fixingDays, calendar,
75 convention, endOfMonth);
76 if (overnightIndex !=
nullptr) {
77 return OvernightLeg(sch, overnightIndex)
79 .withPaymentLag(paymentLag);
81 return IborLeg(sch, idx).withNotionals(1.0).withPaymentLag(paymentLag);
85 npvbpsConstNotionalLeg(
const Leg& iborLeg,
86 const Date& initialNotionalExchangeDate,
87 const Date& finalNotionalExchangeDate,
88 const Handle<YieldTermStructure>& discountCurveHandle) {
89 const Spread basisPoint = 1.0e-4;
90 Date refDt = discountCurveHandle->referenceDate();
91 const YieldTermStructure& discountRef = **discountCurveHandle;
92 bool includeSettleDtFlows =
true;
93 auto [npv, bps] =
CashFlows::npvbps(iborLeg, discountRef, includeSettleDtFlows, refDt, refDt);
95 npv += (-1.0) * discountRef.discount(initialNotionalExchangeDate);
96 npv += discountRef.discount(finalNotionalExchangeDate);
101 class ResettingLegHelper {
103 explicit ResettingLegHelper(
const YieldTermStructure& discountCurve,
104 const YieldTermStructure& foreignCurve)
109 Real notionalAdjustment(
const Date&
d)
const {
118 class ResettingLegCalculator :
public AcyclicVisitor,
public Visitor<Coupon> {
120 explicit ResettingLegCalculator(
const YieldTermStructure& discountCurve,
121 const YieldTermStructure& foreignCurve,
123 Calendar paymentCalendar,
128 void visit(Coupon& c)
override {
129 Date start = c.accrualStartDate();
130 Date end = c.accrualEndDate();
131 Time accrual = c.accrualPeriod();
132 Real adjustedNotional = c.nominal() *
helper_.notionalAdjustment(start);
136 if (paymentLag_ == 0) {
137 discountStart =
helper_.discount(start);
138 discountEnd =
helper_.discount(end);
143 discountStart =
helper_.discount(paymentStart);
144 discountEnd =
helper_.discount(paymentEnd);
152 Real npvRedeemedAmount =
153 adjustedNotional * discountEnd * (1.0 + c.rate() * accrual);
154 Real npvBorrowedAmount = -adjustedNotional * discountStart;
156 npv_ += (npvRedeemedAmount + npvBorrowedAmount);
157 bps_ += adjustedNotional * discountEnd * accrual;
171 std::pair<Real, Real> npvbpsResettingLeg(
const Leg& iborLeg,
173 const Calendar& paymentCalendar,
175 const Handle<YieldTermStructure>& discountCurveHandle,
176 const Handle<YieldTermStructure>& foreignCurveHandle) {
177 const YieldTermStructure& discountCurveRef = **discountCurveHandle;
178 const YieldTermStructure& foreignCurveRef = **foreignCurveHandle;
180 ResettingLegCalculator calc(discountCurveRef, foreignCurveRef, paymentLag,
181 paymentCalendar, convention);
182 for (
const auto& i : iborLeg) {
186 return { calc.NPV(), calc.BPS() };
197 ext::shared_ptr<IborIndex> baseCurrencyIndex,
198 ext::shared_ptr<IborIndex> quoteCurrencyIndex,
200 bool isFxBaseCurrencyCollateralCurrency,
201 bool isBasisOnFxBaseCurrencyLeg,
205 calendar_(
std::move(calendar)),
convention_(convention), endOfMonth_(endOfMonth),
206 baseCcyIdx_(
std::move(baseCurrencyIndex)), quoteCcyIdx_(
std::move(quoteCurrencyIndex)),
207 collateralHandle_(
std::move(collateralCurve)),
208 isFxBaseCurrencyCollateralCurrency_(isFxBaseCurrencyCollateralCurrency),
209 isBasisOnFxBaseCurrencyLeg_(isBasisOnFxBaseCurrencyLeg),
210 paymentFrequency_(paymentFrequency),
paymentLag_(paymentLag) {
254 bool observer =
false;
269 const ext::shared_ptr<IborIndex>& baseCurrencyIndex,
270 const ext::shared_ptr<IborIndex>& quoteCurrencyIndex,
272 bool isFxBaseCurrencyCollateralCurrency,
273 bool isBasisOnFxBaseCurrencyLeg,
285 isFxBaseCurrencyCollateralCurrency,
286 isBasisOnFxBaseCurrencyLeg,
294 return -(npvQuoteCcy - npvBaseCcy) / bps;
312 const ext::shared_ptr<IborIndex>& baseCurrencyIndex,
313 const ext::shared_ptr<IborIndex>& quoteCurrencyIndex,
315 bool isFxBaseCurrencyCollateralCurrency,
316 bool isBasisOnFxBaseCurrencyLeg,
317 bool isFxBaseCurrencyLegResettable,
329 isFxBaseCurrencyCollateralCurrency,
330 isBasisOnFxBaseCurrencyLeg,
333 isFxBaseCurrencyLegResettable_(isFxBaseCurrencyLegResettable) {}
336 Real npvBaseCcy = 0.0, bpsBaseCcy = 0.0;
337 Real npvQuoteCcy = 0.0, bpsQuoteCcy = 0.0;
339 std::tie(npvBaseCcy, bpsBaseCcy) =
342 std::tie(npvQuoteCcy, bpsQuoteCcy) =
346 std::tie(npvBaseCcy, bpsBaseCcy) =
349 std::tie(npvQuoteCcy, bpsQuoteCcy) = npvbpsResettingLeg(
356 return -(npvQuoteCcy - npvBaseCcy) / bps;
const YieldTermStructure & discountCurve_
Cash-flow analysis functions.
degenerate base class for the Acyclic Visitor pattern
virtual void accept(AcyclicVisitor &)
virtual void setTermStructure(TS *)
sets the term structure to be used for pricing
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
static Date maturityDate(const Leg &leg)
static Date startDate(const Leg &leg)
static std::pair< Real, Real > npvbps(const Leg &leg, const YieldTermStructure &discountCurve, bool includeSettlementDateFlows, Date settlementDate=Date(), Date npvDate=Date())
NPV and BPS of the cash flows.
void accept(AcyclicVisitor &) override
ConstNotionalCrossCurrencyBasisSwapRateHelper(const Handle< Quote > &basis, const Period &tenor, Natural fixingDays, const Calendar &calendar, BusinessDayConvention convention, bool endOfMonth, const ext::shared_ptr< IborIndex > &baseCurrencyIndex, const ext::shared_ptr< IborIndex > "eCurrencyIndex, const Handle< YieldTermStructure > &collateralCurve, bool isFxBaseCurrencyCollateralCurrency, bool isBasisOnFxBaseCurrencyLeg, Frequency paymentFrequency=NoFrequency, Integer paymentLag=0)
Real impliedQuote() const override
Base class for cross-currency basis swap rate helpers.
void setTermStructure(YieldTermStructure *) override
RelinkableHandle< YieldTermStructure > termStructureHandle_
ext::shared_ptr< IborIndex > baseCcyIdx_
Date initialNotionalExchangeDate_
const Handle< YieldTermStructure > & baseCcyLegDiscountHandle() const
Date finalNotionalExchangeDate_
ext::shared_ptr< IborIndex > quoteCcyIdx_
BusinessDayConvention convention_
Handle< YieldTermStructure > collateralHandle_
void initializeDates() override
const Handle< YieldTermStructure > & quoteCcyLegDiscountHandle() const
bool isFxBaseCurrencyCollateralCurrency_
Frequency paymentFrequency_
bool isBasisOnFxBaseCurrencyLeg_
CrossCurrencyBasisSwapRateHelperBase(const Handle< Quote > &basis, const Period &tenor, Natural fixingDays, Calendar calendar, BusinessDayConvention convention, bool endOfMonth, ext::shared_ptr< IborIndex > baseCurrencyIndex, ext::shared_ptr< IborIndex > quoteCurrencyIndex, Handle< YieldTermStructure > collateralCurve, bool isFxBaseCurrencyCollateralCurrency, bool isBasisOnFxBaseCurrencyLeg, Frequency paymentFrequency=NoFrequency, Integer paymentLag=0)
Shared handle to an observable.
bool isFxBaseCurrencyLegResettable_
void accept(AcyclicVisitor &) override
Real impliedQuote() const override
MtMCrossCurrencyBasisSwapRateHelper(const Handle< Quote > &basis, const Period &tenor, Natural fixingDays, const Calendar &calendar, BusinessDayConvention convention, bool endOfMonth, const ext::shared_ptr< IborIndex > &baseCurrencyIndex, const ext::shared_ptr< IborIndex > "eCurrencyIndex, const Handle< YieldTermStructure > &collateralCurve, bool isFxBaseCurrencyCollateralCurrency, bool isBasisOnFxBaseCurrencyLeg, bool isFxBaseCurrencyLegResettable, Frequency paymentFrequency=NoFrequency, Integer paymentLag=0)
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Bootstrap helper with date schedule relative to global evaluation date.
Visitor for a specific class
virtual void visit(T &)=0
Interest-rate term structure.
ResettingLegHelper helper_
Calendar paymentCalendar_
BusinessDayConvention convention_
const YieldTermStructure & foreignCurve_
FX and cross currency basis swaps rate helpers.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Frequency
Frequency of events.
BusinessDayConvention
Business Day conventions.
@ NoFrequency
null frequency
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
unsigned QL_INTEGER Natural
positive integer
QL_INTEGER Integer
integer number
Real Spread
spreads on interest rates
Coupon paying a Libor-type index.
MarketModelMultiProduct::CashFlow CashFlow
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
empty deleter for shared_ptr
coupon paying the compounded daily overnight rate
ext::shared_ptr< BlackVolTermStructure > v