• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 29653052760

18 Jul 2026 04:59PM UTC coverage: 74.95% (-0.004%) from 74.954%
29653052760

Pull #2667

github

web-flow
Merge 309a8d49b into 3baff1f70
Pull Request #2667: gh-2172 fix compounding

7 of 9 new or added lines in 1 file covered. (77.78%)

6 existing lines in 1 file now uncovered.

59548 of 79450 relevant lines covered (74.95%)

8596988.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.85
/ql/interestrate.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2004 Ferdinando Ametrano
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
 <https://www.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/interestrate.hpp>
21
#include <ql/utilities/dataformatters.hpp>
22
#include <iomanip>
23
#include <sstream>
24
#include <utility>
25

26
namespace QuantLib {
27

28
    // constructors
29

30
    InterestRate::InterestRate()
522,657✔
31
    : r_(Null<Real>()) {}
522,657✔
32

33
    InterestRate::InterestRate(Rate r, DayCounter dc, Compounding comp, Frequency freq)
630,690,242✔
34
    : r_(r), dc_(std::move(dc)), comp_(comp), freqMakesSense_(false) {
630,690,242✔
35

36
        if (comp_==Compounded || comp_==SimpleThenCompounded || comp_==CompoundedThenSimple) {
630,690,242✔
37
            freqMakesSense_ = true;
786,228✔
38
            QL_REQUIRE(freq!=Once && freq!=NoFrequency,
786,228✔
39
                       "frequency not allowed for this interest rate");
40
            freq_ = Real(freq);
786,228✔
41
        }
42
    }
630,690,242✔
43

44
    Real InterestRate::compoundFactor(Time t) const {
1,449,275,031✔
45

46
        QL_REQUIRE(t>=0.0, "negative time (" << t << ") not allowed");
1,449,275,031✔
47
        QL_REQUIRE(r_ != Null<Rate>(), "null interest rate");
1,449,275,031✔
48
        switch (comp_) {
1,449,275,031✔
49
          case Simple:
1,413,223✔
50
            return 1.0 + r_*t;
1,413,223✔
51
          case Compounded:
2,321,758✔
52
          case SimpleThenCompounded:
53
          case CompoundedThenSimple:
54
            return std::pow(1.0+r_/freq_, freq_*t);
2,321,758✔
55
          case Continuous:
1,445,540,050✔
56
            return std::exp(r_*t);
1,445,540,050✔
UNCOV
57
          default:
×
UNCOV
58
            QL_FAIL("unknown compounding convention");
×
59
        }
60
    }
61

62
    InterestRate InterestRate::impliedRate(Real compound,
629,147,617✔
63
                                           const DayCounter& resultDC,
64
                                           Compounding comp,
65
                                           Frequency freq,
66
                                           Time t) {
67

68
        QL_REQUIRE(compound>0.0, "positive compound factor required");
629,147,617✔
69

70
        Rate r;
71
        if (compound==1.0) {
629,147,617✔
72
            QL_REQUIRE(t>=0.0, "non negative time (" << t << ") required");
195,540,081✔
73
            r = 0.0;
74
        } else {
75
            QL_REQUIRE(t>0.0, "positive time (" << t << ") required");
433,607,536✔
76
            switch (comp) {
433,607,536✔
77
              case Simple:
696,562✔
78
                r = (compound - 1.0)/t;
696,562✔
79
                break;
696,562✔
80
              case Compounded:
226,051✔
81
                r = (std::pow(compound, 1.0/(Real(freq)*t))-1.0)*Real(freq);
226,051✔
82
                break;
226,051✔
83
              case Continuous:
432,684,923✔
84
                r = std::log(compound)/t;
432,684,923✔
85
                break;
432,684,923✔
UNCOV
86
              case SimpleThenCompounded:
×
UNCOV
87
                if (t<=1.0/Real(freq))
×
UNCOV
88
                    r = (compound - 1.0)/t;
×
89
                else
UNCOV
90
                    r = (std::pow(compound, 1.0/(Real(freq)*t))-1.0)*Real(freq);
×
91
                break;
92
              case CompoundedThenSimple:
×
93
                if (t>1.0/Real(freq))
×
94
                    r = (compound - 1.0)/t;
×
95
                else
96
                    r = (std::pow(compound, 1.0/(Real(freq)*t))-1.0)*Real(freq);
×
97
                break;
98
              default:
×
99
                QL_FAIL("unknown compounding convention ("
×
100
                        << Integer(comp) << ")");
101
            }
102
        }
103
        return InterestRate(r, resultDC, comp, freq);
1,258,295,234✔
104
    }
105

106

107
    std::ostream& operator<<(std::ostream& out, const InterestRate& ir) {
12✔
108
        if (ir.rate() == Null<Rate>())
12✔
109
            return out << "null interest rate";
×
110

111
        out << io::rate(ir.rate()) << " " << ir.dayCounter().name() << " ";
36✔
112
        switch (ir.compounding()) {
12✔
113
          case Simple:
12✔
114
            out << "simple compounding";
12✔
115
            break;
12✔
116
          case Compounded:
117
            switch (ir.frequency()) {
×
118
              case NoFrequency:
×
119
              case Once:
120
                QL_FAIL(ir.frequency() << " frequency not allowed "
×
121
                        "for this interest rate");
122
              default:
123
                out << ir.frequency() <<" compounding";
×
124
            }
125
            break;
×
126
          case Continuous:
×
127
            out << "continuous compounding";
×
128
            break;
×
129
          case SimpleThenCompounded:
130
            switch (ir.frequency()) {
×
131
              case NoFrequency:
×
132
              case Once:
133
                QL_FAIL(ir.frequency() << " frequency not allowed "
×
134
                        "for this interest rate");
135
              default:
×
136
                out << "simple compounding up to "
×
137
                    << Integer(12/ir.frequency()) << " months, then "
×
138
                    << ir.frequency() << " compounding";
×
139
            }
140
            break;
×
141
          case CompoundedThenSimple:
142
            switch (ir.frequency()) {
×
143
              case NoFrequency:
×
144
              case Once:
145
                QL_FAIL(ir.frequency() << " frequency not allowed "
×
146
                        "for this interest rate");
147
              default:
×
148
                out << "compounding up to "
×
149
                    << Integer(12/ir.frequency()) << " months, then "
×
150
                    << ir.frequency() << " simple compounding";
×
151
            }
152
            break;
×
153
          default:
×
154
            QL_FAIL("unknown compounding convention ("
×
155
                    << Integer(ir.compounding()) << ")");
156
        }
157
        return out;
158
    }
159

160
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc