Coverage Report

Created: 2025-09-04 07:11

/src/quantlib/ql/indexes/ibor/libor.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2007 Ferdinando Ametrano
5
 Copyright (C) 2007 Chiara Fornarola
6
 Copyright (C) 2005, 2006, 2008 StatPro Italia srl
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
#include <ql/indexes/ibor/libor.hpp>
23
#include <ql/time/calendars/jointcalendar.hpp>
24
#include <ql/time/calendars/unitedkingdom.hpp>
25
#include <ql/currencies/europe.hpp>
26
27
namespace QuantLib {
28
29
    namespace {
30
31
0
        BusinessDayConvention liborConvention(const Period& p) {
32
0
            switch (p.units()) {
33
0
              case Days:
34
0
              case Weeks:
35
0
                return Following;
36
0
              case Months:
37
0
              case Years:
38
0
                return ModifiedFollowing;
39
0
              default:
40
0
                QL_FAIL("invalid time units");
41
0
            }
42
0
        }
43
44
0
        bool liborEOM(const Period& p) {
45
0
            switch (p.units()) {
46
0
              case Days:
47
0
              case Weeks:
48
0
                return false;
49
0
              case Months:
50
0
              case Years:
51
0
                return true;
52
0
              default:
53
0
                QL_FAIL("invalid time units");
54
0
            }
55
0
        }
56
57
    }
58
59
60
    Libor::Libor(const std::string& familyName,
61
                 const Period& tenor,
62
                 Natural settlementDays,
63
                 const Currency& currency,
64
                 const Calendar& financialCenterCalendar,
65
                 const DayCounter& dayCounter,
66
                 const Handle<YieldTermStructure>& h)
67
0
    : IborIndex(familyName, tenor, settlementDays, currency,
68
                // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 :
69
                // UnitedKingdom::Exchange is the fixing calendar for
70
                // a) all currencies but EUR
71
                // b) all indexes but o/n and s/n
72
0
                UnitedKingdom(UnitedKingdom::Exchange),
73
0
                liborConvention(tenor), liborEOM(tenor),
74
0
                dayCounter, h),
75
0
      financialCenterCalendar_(financialCenterCalendar),
76
0
      jointCalendar_(JointCalendar(UnitedKingdom(UnitedKingdom::Exchange),
77
0
                                   financialCenterCalendar,
78
0
                                   JoinHolidays)) {
79
0
        QL_REQUIRE(this->tenor().units()!=Days,
80
0
                   "for daily tenors (" << this->tenor() <<
81
0
                   ") dedicated DailyTenor constructor must be used");
82
0
        QL_REQUIRE(currency!=EURCurrency(),
83
0
                   "for EUR Libor dedicated EurLibor constructor must be used");
84
0
    }
85
86
0
    Date Libor::valueDate(const Date& fixingDate) const {
87
88
0
        QL_REQUIRE(isValidFixingDate(fixingDate),
89
0
                   "Fixing date " << fixingDate << " is not valid");
90
91
        // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 :
92
        // For all currencies other than EUR and GBP the period between
93
        // Fixing Date and Value Date will be two London business days
94
        // after the Fixing Date, or if that day is not both a London
95
        // business day and a business day in the principal financial centre
96
        // of the currency concerned, the next following day which is a
97
        // business day in both centres shall be the Value Date.
98
0
        Date d = fixingCalendar().advance(fixingDate, fixingDays_, Days);
99
0
        return jointCalendar_.adjust(d);
100
0
    }
101
102
0
    Date Libor::maturityDate(const Date& valueDate) const {
103
        // Where a deposit is made on the final business day of a
104
        // particular calendar month, the maturity of the deposit shall
105
        // be on the final business day of the month in which it matures
106
        // (not the corresponding date in the month of maturity). Or in
107
        // other words, in line with market convention, BBA LIBOR rates
108
        // are dealt on an end-end basis. For instance a one month
109
        // deposit for value 28th February would mature on 31st March,
110
        // not the 28th of March.
111
0
        return jointCalendar_.advance(valueDate, tenor_, convention_,
112
0
                                                         endOfMonth());
113
0
    }
114
115
0
    Calendar Libor::jointCalendar() const {
116
0
        return jointCalendar_;
117
0
    }
118
119
    ext::shared_ptr<IborIndex> Libor::clone(
120
0
                                  const Handle<YieldTermStructure>& h) const {
121
0
        return ext::make_shared<Libor>(familyName(),
122
0
                                       tenor(),
123
0
                                       fixingDays(),
124
0
                                       currency(),
125
0
                                       financialCenterCalendar_,
126
0
                                       dayCounter(),
127
0
                                       h);
128
0
    }
129
130
131
    DailyTenorLibor::DailyTenorLibor(
132
                 const std::string& familyName,
133
                 Natural settlementDays,
134
                 const Currency& currency,
135
                 const Calendar& financialCenterCalendar,
136
                 const DayCounter& dayCounter,
137
                 const Handle<YieldTermStructure>& h)
138
0
    : IborIndex(familyName, 1*Days, settlementDays, currency,
139
                // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 :
140
                // no o/n or s/n fixings (as the case may be) will take place
141
                // when the principal centre of the currency concerned is
142
                // closed but London is open on the fixing day.
143
0
                JointCalendar(UnitedKingdom(UnitedKingdom::Exchange),
144
0
                              financialCenterCalendar,
145
0
                              JoinHolidays),
146
0
                liborConvention(1*Days), liborEOM(1*Days),
147
0
                dayCounter, h) {
148
0
        QL_REQUIRE(currency!=EURCurrency(),
149
0
                   "for EUR Libor dedicated EurLibor constructor must be used");
150
0
    }
151
152
}