-
Notifications
You must be signed in to change notification settings - Fork 287
Expand file tree
/
Copy pathcpileg.cpp
More file actions
126 lines (100 loc) · 5.15 KB
/
cpileg.cpp
File metadata and controls
126 lines (100 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
Copyright (C) 2023 Skandinaviska Enskilda Banken AB (publ)
All rights reserved.
This file is part of ORE, a free-software/open-source library
for transparent pricing and risk analysis - http://opensourcerisk.org
ORE is free software: you can redistribute it and/or modify it
under the terms of the Modified BSD License. You should have received a
copy of the license along with this program.
The license is also available online at <http://opensourcerisk.org>
This program is distributed on the basis that it will form a useful
contribution to risk analytics and model standardisation, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
*/
#include "toplevelfixture.hpp"
#include <boost/test/unit_test.hpp>
#include <ql/indexes/inflation/ukrpi.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/all.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <ql/time/daycounters/simpledaycounter.hpp>
#include <ql/time/businessdayconvention.hpp>
#include <qle/cashflows/cpicoupon.hpp>
using namespace QuantLib;
using namespace boost::unit_test_framework;
BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
BOOST_AUTO_TEST_SUITE(CpiLegTest)
BOOST_AUTO_TEST_CASE(testCpiLegPaymentLag) {
BOOST_TEST_MESSAGE("Testing QuantExt::CPILeg for payment lag...");
Date evaluationDate(6, October, 2023);
Settings::instance().evaluationDate() = evaluationDate;
Calendar calendar = WeekendsOnly();
DayCounter dayCounter = ActualActual(ActualActual::ISDA);
Date startDate(6, October, 2023);
Date endDate(6, October, 2026);
Schedule fixedSchedule = MakeSchedule()
.from(startDate)
.to(endDate)
.withTenor(Period(6, Months))
.withCalendar(calendar)
.withConvention(ModifiedFollowing)
.backwards();
auto flatYts = ext::shared_ptr<YieldTermStructure>(new FlatForward(evaluationDate, 0.025, dayCounter));
RelinkableHandle<YieldTermStructure> yTS(flatYts);
auto ukrpi = ext::make_shared<UKRPI>();
Leg cpiLeg = QuantExt::CPILeg(fixedSchedule, ukrpi, yTS, 100, Period(3, Months))
.withNotionals(1e6)
.withFixedRates(0.01)
.withPaymentCalendar(calendar)
.withPaymentLag(2);
for (auto& coupon : cpiLeg) {
if (auto cpiCoupon = ext::dynamic_pointer_cast<CPICoupon>(coupon))
// The setup leg will have six regular coupons
BOOST_CHECK_EQUAL(cpiCoupon->date(), cpiCoupon->accrualEndDate() + 2 * Days);
else if (auto cpiNotionalCashflow = ext::dynamic_pointer_cast<CPICashFlow>(coupon))
// and one of these flows
BOOST_CHECK_EQUAL(cpiNotionalCashflow->date(), fixedSchedule.endDate() + 2 * Days);
}
}
BOOST_AUTO_TEST_CASE(testCpiLegNegativePaymentLag) {
BOOST_TEST_MESSAGE("Testing QuantExt::CPILeg for negative payment lag...");
Date evaluationDate(6, October, 2023);
Settings::instance().evaluationDate() = evaluationDate;
Calendar calendar = WeekendsOnly();
DayCounter dayCounter = SimpleDayCounter();
BusinessDayConvention dayConvention = ModifiedFollowing;
Date startDate(6, October, 2023);
Date endDate(6, October, 2024);
Schedule fixedSchedule = MakeSchedule()
.from(startDate)
.to(endDate)
.withTenor(Period(6, Months))
.withCalendar(calendar)
.withConvention(dayConvention)
.backwards();
auto flatYts = ext::shared_ptr<YieldTermStructure>(new FlatForward(evaluationDate, 0.025, dayCounter));
RelinkableHandle<YieldTermStructure> yTS(flatYts);
auto ukrpi = ext::make_shared<UKRPI>();
Integer paymentLag = -2;
Leg cpiLeg = QuantExt::CPILeg(fixedSchedule, ukrpi, yTS, 100, Period(3, Months))
.withNotionals(1e6)
.withFixedRates(0.01)
.withPaymentCalendar(calendar)
.withPaymentDayCounter(dayCounter)
.withPaymentAdjustment(dayConvention)
.withPaymentLag(paymentLag);
for (auto& coupon : cpiLeg) {
if (auto cpiCoupon = ext::dynamic_pointer_cast<CPICoupon>(coupon)) {
// The setup leg will have six regular coupons
Date testPaymentLag = calendar.advance(cpiCoupon->accrualEndDate(), paymentLag, Days, dayConvention);
BOOST_CHECK_EQUAL(cpiCoupon->date(), testPaymentLag);
} else if (auto cpiNotionalCashflow = ext::dynamic_pointer_cast<CPICashFlow>(coupon)) {
// and one of these flows
Date testPaymentLag = calendar.advance(fixedSchedule.endDate(), paymentLag, Days, dayConvention);
BOOST_CHECK_EQUAL(cpiNotionalCashflow->date(), testPaymentLag);
}
}
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()