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