Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
subperiodsswap.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 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
19#include <ql/cashflows/fixedratecoupon.hpp>
20#include <ql/time/schedule.hpp>
21#include <ql/pricingengines/swap/discountingswapengine.hpp>
24#include <ql/currencies/america.hpp>
25#include <ql/currencies/asia.hpp>
26#include <ql/currencies/europe.hpp>
27#include <ql/currencies/oceania.hpp>
28#include <ql/time/daycounters/thirty360.hpp>
29#include <ql/time/daycounters/actual360.hpp>
30#include <ql/time/daycounters/actual365fixed.hpp>
31
32using namespace QuantLib;
33
34namespace QuantExt {
35
36SubPeriodsSwap::SubPeriodsSwap(const Date& effectiveDate, Real nominal, const Period& swapTenor, bool isPayer,
37 const Period& fixedTenor, Rate fixedRate, const Calendar& fixedCalendar,
38 const DayCounter& fixedDayCount, BusinessDayConvention fixedConvention,
39 const Period& floatPayTenor, const QuantLib::ext::shared_ptr<IborIndex>& iborIndex,
40 const DayCounter& floatingDayCount, DateGeneration::Rule rule,
42
43 : Swap(2), nominal_(nominal), isPayer_(isPayer), fixedRate_(fixedRate), fixedDayCount_(fixedDayCount),
44 floatIndex_(iborIndex), floatDayCount_(floatingDayCount), floatPayTenor_(floatPayTenor), type_(type) {
45
46 Date terminationDate = effectiveDate + swapTenor;
47
48 // Fixed leg
49 fixedSchedule_ = MakeSchedule()
50 .from(effectiveDate)
51 .to(terminationDate)
52 .withTenor(fixedTenor)
53 .withCalendar(fixedCalendar)
54 .withConvention(fixedConvention)
55 .withTerminationDateConvention(fixedConvention)
56 .withRule(rule);
57
58 legs_[0] = FixedRateLeg(fixedSchedule_)
59 .withNotionals(nominal_)
60 .withCouponRates(fixedRate_, fixedDayCount_)
61 .withPaymentAdjustment(fixedConvention);
62
63 // Sub Periods Leg, schedule is the PAY schedule
64 BusinessDayConvention floatPmtConvention = iborIndex->businessDayConvention();
65 Calendar floatPmtCalendar = iborIndex->fixingCalendar();
66 floatSchedule_ = MakeSchedule()
67 .from(effectiveDate)
68 .to(terminationDate)
69 .withTenor(floatPayTenor)
70 .withCalendar(floatPmtCalendar)
71 .withConvention(floatPmtConvention)
72 .withTerminationDateConvention(floatPmtConvention)
73 .withRule(rule);
74
77 .withPaymentAdjustment(floatPmtConvention)
79 .withPaymentCalendar(floatPmtCalendar)
80 .includeSpread(false)
82
83 // legs_[0] is fixed
84 payer_[0] = isPayer_ ? -1.0 : +1.0;
85 payer_[1] = isPayer_ ? +1.0 : -1.0;
86
87 // Register this instrument with its coupons
88 Leg::const_iterator it;
89 for (it = legs_[0].begin(); it != legs_[0].end(); ++it)
90 registerWith(*it);
91 for (it = legs_[1].begin(); it != legs_[1].end(); ++it)
92 registerWith(*it);
93}
94
96 static const Spread basisPoint = 1.0e-4;
97 calculate();
98 QL_REQUIRE(legBPS_[0] != Null<Real>(), "result not available");
99 return fixedRate_ - NPV_ / (legBPS_[0] / basisPoint);
100}
101
102
103MakeSubPeriodsSwap::MakeSubPeriodsSwap(const Period& swapTenor, const QuantLib::ext::shared_ptr<IborIndex>& index, Rate fixedRate,
104 const Period& floatPayTenor, const Period& forwardStart)
105 : swapTenor_(swapTenor), index_(index), fixedRate_(fixedRate), floatPayTenor_(floatPayTenor), forwardStart_(forwardStart),
106 nominal_(1.0), isPayer_(true), settlementDays_(index->fixingDays()), fixedCalendar_(index->fixingCalendar()),
107 fixedConvention_(ModifiedFollowing), fixedRule_(DateGeneration::Backward), floatDayCounter_(index->dayCounter()),
108 subCouponsType_(QuantExt::SubPeriodsCoupon1::Compounding) {}
109
110MakeSubPeriodsSwap::operator SubPeriodsSwap() const {
111 QuantLib::ext::shared_ptr<SubPeriodsSwap> swap = *this;
112 return *swap;
113}
114
115MakeSubPeriodsSwap::operator QuantLib::ext::shared_ptr<SubPeriodsSwap>() const {
116
117 Date startDate;
118
119 // start dates and end dates
120 if (effectiveDate_ != Date())
121 startDate = effectiveDate_;
122 else {
123 Date refDate = Settings::instance().evaluationDate();
124 // if the evaluation date is not a business day
125 // then move to the next business day
126 refDate = index_->fixingCalendar().adjust(refDate);
127 Date spotDate = index_->fixingCalendar().advance(refDate, settlementDays_ * Days);
128 startDate = spotDate + forwardStart_;
129 if (forwardStart_.length() < 0)
130 startDate = index_->fixingCalendar().adjust(startDate, Preceding);
131 else
132 startDate = index_->fixingCalendar().adjust(startDate, Following);
133 }
134
135 // Copied from MakeVanillaSwap - Is there a better way?
136 const Currency& curr = index_->currency();
137 Period fixedTenor;
138 if (fixedTenor_ != Period())
139 fixedTenor = fixedTenor_;
140 else {
141 if ((curr == EURCurrency()) ||
142 (curr == USDCurrency()) ||
143 (curr == CHFCurrency()) ||
144 (curr == SEKCurrency()) ||
145 (curr == GBPCurrency() && swapTenor_ <= 1 * Years))
146 fixedTenor = Period(1, Years);
147 else if ((curr == GBPCurrency() && swapTenor_ > 1 * Years) ||
148 (curr == JPYCurrency()) ||
149 (curr == AUDCurrency() && swapTenor_ >= 4 * Years))
150 fixedTenor = Period(6, Months);
151 else if ((curr == HKDCurrency() ||
152 (curr == AUDCurrency() && swapTenor_ < 4 * Years)))
153 fixedTenor = Period(3, Months);
154 else
155 QL_FAIL("unknown fixed leg default tenor for " << curr);
156 }
157
158 // Copied from MakeVanillaSwap - Is there a better way?
159 DayCounter fixedDayCount;
160 if (fixedDayCount_ != DayCounter())
161 fixedDayCount = fixedDayCount_;
162 else {
163 if (curr == USDCurrency())
164 fixedDayCount = Actual360();
165 else if (curr == EURCurrency() || curr == CHFCurrency() ||
166 curr == SEKCurrency())
167 fixedDayCount = Thirty360(Thirty360::BondBasis);
168 else if (curr == GBPCurrency() || curr == JPYCurrency() ||
169 curr == AUDCurrency() || curr == HKDCurrency() ||
170 curr == THBCurrency())
171 fixedDayCount = Actual365Fixed();
172 else
173 QL_FAIL("unknown fixed leg day counter for " << curr);
174 }
175
176 QuantLib::ext::shared_ptr<SubPeriodsSwap> swap(new SubPeriodsSwap(startDate, nominal_, swapTenor_, isPayer_,
177 fixedTenor, fixedRate_, fixedCalendar_, fixedDayCount, fixedConvention_, floatPayTenor_, index_,
178 floatDayCounter_, fixedRule_, subCouponsType_));
179
180 if (engine_ != 0)
181 swap->setPricingEngine(engine_);
182
183 return swap;
184}
185
187 effectiveDate_ = effectiveDate;
188 return *this;
189}
190
192 nominal_ = n;
193 return *this;
194}
195
197 isPayer_ = p;
198 return *this;
199}
200
202 settlementDays_ = settlementDays;
203 effectiveDate_ = Date();
204 return *this;
205}
206
208 fixedTenor_ = t;
209 return *this;
210}
211
213 fixedCalendar_ = cal;
214 return *this;
215}
216
218 fixedConvention_ = bdc;
219 return *this;
220}
221
223 fixedRule_ = r;
224 return *this;
225}
226
228 fixedDayCount_ = dc;
229 return *this;
230}
231
233 subCouponsType_ = st;
234 return *this;
235}
236
238 bool includeSettlementDateFlows = false;
239 engine_ = QuantLib::ext::shared_ptr<PricingEngine>(new DiscountingSwapEngine(d, includeSettlementDateFlows));
240 return *this;
241}
242
243MakeSubPeriodsSwap& MakeSubPeriodsSwap::withPricingEngine(const QuantLib::ext::shared_ptr<PricingEngine>& engine) {
244 engine_ = engine;
245 return *this;
246}
247} // namespace QuantExt
QuantLib::ext::shared_ptr< PricingEngine > engine_
Definition: cdsoption.cpp:78
MakeSubPeriodsSwap & withFixedLegTenor(const Period &t)
MakeSubPeriodsSwap & withNominal(Real n)
MakeSubPeriodsSwap & withSettlementDays(Natural settlementDays)
BusinessDayConvention fixedConvention_
QuantExt::SubPeriodsCoupon1::Type subCouponsType_
MakeSubPeriodsSwap & withEffectiveDate(const Date &)
MakeSubPeriodsSwap & withFixedLegConvention(BusinessDayConvention bdc)
MakeSubPeriodsSwap & withFixedLegRule(DateGeneration::Rule r)
MakeSubPeriodsSwap & withIsPayer(bool p)
QuantLib::ext::shared_ptr< PricingEngine > engine_
DateGeneration::Rule fixedRule_
MakeSubPeriodsSwap & withSubCouponsType(const QuantExt::SubPeriodsCoupon1::Type &st)
MakeSubPeriodsSwap & withPricingEngine(const QuantLib::ext::shared_ptr< PricingEngine > &engine)
MakeSubPeriodsSwap(const Period &swapTenor, const QuantLib::ext::shared_ptr< IborIndex > &index, Rate fixedRate, const Period &floatPayTenor, const Period &forwardStart=0 *Days)
MakeSubPeriodsSwap & withFixedLegDayCount(const DayCounter &dc)
MakeSubPeriodsSwap & withDiscountingTermStructure(const Handle< YieldTermStructure > &discountCurve)
MakeSubPeriodsSwap & withFixedLegCalendar(const Calendar &cal)
helper class building a sequence of sub-period coupons
SubPeriodsLeg1 & withPaymentDayCounter(const DayCounter &dayCounter)
SubPeriodsLeg1 & withType(SubPeriodsCoupon1::Type type)
SubPeriodsLeg1 & includeSpread(bool includeSpread)
SubPeriodsLeg1 & withPaymentCalendar(const Calendar &calendar)
SubPeriodsLeg1 & withNotional(Real notional)
SubPeriodsLeg1 & withPaymentAdjustment(BusinessDayConvention convention)
Single currency sub periods swap.
SubPeriodsSwap(const Date &effectiveDate, Real nominal, const Period &swapTenor, bool isPayer, const Period &fixedTenor, Rate fixedRate, const Calendar &fixedCalendar, const DayCounter &fixedDayCount, BusinessDayConvention fixedConvention, const Period &floatPayTenor, const QuantLib::ext::shared_ptr< IborIndex > &iborIndex, const DayCounter &floatingDayCount, DateGeneration::Rule rule=DateGeneration::Backward, QuantExt::SubPeriodsCoupon1::Type type=QuantExt::SubPeriodsCoupon1::Compounding)
Constructor with conventions deduced from the index.
QuantLib::ext::shared_ptr< IborIndex > floatIndex_
const Period & floatPayTenor() const
QuantExt::SubPeriodsCoupon1::Type type_
Coupon with a number of sub-periods.
Single currency sub periods swap instrument.