QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
equitytotalreturnswap.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4Copyright (C) 2023 Marcin Rybacki
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/cashflows/equitycashflow.hpp>
21#include <ql/cashflows/iborcoupon.hpp>
22#include <ql/cashflows/overnightindexedcoupon.hpp>
23#include <ql/indexes/equityindex.hpp>
24#include <ql/instruments/equitytotalreturnswap.hpp>
25#include <utility>
26
27namespace QuantLib {
28
29 namespace {
30 ext::shared_ptr<CashFlow>
31 createEquityCashFlow(const Schedule& schedule,
32 const ext::shared_ptr<EquityIndex>& equityIndex,
33 Real nominal,
34 const Calendar& paymentCalendar,
35 BusinessDayConvention paymentConvention,
36 Natural paymentDelay) {
37 Date startDate = schedule.startDate();
38 Date endDate = schedule.endDate();
39
40 Calendar cal = paymentCalendar;
41 if (cal.empty()) {
42 QL_REQUIRE(!schedule.calendar().empty(), "Calendar in schedule cannot be empty");
43 cal = schedule.calendar();
44 }
45 Date paymentDate =
46 cal.advance(endDate, paymentDelay, Days, paymentConvention, schedule.endOfMonth());
47 return ext::make_shared<EquityCashFlow>(nominal, equityIndex, startDate, endDate,
48 paymentDate);
49 }
50
51 template <typename IndexType, typename LegType>
52 Leg createInterestLeg(const Schedule& schedule,
53 const ext::shared_ptr<IndexType>& interestRateIndex,
54 Real nominal,
55 const DayCounter& dayCounter,
56 Rate margin,
57 Real gearing,
58 const Calendar& paymentCalendar,
59 BusinessDayConvention paymentConvention,
60 Natural paymentDelay) {
61 return LegType(schedule, interestRateIndex)
62 .withNotionals(nominal)
63 .withPaymentDayCounter(dayCounter)
64 .withSpreads(margin)
65 .withGearings(gearing)
66 .withPaymentCalendar(paymentCalendar)
67 .withPaymentAdjustment(paymentConvention)
68 .withPaymentLag(paymentDelay);
69 }
70 }
71
73 ext::shared_ptr<EquityIndex> equityIndex,
74 ext::shared_ptr<InterestRateIndex> interestRateIndex,
75 Type type,
76 Real nominal,
77 Schedule schedule,
78 DayCounter dayCounter,
79 Rate margin,
80 Real gearing,
81 Calendar paymentCalendar,
82 BusinessDayConvention paymentConvention,
83 Natural paymentDelay)
84 : Swap(2), equityIndex_(std::move(equityIndex)),
85 interestRateIndex_(std::move(interestRateIndex)), type_(type), nominal_(nominal),
86 schedule_(std::move(schedule)), dayCounter_(std::move(dayCounter)), margin_(margin),
87 gearing_(gearing), paymentCalendar_(std::move(paymentCalendar)),
88 paymentConvention_(paymentConvention), paymentDelay_(paymentDelay) {
89
90 QL_REQUIRE(!(nominal_ < 0.0), "Nominal cannot be negative");
91
92 legs_[0].push_back(createEquityCashFlow(schedule_, equityIndex_, nominal_, paymentCalendar_,
94 for (Leg::const_iterator i = legs_[0].begin(); i < legs_[0].end(); ++i)
95 registerWith(*i);
96
97 switch (type_) {
98 case Payer:
99 payer_[0] = -1.0;
100 payer_[1] = +1.0;
101 break;
102 case Receiver:
103 payer_[0] = +1.0;
104 payer_[1] = -1.0;
105 break;
106 default:
107 QL_FAIL("unknown equity total return swap type");
108 }
109 }
110
112 Real nominal,
113 Schedule schedule,
114 ext::shared_ptr<EquityIndex> equityIndex,
115 const ext::shared_ptr<IborIndex>& interestRateIndex,
116 DayCounter dayCounter,
117 Rate margin,
118 Real gearing,
119 Calendar paymentCalendar,
120 BusinessDayConvention paymentConvention,
121 Natural paymentDelay)
122 : EquityTotalReturnSwap(std::move(equityIndex),
123 interestRateIndex,
124 type,
125 nominal,
126 std::move(schedule),
127 std::move(dayCounter),
128 margin,
129 gearing,
130 std::move(paymentCalendar),
131 paymentConvention,
132 paymentDelay) {
133 legs_[1] = createInterestLeg<IborIndex, IborLeg>(
136 for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
137 registerWith(*i);
138 }
139
141 Real nominal,
142 Schedule schedule,
143 ext::shared_ptr<EquityIndex> equityIndex,
144 const ext::shared_ptr<OvernightIndex>& interestRateIndex,
145 DayCounter dayCounter,
146 Rate margin,
147 Real gearing,
148 Calendar paymentCalendar,
149 BusinessDayConvention paymentConvention,
150 Natural paymentDelay)
151 : EquityTotalReturnSwap(std::move(equityIndex),
152 interestRateIndex,
153 type,
154 nominal,
155 std::move(schedule),
156 std::move(dayCounter),
157 margin,
158 gearing,
159 std::move(paymentCalendar),
160 paymentConvention,
161 paymentDelay) {
162 legs_[1] = createInterestLeg<OvernightIndex, OvernightLeg>(
165 for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
166 registerWith(*i);
167 }
168
170 return leg(0);
171 }
172
174 return leg(1);
175 }
176
178 return legNPV(0);
179 }
180
182 return legNPV(1);
183 }
184
186 // Knowing that for the fair margin NPV = 0.0, where:
187 // NPV = NPV Equity Leg + [NPV Floating Leg + margin * BPS / 10000]
188 // hence,
189 // fair margin = - [NPV Equity Leg + NPV Floating Leg] / BPS * 10000
190 const Spread basisPoint = 1.0e-4;
191 Real interestLegBps = legBPS(1) / basisPoint;
192 Real exMarginInterestLegNpv = interestRateLegNPV() - margin() * interestLegBps;
193 return -(equityLegNPV() + exMarginInterestLegNpv) / interestLegBps;
194 }
195}
calendar class
Definition: calendar.hpp:61
day counter class
Definition: daycounter.hpp:44
ext::shared_ptr< EquityIndex > equityIndex_
const ext::shared_ptr< InterestRateIndex > & interestRateIndex() const
EquityTotalReturnSwap(Type type, Real nominal, Schedule schedule, ext::shared_ptr< EquityIndex > equityIndex, const ext::shared_ptr< IborIndex > &interestRateIndex, DayCounter dayCounter, Rate margin, Real gearing=1.0, Calendar paymentCalendar=Calendar(), BusinessDayConvention paymentConvention=Unadjusted, Natural paymentDelay=0)
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Payment schedule.
Definition: schedule.hpp:40
Interest rate swap.
Definition: swap.hpp:41
Real legBPS(Size j) const
Definition: swap.hpp:82
std::vector< Leg > legs_
Definition: swap.hpp:133
const Leg & leg(Size j) const
Definition: swap.hpp:111
Real legNPV(Size j) const
Definition: swap.hpp:88
std::vector< Real > payer_
Definition: swap.hpp:134
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
Real Spread
spreads on interest rates
Definition: types.hpp:74
Real Rate
interest rates
Definition: types.hpp:70
Definition: any.hpp:35
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.