Coverage Report

Created: 2025-11-04 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/termstructures/volatility/inflation/cpivolatilitystructure.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2009, 2011 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
 <https://www.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/termstructures/volatility/inflation/cpivolatilitystructure.hpp>
21
#include <ql/termstructures/inflationtermstructure.hpp>
22
23
namespace QuantLib {
24
25
    CPIVolatilitySurface::CPIVolatilitySurface(Natural settlementDays,
26
                                               const Calendar& cal,
27
                                               BusinessDayConvention bdc,
28
                                               const DayCounter& dc,
29
                                               const Period& observationLag,
30
                                               Frequency frequency,
31
                                               bool indexIsInterpolated)
32
0
    : VolatilityTermStructure(settlementDays, cal, bdc, dc),
33
0
      baseLevel_(Null<Volatility>()), observationLag_(observationLag),
34
0
      frequency_(frequency), indexIsInterpolated_(indexIsInterpolated)
35
0
    {}
36
37
38
0
    Date CPIVolatilitySurface::baseDate() const {
39
        // Depends on interpolation, or not, of observed index
40
        // and observation lag with which it was built.
41
        // We want this to work even if the index does not
42
        // have a term structure.
43
0
        if (indexIsInterpolated()) {
44
0
            return referenceDate() - observationLag();
45
0
        } else {
46
0
            return inflationPeriod(referenceDate() - observationLag(),
47
0
                                   frequency()).first;
48
0
        }
49
0
    }
50
51
52
    void CPIVolatilitySurface::checkRange(const Date& d, Rate strike,
53
0
                                          bool extrapolate) const {
54
0
        QL_REQUIRE(d >= baseDate(),
55
0
                   "date (" << d << ") is before base date");
56
0
        QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(),
57
0
                   "date (" << d << ") is past max curve date ("
58
0
                   << maxDate() << ")");
59
0
        QL_REQUIRE(extrapolate || allowsExtrapolation() ||
60
0
                   (strike >= minStrike() && strike <= maxStrike()),
61
0
                   "strike (" << strike << ") is outside the curve domain ["
62
0
                   << minStrike() << "," << maxStrike()<< "]] at date = " << d);
63
0
    }
64
65
66
    void CPIVolatilitySurface::checkRange(Time t, Rate strike,
67
0
                                          bool extrapolate) const {
68
0
        QL_REQUIRE(t >= timeFromReference(baseDate()),
69
0
                   "time (" << t << ") is before base date");
70
0
        QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(),
71
0
                   "time (" << t << ") is past max curve time ("
72
0
                   << maxTime() << ")");
73
0
        QL_REQUIRE(extrapolate || allowsExtrapolation() ||
74
0
                   (strike >= minStrike() && strike <= maxStrike()),
75
0
                   "strike (" << strike << ") is outside the curve domain ["
76
0
                   << minStrike() << "," << maxStrike()<< "] at time = " << t);
77
0
    }
78
79
80
    Volatility CPIVolatilitySurface::volatility(const Date& maturityDate,
81
                                                Rate strike,
82
                                                const Period& obsLag,
83
0
                                                bool extrapolate) const {
84
85
0
        Period useLag = obsLag;
86
0
        if (obsLag==Period(-1,Days)) {
87
0
            useLag = observationLag();
88
0
        }
89
90
0
        if (indexIsInterpolated()) {
91
0
            checkRange(maturityDate-useLag, strike, extrapolate);
92
0
            Time t = timeFromReference(maturityDate-useLag);
93
0
            return volatilityImpl(t,strike);
94
0
        } else {
95
0
            std::pair<Date,Date> dd =
96
0
                inflationPeriod(maturityDate-useLag, frequency());
97
0
            checkRange(dd.first, strike, extrapolate);
98
0
            Time t = timeFromReference(dd.first);
99
0
            return volatilityImpl(t,strike);
100
0
        }
101
0
    }
102
103
104
    Volatility CPIVolatilitySurface::volatility(const Period& optionTenor,
105
                                                Rate strike,
106
                                                const Period& obsLag,
107
0
                                                bool extrapolate) const {
108
0
        Date maturityDate = optionDateFromTenor(optionTenor);
109
0
        return volatility(maturityDate, strike, obsLag, extrapolate);
110
0
    }
111
112
0
    Volatility CPIVolatilitySurface::volatility(Time time, Rate strike) const {
113
0
        return volatilityImpl(time, strike);
114
0
    }
115
116
    //! needed for total variance calculations
117
    Time CPIVolatilitySurface::timeFromBase(const Date& maturityDate,
118
0
                                            const Period& obsLag) const {
119
0
        Period useLag = obsLag;
120
0
        if (obsLag==Period(-1,Days)) {
121
0
            useLag = observationLag();
122
0
        }
123
124
0
        Date useDate;
125
0
        if (indexIsInterpolated()) {
126
0
            useDate = maturityDate - useLag;
127
0
        } else {
128
0
            useDate = inflationPeriod(maturityDate - useLag,
129
0
                                      frequency()).first;
130
0
        }
131
132
        // This assumes that the inflation term structure starts
133
        // as late as possible given the inflation index definition,
134
        // which is the usual case.
135
0
        return dayCounter().yearFraction(baseDate(), useDate);
136
0
    }
137
138
139
    Volatility CPIVolatilitySurface::totalVariance(const Date& maturityDate,
140
                                                   Rate strike,
141
                                                   const Period& obsLag,
142
0
                                                   bool extrapolate) const {
143
0
        Volatility vol = volatility(maturityDate, strike, obsLag, extrapolate);
144
0
        Time t = timeFromBase(maturityDate, obsLag);
145
0
        return vol*vol*t;
146
0
    }
147
148
149
    Volatility CPIVolatilitySurface::totalVariance(const Period& tenor,
150
                                                   Rate strike,
151
                                                   const Period& obsLag,
152
0
                                                   bool extrap) const {
153
0
        Date maturityDate = optionDateFromTenor(tenor);
154
0
        return totalVariance(maturityDate, strike, obsLag, extrap);
155
0
    }
156
157
}
158