QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
swaptioncfs.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4Copyright (C) 2018 Sebastian Schlenkrich
5
6This file is part of QuantLib, a free-software/open-source library
7for financial quantitative analysts and developers - http://quantlib.org/
8
9QuantLib is free software: you can redistribute it and/or modify it
10under the terms of the QuantLib license. You should have received a
11copy 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
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
24#include <ql/experimental/basismodels/swaptioncfs.hpp>
25#include <ql/cashflows/coupon.hpp>
26#include <ql/cashflows/fixedratecoupon.hpp>
27#include <ql/cashflows/simplecashflow.hpp>
28#include <ql/exercise.hpp>
29#include <ql/settings.hpp>
30
31
32namespace QuantLib {
33
35 const Handle<YieldTermStructure>& discountCurve,
36 bool contTenorSpread)
37 : refDate_(discountCurve->referenceDate()) {
38 // we need to find the first coupon for initial payment
39 Size floatIdx = 0;
40 while (
41 (floatIdx + 1 < iborLeg.size()) &&
42 (refDate_ > (ext::dynamic_pointer_cast<Coupon>(iborLeg[floatIdx]))->accrualStartDate()))
43 ++floatIdx;
44 if (refDate_ <= (ext::dynamic_pointer_cast<Coupon>(iborLeg[floatIdx]))
45 ->accrualStartDate()) { // otherwise there is no floating coupon left
46 ext::shared_ptr<Coupon> firstFloatCoupon =
47 ext::dynamic_pointer_cast<Coupon>(iborLeg[floatIdx]);
48 floatLeg_.push_back(ext::shared_ptr<CashFlow>(new SimpleCashFlow(
49 firstFloatCoupon->nominal(), firstFloatCoupon->accrualStartDate())));
50 // calculate spread payments
51 for (Size k = floatIdx; k < iborLeg.size(); ++k) {
52 ext::shared_ptr<Coupon> coupon = ext::dynamic_pointer_cast<Coupon>(iborLeg[k]);
53 if (!coupon)
54 QL_FAIL("FloatingLeg CashFlow is no Coupon.");
55 Date startDate = coupon->accrualStartDate();
56 Date endDate = coupon->accrualEndDate();
57 Rate liborForwardRate = coupon->rate();
58 Rate discForwardRate =
59 (discountCurve->discount(startDate) / discountCurve->discount(endDate) - 1.0) /
60 coupon->accrualPeriod();
61 Rate spread;
62 Date payDate;
63 if (contTenorSpread) {
64 // Db = (1 + Delta L^libor) / (1 + Delta L^ois)
65 // spread (Db - 1) paid at startDate
66 spread = ((1.0 + coupon->accrualPeriod() * liborForwardRate) /
67 (1.0 + coupon->accrualPeriod() * discForwardRate) -
68 1.0) /
69 coupon->accrualPeriod();
70 payDate = startDate;
71 } else {
72 // spread L^libor - L^ois
73 spread = liborForwardRate - discForwardRate;
74 payDate = coupon->date();
75 }
76 floatLeg_.push_back(ext::shared_ptr<CashFlow>(new FixedRateCoupon(
77 payDate, coupon->nominal(), spread, coupon->dayCounter(), startDate, endDate)));
78 } // for ...
79 // finally, add the notional at the last date
80 ext::shared_ptr<Coupon> lastFloatCoupon =
81 ext::dynamic_pointer_cast<Coupon>(iborLeg.back());
82 floatLeg_.push_back(ext::shared_ptr<CashFlow>(new SimpleCashFlow(
83 -1.0 * lastFloatCoupon->nominal(), lastFloatCoupon->accrualEndDate())));
84 } // if ...
85 // assemble raw cash flow data...
87 // ... float times/weights
88 for (auto& k : floatLeg_)
89 floatTimes_.push_back(dc.yearFraction(refDate_, k->date()));
90 for (auto& k : floatLeg_)
91 floatWeights_.push_back(k->amount());
92 }
93
94 SwapCashFlows::SwapCashFlows(const ext::shared_ptr<VanillaSwap>& swap,
95 const Handle<YieldTermStructure>& discountCurve,
96 bool contTenorSpread)
97 : IborLegCashFlows(swap->floatingLeg(), discountCurve, contTenorSpread) {
98 // copy fixed leg coupons
99 Leg fixedLeg = swap->fixedLeg();
100 for (auto& k : fixedLeg) {
101 if (ext::dynamic_pointer_cast<Coupon>(k)->accrualStartDate() >= refDate_)
102 fixedLeg_.push_back(k);
103 }
105 // ... fixed times/weights
106 for (auto& k : fixedLeg_)
107 fixedTimes_.push_back(dc.yearFraction(refDate_, k->date()));
108 for (auto& k : fixedLeg_)
109 fixedWeights_.push_back(k->amount());
110 for (auto& k : fixedLeg_) {
111 ext::shared_ptr<Coupon> coupon = ext::dynamic_pointer_cast<Coupon>(k);
112 if (coupon != nullptr)
113 annuityWeights_.push_back(coupon->nominal() * coupon->accrualPeriod());
114 }
115 }
116
117
118 // constructor to map a swaption to deterministic fixed and floating leg cash flows
119 SwaptionCashFlows::SwaptionCashFlows(const ext::shared_ptr<Swaption>& swaption,
120 const Handle<YieldTermStructure>& discountCurve,
121 bool contTenorSpread)
122 : SwapCashFlows(swaption->underlyingSwap(), discountCurve, contTenorSpread),
123 swaption_(swaption) {
124 // assemble raw cash flow data...
126 // ... exercise times
127 for (Size k = 0; k < swaption_->exercise()->dates().size(); ++k)
128 if (swaption_->exercise()->dates()[k] > refDate_) // consider only future exercise dates
129 exerciseTimes_.push_back(
130 dc.yearFraction(refDate_, swaption_->exercise()->dates()[k]));
131 }
132
133
134}
Actual/365 (Fixed) day count convention.
Concrete date class.
Definition: date.hpp:125
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
Coupon paying a fixed interest rate
Shared handle to an observable.
Definition: handle.hpp:41
std::vector< Real > floatTimes_
Definition: swaptioncfs.hpp:38
std::vector< Real > floatWeights_
Definition: swaptioncfs.hpp:39
Predetermined cash flow.
std::vector< Real > annuityWeights_
Definition: swaptioncfs.hpp:59
std::vector< Real > fixedTimes_
Definition: swaptioncfs.hpp:57
const Leg & fixedLeg() const
Definition: swaptioncfs.hpp:68
std::vector< Real > fixedWeights_
Definition: swaptioncfs.hpp:58
ext::shared_ptr< Swaption > swaption_
Definition: swaptioncfs.hpp:77
std::vector< Real > exerciseTimes_
Definition: swaptioncfs.hpp:78
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
void swap(Array &v, Array &w) noexcept
Definition: array.hpp:903
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78