Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
time.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 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/*! \file qle/utilities/time.hpp
20 \brief time related utilities.
21*/
22
24
25#include <ql/errors.hpp>
26#include <ql/math/comparison.hpp>
27#include <ql/time/dategenerationrule.hpp>
28#include <ql/time/period.hpp>
29#include <ql/time/schedule.hpp>
30#include <ql/types.hpp>
31
32#include <vector>
33
34namespace QuantExt {
35using namespace QuantLib;
36
37Real periodToTime(const Period& p) {
38 switch (p.units()) {
39 case Days:
40 return static_cast<Real>(p.length()) / 365.25;
41 case Weeks:
42 return static_cast<Real>(p.length()) * 7.0 / 365.25;
43 case Months:
44 return static_cast<Real>(p.length()) / 12.0;
45 case Years:
46 return static_cast<Real>(p.length());
47 default:
48 QL_FAIL("periodToTime(): time unit (" << p.units() << ") not handled");
49 }
50}
51
52QuantLib::Period implyIndexTerm(const Date& startDate, const Date& endDate) {
53 static const std::vector<Period> eligibleTerms = {5 * Years, 7 * Years, 10 * Years, 3 * Years, 1 * Years,
54 2 * Years, 4 * Years, 6 * Years, 8 * Years, 9 * Years};
55 static const int gracePeriod = 15;
56
57 for (auto const& p : eligibleTerms) {
58 if (std::abs(cdsMaturity(startDate, p, DateGeneration::CDS2015) - endDate) < gracePeriod) {
59 return p;
60 }
61 }
62
63 return 0 * Days;
64}
65
66QuantLib::Date lowerDate(const Real t, const QuantLib::Date& refDate, const QuantLib::DayCounter& dc) {
67 if (close_enough(t, 0.0))
68 return refDate;
69 QL_REQUIRE(t > 0.0, "lowerDate(" << t << "," << refDate << "," << dc.name()
70 << ") was called with negative time, this is not allowed.");
71 bool done = false;
72 Date d = refDate + static_cast<int>(t * 365.25);
73 Real tmp = dc.yearFraction(refDate, d);
74 Size attempts = 0;
75 while ((tmp < t || close_enough(tmp, t)) && (++attempts < 10000)) {
76 ++d;
77 tmp = dc.yearFraction(refDate, d);
78 done = true;
79 }
80 QL_REQUIRE(attempts < 10000, "lowerDate(" << t << "," << refDate << "," << dc.name() << ") could not be computed.");
81 if (done)
82 return --d;
83 while ((tmp > t && !close_enough(tmp, t)) && (++attempts < 10000)) {
84 --d;
85 tmp = dc.yearFraction(refDate, d);
86 done = true;
87 }
88 QL_REQUIRE(attempts < 10000, "lowerDate(" << t << "," << refDate << "," << dc.name() << ") could not be computed.");
89 if (done)
90 return d;
91 QL_FAIL("lowerDate(" << t << "," << refDate << "," << dc.name() << ") could not be computed.");
92}
93
94QuantLib::Period tenorFromLength(const QuantLib::Real length) {
95 if (std::abs(length - std::round(length)) < 1.0 / 365.25)
96 return std::lround(length) * Years;
97 if (std::abs(length * 12.0 - std::round(length * 12.0)) < 12.0 / 365.25)
98 return std::lround(length * 12.0) * Months;
99 return std::lround(length * 365.25) * Days;
100}
101
102QuantLib::Integer daylightSavingCorrection(const std::string& location, const QuantLib::Date& start,
103 const QuantLib::Date& end) {
104 Integer result = 0;
105 if (location == "Null") {
106 result = 0;
107 } else if (location == "US") {
108 for (Integer y = start.year(); y <= end.year(); ++y) {
109 Date d1 = Date::nthWeekday(2, Sunday, March, y);
110 Date d2 = Date::nthWeekday(1, Sunday, November, y);
111 if (start <= d1 && end > d1)
112 --result;
113 if (start <= d2 && end > d2)
114 ++result;
115 }
116 } else {
117 QL_FAIL("daylightSavings(" << location << ") not supported. Contact dev to add support for this location.");
118 }
119 return result;
120}
121
122} // namespace QuantExt
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
QuantLib::Period tenorFromLength(const QuantLib::Real length)
Definition: time.cpp:94
Real periodToTime(const Period &p)
Definition: time.cpp:37
QuantLib::Date lowerDate(const Real t, const QuantLib::Date &refDate, const QuantLib::DayCounter &dc)
Definition: time.cpp:66
QuantLib::Integer daylightSavingCorrection(const std::string &location, const QuantLib::Date &start, const QuantLib::Date &end)
Definition: time.cpp:102
QuantLib::Period implyIndexTerm(const Date &startDate, const Date &endDate)
Definition: time.cpp:52
time related utilities.