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