20#include <ql/cashflows/iborcoupon.hpp>
21#include <ql/cashflows/cashflows.hpp>
22#include <ql/cashflows/simplecashflow.hpp>
23#include <ql/experimental/termstructures/crosscurrencyratehelpers.hpp>
24#include <ql/utilities/null_deleter.hpp>
31 Schedule legSchedule(
const Date& evaluationDate,
33 const Period& frequency,
35 const Calendar& calendar,
38 QL_REQUIRE(tenor >= frequency,
39 "XCCY instrument tenor should not be smaller than coupon frequency.");
41 Date referenceDate = calendar.adjust(evaluationDate);
42 Date earliestDate = calendar.advance(referenceDate, fixingDays *
Days, convention);
43 Date maturity = earliestDate + tenor;
48 .withCalendar(calendar)
49 .withConvention(convention)
50 .endOfMonth(endOfMonth)
54 Leg buildIborLeg(
const Date& evaluationDate,
57 const Calendar& calendar,
60 const ext::shared_ptr<IborIndex>& idx) {
61 Schedule sch = legSchedule(evaluationDate, tenor, idx->tenor(), fixingDays, calendar,
62 convention, endOfMonth);
63 return IborLeg(sch, idx).withNotionals(1.0);
66 std::pair<Real, Real> npvbpsConstNotionalLeg(
const Leg& iborLeg,
67 const Handle<YieldTermStructure>& discountCurveHandle) {
68 const Spread basisPoint = 1.0e-4;
69 Date refDt = discountCurveHandle->referenceDate();
70 const YieldTermStructure& discountRef = **discountCurveHandle;
71 bool includeSettleDtFlows =
true;
73 std::tie(npv, bps) =
CashFlows::npvbps(iborLeg, discountRef, includeSettleDtFlows, refDt, refDt);
75 npv += discountRef.discount(iborLeg.back()->date()) - 1.0;
80 class ResettingLegHelper {
82 explicit ResettingLegHelper(
const YieldTermStructure& discountCurve,
83 const YieldTermStructure& foreignCurve)
84 : discountCurve_(discountCurve), foreignCurve_(foreignCurve) {}
86 return discountCurve_.discount(d);
88 Real notionalAdjustment(
const Date& d)
const {
89 return foreignCurve_.discount(d) / discountCurve_.discount(d);
93 const YieldTermStructure& discountCurve_;
94 const YieldTermStructure& foreignCurve_;
97 class ResettingLegCalculator :
public AcyclicVisitor,
public Visitor<Coupon> {
99 explicit ResettingLegCalculator(
const YieldTermStructure& discountCurve,
100 const YieldTermStructure& foreignCurve)
101 : helper_(discountCurve, foreignCurve) {}
102 void visit(Coupon& c)
override {
103 Date start = c.accrualStartDate();
104 Date end = c.accrualEndDate();
105 Time accrual = c.accrualPeriod();
106 Real adjustedNotional = c.nominal() * helper_.notionalAdjustment(start);
115 Real npvRedeemedAmount =
116 adjustedNotional * discountEnd * (1.0 + c.rate() * accrual);
117 Real npvBorrowedAmount = -adjustedNotional * discountStart;
119 npv_ += npvRedeemedAmount + npvBorrowedAmount;
120 bps_ += adjustedNotional * discountEnd * accrual;
122 Real NPV()
const {
return npv_; }
123 Real BPS()
const {
return bps_; }
126 ResettingLegHelper helper_;
131 std::pair<Real, Real> npvbpsResettingLeg(
const Leg& iborLeg,
132 const Handle<YieldTermStructure>& discountCurveHandle,
133 const Handle<YieldTermStructure>& foreignCurveHandle) {
134 const YieldTermStructure& discountCurveRef = **discountCurveHandle;
135 const YieldTermStructure& foreignCurveRef = **foreignCurveHandle;
137 ResettingLegCalculator calc(discountCurveRef, foreignCurveRef);
138 for (
const auto& i : iborLeg) {
142 return { calc.NPV(), calc.BPS() };
153 ext::shared_ptr<IborIndex> baseCurrencyIndex,
154 ext::shared_ptr<IborIndex> quoteCurrencyIndex,
156 bool isFxBaseCurrencyCollateralCurrency,
157 bool isBasisOnFxBaseCurrencyLeg)
159 calendar_(
std::move(calendar)), convention_(convention), endOfMonth_(endOfMonth),
160 baseCcyIdx_(
std::move(baseCurrencyIndex)), quoteCcyIdx_(
std::move(quoteCurrencyIndex)),
161 collateralHandle_(
std::move(collateralCurve)),
162 isFxBaseCurrencyCollateralCurrency_(isFxBaseCurrencyCollateralCurrency),
163 isBasisOnFxBaseCurrencyLeg_(isBasisOnFxBaseCurrencyLeg) {
198 bool observer =
false;
200 ext::shared_ptr<YieldTermStructure> temp(t,
null_deleter());
213 const ext::shared_ptr<IborIndex>& baseCurrencyIndex,
214 const ext::shared_ptr<IborIndex>& quoteCurrencyIndex,
216 bool isFxBaseCurrencyCollateralCurrency,
217 bool isBasisOnFxBaseCurrencyLeg)
227 isFxBaseCurrencyCollateralCurrency,
228 isBasisOnFxBaseCurrencyLeg) {}
231 Real npvBaseCcy = 0.0, bpsBaseCcy = 0.0;
233 Real npvQuoteCcy = 0.0, bpsQuoteCcy = 0.0;
236 return -(npvQuoteCcy - npvBaseCcy) / bps;
254 const ext::shared_ptr<IborIndex>& baseCurrencyIndex,
255 const ext::shared_ptr<IborIndex>& quoteCurrencyIndex,
257 bool isFxBaseCurrencyCollateralCurrency,
258 bool isBasisOnFxBaseCurrencyLeg,
259 bool isFxBaseCurrencyLegResettable)
269 isFxBaseCurrencyCollateralCurrency,
270 isBasisOnFxBaseCurrencyLeg),
271 isFxBaseCurrencyLegResettable_(isFxBaseCurrencyLegResettable) {}
274 Real npvBaseCcy = 0.0, bpsBaseCcy = 0.0;
275 Real npvQuoteCcy = 0.0, bpsQuoteCcy = 0.0;
277 std::tie(npvBaseCcy, bpsBaseCcy) =
280 std::tie(npvQuoteCcy, bpsQuoteCcy) =
283 std::tie(npvBaseCcy, bpsBaseCcy) =
285 std::tie(npvQuoteCcy, bpsQuoteCcy) =
292 return -(npvQuoteCcy - npvBaseCcy) / bps;
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
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.
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)
void accept(AcyclicVisitor &) override
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_
const Handle< YieldTermStructure > & baseCcyLegDiscountHandle() const
ext::shared_ptr< IborIndex > quoteCcyIdx_
BusinessDayConvention convention_
Handle< YieldTermStructure > collateralHandle_
void initializeDates() override
const Handle< YieldTermStructure > & quoteCcyLegDiscountHandle() const
bool isFxBaseCurrencyCollateralCurrency_
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)
bool isBasisOnFxBaseCurrencyLeg_
Shared handle to an observable.
bool isFxBaseCurrencyLegResettable_
void accept(AcyclicVisitor &) 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)
Real impliedQuote() const override
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.
BusinessDayConvention
Business Day conventions.
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
unsigned QL_INTEGER Natural
positive integer
Real Spread
spreads on interest rates
MarketModelMultiProduct::CashFlow CashFlow
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.