[go: up one dir, main page]

1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007, 2014 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 <http://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 "period.hpp"
21#include "utilities.hpp"
22#include "ql/time/period.hpp"
23
24using namespace QuantLib;
25using namespace boost::unit_test_framework;
26
27void PeriodTest::testYearsMonthsAlgebra() {
28
29 BOOST_TEST_MESSAGE("Testing period algebra on years/months...");
30
31 Period OneYear(1, Years);
32 Period SixMonths(6, Months);
33 Period ThreeMonths(3, Months);
34
35 Integer n = 4;
36 if (OneYear/n!=ThreeMonths)
37 BOOST_ERROR("division error: " << OneYear << "/" << n <<
38 " not equal to " << ThreeMonths);
39 n = 2;
40 if (OneYear/n!=SixMonths)
41 BOOST_ERROR("division error: " << OneYear << "/" << n <<
42 " not equal to " << SixMonths);
43
44 Period sum=ThreeMonths;
45 sum+=SixMonths;
46 if (sum!=Period(9, Months))
47 BOOST_ERROR("sum error: " << ThreeMonths <<
48 " + " << SixMonths <<
49 " != " << Period(9, Months));
50
51 sum+=OneYear;
52 if (sum!=Period(21, Months))
53 BOOST_ERROR("sum error: " << ThreeMonths <<
54 " + " << SixMonths <<
55 " + " << OneYear <<
56 " != " << Period(21, Months));
57
58 Period TwelveMonths(12, Months);
59 if (TwelveMonths.length()!=12)
60 BOOST_ERROR("normalization error: TwelveMonths.length()" <<
61 " is " << TwelveMonths.length() <<
62 " instead of 12");
63 if (TwelveMonths.units()!=Months)
64 BOOST_ERROR("normalization error: TwelveMonths.units()" <<
65 " is " << TwelveMonths.units() <<
66 " instead of " << Months);
67
68 Period NormalizedTwelveMonths(12, Months);
69 NormalizedTwelveMonths.normalize();
70 if (NormalizedTwelveMonths.length()!=1)
71 BOOST_ERROR("normalization error: NormalizedTwelveMonths.length()" <<
72 " is " << NormalizedTwelveMonths.length() <<
73 " instead of 1");
74 if (NormalizedTwelveMonths.units()!=Years)
75 BOOST_ERROR("normalization error: NormalizedTwelveMonths.units()" <<
76 " is " << NormalizedTwelveMonths.units() <<
77 " instead of " << Years);
78}
79
80void PeriodTest::testWeeksDaysAlgebra() {
81
82 BOOST_TEST_MESSAGE("Testing period algebra on weeks/days...");
83
84 Period TwoWeeks(2, Weeks);
85 Period OneWeek(1, Weeks);
86 Period ThreeDays(3, Days);
87 Period OneDay(1, Days);
88
89 Integer n = 2;
90 if (TwoWeeks/n!=OneWeek)
91 BOOST_ERROR("division error: " << TwoWeeks << "/" << n <<
92 " not equal to " << OneWeek);
93 n = 7;
94 if (OneWeek/n!=OneDay)
95 BOOST_ERROR("division error: " << OneWeek << "/" << n <<
96 " not equal to " << OneDay);
97
98 Period sum=ThreeDays;
99 sum+=OneDay;
100 if (sum!=Period(4, Days))
101 BOOST_ERROR("sum error: " << ThreeDays <<
102 " + " << OneDay <<
103 " != " << Period(4, Days));
104
105 sum+=OneWeek;
106 if (sum!=Period(11, Days))
107 BOOST_ERROR("sum error: " << ThreeDays <<
108 " + " << OneDay <<
109 " + " << OneWeek <<
110 " != " << Period(11, Days));
111
112 Period SevenDays(7, Days);
113 if (SevenDays.length()!=7)
114 BOOST_ERROR("normalization error: SevenDays.length()" <<
115 " is " << SevenDays.length() <<
116 " instead of 7");
117 if (SevenDays.units()!=Days)
118 BOOST_ERROR("normalization error: SevenDays.units()" <<
119 " is " << SevenDays.units() <<
120 " instead of " << Days);
121}
122
123void PeriodTest::testNormalization() {
124
125 BOOST_TEST_MESSAGE("Testing period normalization...");
126
127 Period test_values[] = {
128 0 * Days,
129 0 * Weeks,
130 0 * Months,
131 0 * Years,
132 3 * Days,
133 7 * Days,
134 14 * Days,
135 30 * Days,
136 60 * Days,
137 365 * Days,
138 1 * Weeks,
139 2 * Weeks,
140 4 * Weeks,
141 8 * Weeks,
142 52 * Weeks,
143 1 * Months,
144 2 * Months,
145 6 * Months,
146 12 * Months,
147 18 * Months,
148 24 * Months,
149 1 * Years,
150 2 * Years
151 };
152
153 for (Period p1 : test_values) {
154 auto n1 = p1.normalized();
155 if (n1 != p1) {
156 BOOST_ERROR("Normalizing " << p1 << " yields " << n1 << ", which compares different");
157 }
158
159 for (Period p2 : test_values) {
160 auto n2 = p2.normalized();
161 ext::optional<bool> comparison;
162 try {
163 comparison = (p1 == p2);
164 } catch (Error&) {
165 ;
166 }
167
168 if (comparison && *comparison) {
169 // periods which compare equal must normalize to exactly the same period
170 if (n1.units() != n2.units() || n1.length() != n2.length()) {
171 BOOST_ERROR(p1 << " and " << p2 << " compare equal, but normalize to "
172 << n1 << " and " << n2 << " respectively");
173 }
174 }
175
176 if (n1.units() == n2.units() && n1.length() == n2.length()) {
177 // periods normalizing to exactly the same period must compare equal
178 if (p1 != p2) {
179 BOOST_ERROR(p1 << " and " << p2 << " compare different, but normalize to "
180 << n1 << " and " << n2 << " respectively");
181 }
182 }
183 }
184 }
185
186}
187
188test_suite* PeriodTest::suite() {
189 auto* suite = BOOST_TEST_SUITE("Period tests");
190 suite->add(QUANTLIB_TEST_CASE(&PeriodTest::testYearsMonthsAlgebra));
191 suite->add(QUANTLIB_TEST_CASE(&PeriodTest::testWeeksDaysAlgebra));
192 suite->add(QUANTLIB_TEST_CASE(&PeriodTest::testNormalization));
193 return suite;
194}
195
196

source code of quantlib/test-suite/period.cpp