Coverage Report

Created: 2026-06-23 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/cashflows/overnightindexedcouponpricer.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2009 Roland Lichters
5
 Copyright (C) 2009 Ferdinando Ametrano
6
 Copyright (C) 2014 Peter Caspers
7
 Copyright (C) 2016 Stefano Fondi
8
 Copyright (C) 2017 Joseph Jeisman
9
 Copyright (C) 2017 Fabrice Lecuyer
10
11
 This file is part of QuantLib, a free-software/open-source library
12
 for financial quantitative analysts and developers - http://quantlib.org/
13
14
 QuantLib is free software: you can redistribute it and/or modify it
15
 under the terms of the QuantLib license.  You should have received a
16
 copy of the license along with this program; if not, please email
17
 <quantlib-dev@lists.sf.net>. The license is also available online at
18
 <https://www.quantlib.org/license.shtml>.
19
20
 This program is distributed in the hope that it will be useful, but WITHOUT
21
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22
 FOR A PARTICULAR PURPOSE.  See the license for more details.
23
*/
24
25
/*! \file overnightindexedcouponpricer.hpp
26
    \brief contains the pricer for an OvernightIndexedCoupon
27
*/
28
29
#ifndef quantlib_overnight_indexed_coupon_pricer_hpp
30
#define quantlib_overnight_indexed_coupon_pricer_hpp
31
32
#include <ql/cashflows/couponpricer.hpp>
33
#include <ql/cashflows/floatingratecoupon.hpp>
34
#include <ql/cashflows/overnightindexedcoupon.hpp>
35
#include <utility>
36
37
namespace QuantLib {
38
39
    class OptionletVolatilityStructure;
40
41
    //! Base pricer for overnight-indexed floating coupons
42
    /*! This is the base pricer class for coupons indexed to an overnight rate.  
43
        It defines the common pricing interface and provides the foundation for 
44
        more specialized overnight coupon pricers (e.g., compounded, averaged, 
45
        capped/floored variants).
46
47
        Derived classes should implement the specific logic for computing the 
48
        rate and optional adjustments, depending on the compounding or 
49
        averaging convention used.
50
    */
51
    class OvernightIndexedCouponPricer : public FloatingRateCouponPricer {
52
      using FloatingRateCouponPricer::capletRate;
53
      using FloatingRateCouponPricer::floorletRate;
54
      public:
55
56
        explicit OvernightIndexedCouponPricer(
57
          Handle<OptionletVolatilityStructure> v = Handle<OptionletVolatilityStructure>(),
58
          bool effectiveVolatilityInput = false);
59
60
        void initialize(const FloatingRateCoupon& coupon) override;
61
62
        void setCapletVolatility(
63
                            const Handle<OptionletVolatilityStructure>& v =
64
0
                                    Handle<OptionletVolatilityStructure>()) {
65
0
            unregisterWith(capletVol_);
66
0
            capletVol_ = v;
67
0
            registerWith(capletVol_);
68
0
            update();
69
0
        }
70
71
        /*! \brief Returns the handle to the optionlet volatility structure used for caplets/floorlets */
72
0
        Handle<OptionletVolatilityStructure> capletVolatility() const {
73
0
            return capletVol_;
74
0
        }
75
        
76
0
        void setEffectiveVolatilityInput(const bool effectiveVolatilityInput) {
77
0
            effectiveVolatilityInput_ = effectiveVolatilityInput;
78
0
        }
79
80
        /*! \brief Returns true if the volatility input is interpreted as effective volatility */
81
        bool effectiveVolatilityInput() const;
82
        /*! \brief Returns the effective caplet volatility used in the last capletRate() calculation.
83
            \note Only available after capletRate() was called.
84
        */
85
        virtual Real effectiveCapletVolatility() const;
86
        /*! \brief Returns the effective floorlet volatility used in the last floorletRate() calculation.
87
            \note Only available after floorletRate() was called.
88
        */
89
        virtual Real effectiveFloorletVolatility() const;
90
91
        virtual Rate capletRate(Rate effectiveCap, bool dailyCapFloor) const = 0;
92
        virtual Rate floorletRate(Rate effectiveCap, bool dailyCapFloor) const = 0;
93
        virtual Rate averageRate(const Date& date) const = 0;
94
95
      protected:
96
        const OvernightIndexedCoupon* coupon_ = nullptr;
97
        Handle<OptionletVolatilityStructure> capletVol_;
98
        bool effectiveVolatilityInput_ = false;
99
        mutable Real effectiveCapletVolatility_ = Null<Real>();
100
        mutable Real effectiveFloorletVolatility_ = Null<Real>();
101
    };
102
103
    //! Base pricer for compounded overnight-indexed floating coupons
104
    class CompoundingOvernightIndexedCouponPricer : public OvernightIndexedCouponPricer {
105
      public:
106
        explicit CompoundingOvernightIndexedCouponPricer(
107
          Handle<OptionletVolatilityStructure> v = Handle<OptionletVolatilityStructure>(),
108
          bool effectiveVolatilityInput = false);
109
        //! \name FloatingRateCoupon interface
110
        //@{
111
        //void initialize(const FloatingRateCoupon& coupon) override;
112
        Rate swapletRate() const override;
113
0
        Real swapletPrice() const override { QL_FAIL("swapletPrice not available"); }
114
0
        Real capletPrice(Rate) const override { QL_FAIL("capletPrice not available"); }
115
0
        Rate capletRate(Rate) const override { QL_FAIL("capletRate not available"); }
116
0
        Real floorletPrice(Rate) const override { QL_FAIL("floorletPrice not available"); }
117
0
        Rate floorletRate(Rate) const override { QL_FAIL("floorletRate not available"); }
118
        //@}
119
0
        Rate capletRate([[maybe_unused]] Rate effectiveCap, [[maybe_unused]] bool dailyCapFloor) const override {
120
0
          QL_FAIL("CompoundingOvernightIndexedCouponPricer::capletRate(Rate, bool) not implemented");
121
0
        }
122
0
        Rate floorletRate([[maybe_unused]] Rate effectiveCap, [[maybe_unused]] bool dailyCapFloor) const override {
123
0
          QL_FAIL("CompoundingOvernightIndexedCouponPricer::floorletRate(Rate, bool) not implemented");
124
0
        }
125
        Rate averageRate(const Date& date) const override;
126
        Rate effectiveSpread() const;
127
        Rate effectiveIndexFixing() const;
128
129
      protected:
130
        std::tuple<Rate, Spread, Rate> compute(const Date& date) const;
131
        mutable Real swapletRate_, effectiveSpread_, effectiveIndexFixing_;
132
    };
133
134
    //! Base pricer for arithmetically averaged overnight-indexed floating coupons
135
    /*! Reference: Katsumi Takada 2011, Valuation of Arithmetically Average of
136
        Fed Funds Rates and Construction of the US Dollar Swap Yield Curve
137
    */
138
    class ArithmeticAveragedOvernightIndexedCouponPricer : public OvernightIndexedCouponPricer {
139
      public:
140
        explicit ArithmeticAveragedOvernightIndexedCouponPricer(
141
            Real meanReversion = 0.03,
142
            Real volatility = 0.00, // NO convexity adjustment by default
143
            bool byApprox = false, // TRUE to use Katsumi Takada approximation
144
            Handle<OptionletVolatilityStructure> v = Handle<OptionletVolatilityStructure>(),
145
            const bool effectiveVolatilityInput = false)
146
0
        : OvernightIndexedCouponPricer(std::move(v), effectiveVolatilityInput),
147
0
         byApprox_(byApprox), mrs_(meanReversion), vol_(volatility) {}
Unexecuted instantiation: QuantLib::ArithmeticAveragedOvernightIndexedCouponPricer::ArithmeticAveragedOvernightIndexedCouponPricer(double, double, bool, QuantLib::Handle<QuantLib::OptionletVolatilityStructure>, bool)
Unexecuted instantiation: QuantLib::ArithmeticAveragedOvernightIndexedCouponPricer::ArithmeticAveragedOvernightIndexedCouponPricer(double, double, bool, QuantLib::Handle<QuantLib::OptionletVolatilityStructure>, bool)
148
149
        explicit ArithmeticAveragedOvernightIndexedCouponPricer(
150
            bool byApprox) // Simplified constructor assuming no convexity correction
151
0
        : ArithmeticAveragedOvernightIndexedCouponPricer(0.03, 0.0, byApprox) {}
152
153
        //void initialize(const FloatingRateCoupon& coupon) override;
154
        Rate swapletRate() const override;
155
0
        Real swapletPrice() const override { QL_FAIL("swapletPrice not available"); }
156
0
        Real capletPrice(Rate) const override { QL_FAIL("capletPrice not available"); }
157
0
        Rate capletRate(Rate) const override { QL_FAIL("capletRate not available"); }
158
0
        Real floorletPrice(Rate) const override { QL_FAIL("floorletPrice not available"); }
159
0
        Rate floorletRate(Rate) const override { QL_FAIL("floorletRate not available"); }
160
161
0
        Rate capletRate([[maybe_unused]] Rate effectiveCap, [[maybe_unused]] bool dailyCapFloor) const override {
162
0
          QL_FAIL("ArithmeticAveragedOvernightIndexedCouponPricer::capletRate(Rate, bool) not implemented");
163
0
        }
164
0
        Rate floorletRate([[maybe_unused]] Rate effectiveCap, [[maybe_unused]] bool dailyCapFloor) const override {
165
          QL_FAIL("ArithmeticAveragedOvernightIndexedCouponPricer::floorletRate(Rate, bool) not implemented");
166
0
        }
167
        Rate averageRate(const Date& date) const override;
168
      protected:
169
        Real convAdj1(Time ts, Time te) const;
170
        Real convAdj2(Time ts, Time te) const;
171
        bool byApprox_;
172
        Real mrs_;
173
        Real vol_;
174
    };
175
}
176
177
#endif