Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
floatingannuitycoupon.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/couponpricer.hpp>
20#include <ql/indexes/interestrateindex.hpp>
21#include <ql/termstructures/yieldtermstructure.hpp>
23
24namespace QuantExt {
25
27 const QuantLib::ext::shared_ptr<Coupon>& previousCoupon, const Date& paymentDate,
28 const Date& startDate, const Date& endDate, Natural fixingDays,
29 const QuantLib::ext::shared_ptr<InterestRateIndex>& index, Real gearing,
30 Spread spread, const Date& refPeriodStart, const Date& refPeriodEnd,
31 const DayCounter& dayCounter, bool isInArrears)
32 : Coupon(paymentDate, 0.0, startDate, endDate, refPeriodStart, refPeriodEnd), annuity_(annuity),
33 underflow_(underflow), previousCoupon_(previousCoupon), fixingDays_(fixingDays), index_(index), gearing_(gearing),
34 spread_(spread), dayCounter_(dayCounter), isInArrears_(isInArrears) {
35
36 if (dayCounter_ == DayCounter())
37 dayCounter_ = index_->dayCounter();
38
39 QL_REQUIRE(previousCoupon, "Non-empty previous coupon required for FloatingAnnuityCoupon");
40 registerWith(previousCoupon);
41 registerWith(index);
42 registerWith(Settings::instance().evaluationDate());
43}
44
46 // If the previous coupon was a FloatingAnnuityCoupon we need to cast here in order to get its mutable nominal.
47 // Using the Coupon interface previousCoupon_->nominal() would return zero.
48 QuantLib::ext::shared_ptr<FloatingAnnuityCoupon> c = QuantLib::ext::dynamic_pointer_cast<FloatingAnnuityCoupon>(previousCoupon_);
49 if (c)
50 this->nominal_ = c->nominal() + c->amount() - annuity_;
51 else
52 this->nominal_ = previousCoupon_->nominal() + previousCoupon_->amount() - annuity_;
53
54 // The following requires a QuantLib change (expected in 1.11), making the Coupon nominal() interface virtual
55 // so that it can be overridden by this class.
56 // this->nominal_ = previousCoupon_->nominal() + previousCoupon_->amount() - annuity_;
57 if (this->nominal_ < 0.0 && underflow_ == false)
58 this->nominal_ = 0.0;
59 // std::cout << "FloatingAnnuityCoupon called() for startDate " << QuantLib::io::iso_date(accrualStartDate_) << " "
60 // << "Nominal " << this->nominal_ << std::endl;
61}
62
64
66 calculate(); // lazy
67 // performCalculations(); // not lazy
68 return this->nominal_;
69}
70
72 calculate();
73 return rate() * accrualPeriod() * this->nominal_;
74}
75
76Real FloatingAnnuityCoupon::accruedAmount(const Date& d) const {
77 if (d <= accrualStartDate_ || d > paymentDate_) {
78 return 0.0;
79 } else {
80 return this->nominal_ * rate() *
81 dayCounter().yearFraction(accrualStartDate_, std::min(d, accrualEndDate_), refPeriodStart_,
82 refPeriodEnd_);
83 }
84}
85
87
89 // if isInArrears_ fix at the end of period
90 Date refDate = isInArrears_ ? accrualEndDate_ : accrualStartDate_;
91 return index_->fixingCalendar().advance(refDate, -static_cast<Integer>(fixingDays_), Days, Preceding);
92}
93
94Real FloatingAnnuityCoupon::indexFixing() const { return index_->fixing(fixingDate()); }
95
96Real FloatingAnnuityCoupon::price(const Handle<YieldTermStructure>& discountingCurve) const {
97 return amount() * discountingCurve->discount(date());
98}
99
100void FloatingAnnuityCoupon::accept(AcyclicVisitor& v) {
101 Visitor<FloatingAnnuityCoupon>* v1 = dynamic_cast<Visitor<FloatingAnnuityCoupon>*>(&v);
102 if (v1 != 0)
103 v1->visit(*this);
104 else
105 Coupon::accept(v);
106}
107
108} // namespace QuantExt
QuantLib::ext::shared_ptr< Coupon > previousCoupon_
const QuantLib::ext::shared_ptr< InterestRateIndex > & index() const
QuantLib::ext::shared_ptr< InterestRateIndex > index_
FloatingAnnuityCoupon(Real annuity, bool underflow, const QuantLib::ext::shared_ptr< Coupon > &previousCoupon, const Date &paymentDate, const Date &startDate, const Date &endDate, Natural fixingDays, const QuantLib::ext::shared_ptr< InterestRateIndex > &index, Real gearing=1.0, Spread spread=0.0, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date(), const DayCounter &dayCounter=DayCounter(), bool isInArrears=false)
virtual void accept(AcyclicVisitor &) override
DayCounter dayCounter() const override
Real price(const Handle< YieldTermStructure > &discountingCurve) const
Real accruedAmount(const Date &d) const override
Coupon paying a Libor-type index.
SimpleQuote & spread_