Coverage Report

Created: 2025-08-05 06:45

/src/quantlib/ql/experimental/inflation/yoycapfloortermpricesurface.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) 2009 Chris Kenyon
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 <ql/experimental/inflation/yoycapfloortermpricesurface.hpp>
21
#include <utility>
22
23
namespace QuantLib {
24
25
    YoYCapFloorTermPriceSurface::YoYCapFloorTermPriceSurface(
26
        Natural fixingDays,
27
        const Period& lag,
28
        const ext::shared_ptr<YoYInflationIndex>& yii,
29
        CPI::InterpolationType interpolation,
30
        Handle<YieldTermStructure> nominal,
31
        const DayCounter& dc,
32
        const Calendar& cal,
33
        const BusinessDayConvention& bdc,
34
        const std::vector<Rate>& cStrikes,
35
        const std::vector<Rate>& fStrikes,
36
        const std::vector<Period>& cfMaturities,
37
        const Matrix& cPrice,
38
        const Matrix& fPrice)
39
0
    : TermStructure(0, cal, dc),
40
0
      fixingDays_(fixingDays), bdc_(bdc), yoyIndex_(yii), observationLag_(lag), nominalTS_(std::move(nominal)),
41
0
      cStrikes_(cStrikes), fStrikes_(fStrikes), cfMaturities_(cfMaturities), cPrice_(cPrice),
42
0
      fPrice_(fPrice), indexIsInterpolated_(detail::CPI::isInterpolated(interpolation, yoyIndex_)) {
43
44
        // data consistency checking, enough data?
45
0
        QL_REQUIRE(fStrikes_.size() > 1, "not enough floor strikes");
46
0
        QL_REQUIRE(cStrikes_.size() > 1, "not enough cap strikes");
47
0
        QL_REQUIRE(cfMaturities_.size() > 1, "not enough maturities");
48
0
        QL_REQUIRE(fStrikes_.size() == fPrice.rows(),
49
0
                   "floor strikes vs floor price rows not equal");
50
0
        QL_REQUIRE(cStrikes_.size() == cPrice.rows(),
51
0
                   "cap strikes vs cap price rows not equal");
52
0
        QL_REQUIRE(cfMaturities_.size() == fPrice.columns(),
53
0
                   "maturities vs floor price columns not equal");
54
0
        QL_REQUIRE(cfMaturities_.size() == cPrice.columns(),
55
0
                   "maturities vs cap price columns not equal");
56
57
        // data has correct properties (positive, monotonic)?
58
0
        for(Size j = 0; j <cfMaturities_.size(); j++) {
59
0
            QL_REQUIRE( cfMaturities[j] > Period(0,Days), "non-positive maturities");
60
0
            if(j>0) {
61
0
                QL_REQUIRE( cfMaturities[j] > cfMaturities[j-1],
62
0
                            "non-increasing maturities");
63
0
            }
64
0
            for(Size i = 0; i <fPrice_.rows(); i++) {
65
0
                QL_REQUIRE( fPrice_[i][j] > 0.0,
66
0
                            "non-positive floor price: " << fPrice_[i][j] );
67
0
                if(i>0) {
68
0
                    QL_REQUIRE( fPrice_[i][j] >= fPrice_[i-1][j],
69
0
                                "non-increasing floor prices");
70
0
                }
71
0
            }
72
0
            for(Size i = 0; i <cPrice_.rows(); i++) {
73
0
                QL_REQUIRE( cPrice_[i][j] > 0.0,
74
0
                            "non-positive cap price: " << cPrice_[i][j] );
75
0
                if(i>0) {
76
0
                    QL_REQUIRE( cPrice_[i][j] <= cPrice_[i-1][j],
77
0
                                "non-decreasing cap prices");
78
0
                }
79
0
            }
80
0
        }
81
82
83
        // Get the set of strikes, noting that repeats, overlaps are
84
        // expected between caps and floors but that no overlap in the
85
        // output is allowed so no repeats or overlaps are used
86
0
        cfStrikes_ = std::vector<Rate>();
87
0
        for(Size i = 0; i <fStrikes_.size(); i++)
88
0
            cfStrikes_.push_back( fStrikes[i] );
89
0
        Real eps = 0.0000001;
90
0
        Rate maxFstrike = fStrikes_.back();
91
0
        for(Size i = 0; i < cStrikes_.size(); i++) {
92
0
            Rate k = cStrikes[i];
93
0
            if (k > maxFstrike + eps) cfStrikes_.push_back(k);
94
0
        }
95
96
        // final consistency checking
97
0
        QL_REQUIRE(cfStrikes_.size() > 2, "overall not enough strikes");
98
0
        for (Size i = 1; i < cfStrikes_.size(); i++)
99
0
            QL_REQUIRE( cfStrikes_[i] > cfStrikes_[i-1],
100
0
                        "cfStrikes not increasing");
101
0
    }
102
103
    YoYCapFloorTermPriceSurface::YoYCapFloorTermPriceSurface(
104
        Natural fixingDays,
105
        const Period& yyLag,
106
        const ext::shared_ptr<YoYInflationIndex>& yii,
107
        Rate baseRate,
108
        Handle<YieldTermStructure> nominal,
109
        const DayCounter& dc,
110
        const Calendar& cal,
111
        const BusinessDayConvention& bdc,
112
        const std::vector<Rate>& cStrikes,
113
        const std::vector<Rate>& fStrikes,
114
        const std::vector<Period>& cfMaturities,
115
        const Matrix& cPrice,
116
        const Matrix& fPrice)
117
0
    : YoYCapFloorTermPriceSurface(fixingDays, yyLag, yii, CPI::AsIndex, std::move(nominal), dc, cal, bdc,
118
0
                                  cStrikes, fStrikes, cfMaturities, cPrice, fPrice) {}
119
120
    Date YoYCapFloorTermPriceSurface::yoyOptionDateFromTenor(const Period& p) const
121
0
    {
122
0
        return referenceDate() + p;
123
0
    }
124
125
0
    Real YoYCapFloorTermPriceSurface::price(const Period &d, const Rate k) const {
126
0
        return price(yoyOptionDateFromTenor(d), k);
127
0
    }
128
129
0
    Real YoYCapFloorTermPriceSurface::capPrice(const Period &d, const Rate k) const {
130
0
        return capPrice(yoyOptionDateFromTenor(d), k);
131
0
    }
132
133
0
    Real YoYCapFloorTermPriceSurface::floorPrice(const Period &d, const Rate k) const {
134
0
        return floorPrice(yoyOptionDateFromTenor(d), k);
135
0
    }
136
137
    Rate YoYCapFloorTermPriceSurface::atmYoYSwapRate(const Period &d,
138
0
                        bool extrapolate) const {
139
0
        return atmYoYSwapRate(yoyOptionDateFromTenor(d), extrapolate);
140
0
    }
141
142
    Rate YoYCapFloorTermPriceSurface::atmYoYRate(const Period &d,
143
                                                 const Period& obsLag,
144
0
                    bool extrapolate) const {
145
0
        return atmYoYRate(yoyOptionDateFromTenor(d), obsLag, extrapolate);
146
0
    }
147
148
}
149