Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
crossccyfixfloatmtmresetswaphelper.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18#include <boost/make_shared.hpp>
19#include <ql/cashflows/iborcoupon.hpp>
20#include <ql/utilities/null_deleter.hpp>
23
24namespace QuantExt {
25
27 const Handle<Quote>& rate, const Handle<Quote>& spotFx, Natural settlementDays, const Calendar& paymentCalendar,
28 BusinessDayConvention paymentConvention, const Period& tenor, const Currency& fixedCurrency,
29 Frequency fixedFrequency, BusinessDayConvention fixedConvention, const DayCounter& fixedDayCount,
30 const QuantLib::ext::shared_ptr<IborIndex>& index, const Handle<YieldTermStructure>& floatDiscount,
31 const Handle<Quote>& spread, bool endOfMonth, bool resetsOnFloatLeg)
32 : RelativeDateRateHelper(rate), spotFx_(spotFx), settlementDays_(settlementDays), paymentCalendar_(paymentCalendar),
33 paymentConvention_(paymentConvention), tenor_(tenor), fixedCurrency_(fixedCurrency),
34 fixedFrequency_(fixedFrequency), fixedConvention_(fixedConvention), fixedDayCount_(fixedDayCount), index_(index),
35 floatDiscount_(floatDiscount), spread_(spread), endOfMonth_(endOfMonth), resetsOnFloatLeg_(resetsOnFloatLeg){
36
37 QL_REQUIRE(!spotFx_.empty(), "Spot FX quote cannot be empty.");
38 QL_REQUIRE(fixedCurrency_ != index_->currency(), "Fixed currency should not equal float leg currency.");
39
40 registerWith(spotFx_);
41 registerWith(index_);
42 registerWith(floatDiscount_);
43 registerWith(spread_);
44
46}
47
49
50 // Swap start and end
51 Date referenceDate = evaluationDate_ = Settings::instance().evaluationDate();
52 referenceDate = paymentCalendar_.adjust(referenceDate);
53 Date start = paymentCalendar_.advance(referenceDate, settlementDays_ * Days);
54 Date end = start + tenor_;
55
56 // Fixed schedule
57 Schedule fixedSchedule(start, end, Period(fixedFrequency_), paymentCalendar_, fixedConvention_, fixedConvention_,
58 DateGeneration::Backward, endOfMonth_);
59
60 // Float schedule
61 Schedule floatSchedule(start, end, index_->tenor(), paymentCalendar_, paymentConvention_, paymentConvention_,
62 DateGeneration::Backward, endOfMonth_);
63
64 Real nominal = 1.0;
65
66 // build an FX index for forward rate projection (TODO - review settlement and calendar)
67 Natural paymentLag = 0;
68 Spread floatSpread = spread_.empty() ? 0.0 : spread_->value();
69 QuantLib::ext::shared_ptr<FxIndex> fxIdx;
71 fxIdx = QuantLib::ext::make_shared<FxIndex>("dummy", settlementDays_, fixedCurrency_, index_->currency(), paymentCalendar_,
73 } else {
74 fxIdx = QuantLib::ext::make_shared<FxIndex>("dummy", settlementDays_, index_->currency(), fixedCurrency_, paymentCalendar_,
76 }
77
78 swap_ = QuantLib::ext::make_shared<CrossCcyFixFloatMtMResetSwap>(nominal, fixedCurrency_, fixedSchedule, 0.0, fixedDayCount_, paymentConvention_,
79 paymentLag, paymentCalendar_, index_->currency(), floatSchedule, index_, floatSpread, paymentConvention_,
80 paymentLag, paymentCalendar_, fxIdx, resetsOnFloatLeg_);
81
82 // Attach engine
83 QuantLib::ext::shared_ptr<PricingEngine> engine = QuantLib::ext::make_shared<CrossCcySwapEngine>(
85 swap_->setPricingEngine(engine);
86
87 earliestDate_ = swap_->startDate();
88 latestDate_ = swap_->maturityDate();
89
90 /* May need to adjust latestDate_ if you are projecting libor based
91 on tenor length rather than from accrual date to accrual date. */
92 if (!IborCoupon::Settings::instance().usingAtParCoupons()) {
93 Size numCashflows = swap_->leg(1).size();
94 Date endDate = latestDate_;
95 if (numCashflows > 0) {
96 for(Size i = numCashflows; i > 0; i--) {
97 Size pos = i - 1;
98 QuantLib::ext::shared_ptr<FloatingRateCoupon> lastFloating =
99 QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(swap_->leg(1)[pos]);
100 if (!lastFloating)
101 continue;
102 else {
103 Date fixingValueDate = index_->valueDate(lastFloating->fixingDate());
104 endDate = index_->maturityDate(fixingValueDate);
105 Date endValueDate = index_->maturityDate(fixingValueDate);
106 latestDate_ = std::max(latestDate_, endValueDate);
107 break;
108 }
109 }
110 }
111 }
112}
113
115 QuantLib::ext::shared_ptr<YieldTermStructure> temp(t, null_deleter());
116 termStructureHandle_.linkTo(temp, false);
117 RelativeDateRateHelper::setTermStructure(t);
118}
120 // Maybe FX spot quote or spread quote changed
121 if (!close(spotFx_->value(), swap_->nominal()) ||
122 (!spread_.empty() && !close(spread_->value(), swap_->floatSpread()))) {
124 }
125
126 // Maybe evaluation date changed. RelativeDateRateHelper will take care of this
127 // Note: if initializeDates() was called in above if statement, it will not be called
128 // again in RelativeDateRateHelper::update() because evaluationDate_ is set in
129 // initializeDates(). So, redundant instrument builds are avoided.
130 RelativeDateRateHelper::update();
131}
132
134 QL_REQUIRE(termStructure_, "Term structure needs to be set");
135 swap_->deepUpdate();
136 return swap_->fairFixedRate();
137}
138
140 Visitor<CrossCcyFixFloatMtMResetSwapHelper>* v1 = dynamic_cast<Visitor<CrossCcyFixFloatMtMResetSwapHelper>*>(&v);
141 if (v1)
142 v1->visit(*this);
143 else
144 RateHelper::accept(v);
145}
146} // namespace QuantExt
QuantLib::ext::shared_ptr< CrossCcyFixFloatMtMResetSwap > swap_
CrossCcyFixFloatMtMResetSwapHelper(const QuantLib::Handle< QuantLib::Quote > &rate, const QuantLib::Handle< QuantLib::Quote > &spotFx, QuantLib::Natural settlementDays, const QuantLib::Calendar &paymentCalendar, QuantLib::BusinessDayConvention paymentConvention, const QuantLib::Period &tenor, const QuantLib::Currency &fixedCurrency, QuantLib::Frequency fixedFrequency, QuantLib::BusinessDayConvention fixedConvention, const QuantLib::DayCounter &fixedDayCount, const QuantLib::ext::shared_ptr< QuantLib::IborIndex > &index, const QuantLib::Handle< QuantLib::YieldTermStructure > &floatDiscount, const Handle< Quote > &spread=Handle< Quote >(), bool endOfMonth=false, bool resetsOnFloatLeg=true)
QuantLib::Handle< QuantLib::YieldTermStructure > floatDiscount_
QuantLib::ext::shared_ptr< QuantLib::IborIndex > index_
Cross currency swap engine.
SimpleQuote & spread_