File: cpicapfloortermpricesurface.cpp

package info (click to toggle)
quantlib 1.21-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 45,532 kB
  • sloc: cpp: 388,042; makefile: 6,661; sh: 4,381; lisp: 86
file content (135 lines) | stat: -rw-r--r-- 5,836 bytes parent folder | download
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
127
128
129
130
131
132
133
134
135
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2010 Chris Kenyon

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/


#include <ql/experimental/inflation/cpicapfloortermpricesurface.hpp>


namespace QuantLib {

    CPICapFloorTermPriceSurface::
    CPICapFloorTermPriceSurface(Real nominal, 
                                Real baseRate,                      // avoids an uncontrolled crash if index has no TS
                                const Period &observationLag,
                                const Calendar &cal,                // calendar in index may not be useful
                                const BusinessDayConvention &bdc,
                                const DayCounter &dc,
                                const Handle<ZeroInflationIndex>& zii,
                                const Handle<YieldTermStructure>& yts,
                                const std::vector<Rate> &cStrikes,
                                const std::vector<Rate> &fStrikes,
                                const std::vector<Period> &cfMaturities,
                                const Matrix &cPrice,
                                const Matrix &fPrice)
    : InflationTermStructure(0, cal, baseRate, observationLag, zii->frequency(), 
                             zii->interpolated(), dc),
      zii_(zii), nominalTS_(yts), cStrikes_(cStrikes), fStrikes_(fStrikes),
      cfMaturities_(cfMaturities), cPrice_(cPrice), fPrice_(fPrice),
      nominal_(nominal), bdc_(bdc) {

          // does the index have a TS?
          QL_REQUIRE(!zii_->zeroInflationTermStructure().empty(),"ZITS missing from index");
          QL_REQUIRE(!nominalTS_.empty(),"nominal TS missing");
              
        // data consistency checking, enough data?
        QL_REQUIRE(fStrikes_.size() > 1, "not enough floor strikes");
        QL_REQUIRE(cStrikes_.size() > 1, "not enough cap strikes");
        QL_REQUIRE(cfMaturities_.size() > 1, "not enough maturities");
        QL_REQUIRE(fStrikes_.size() == fPrice.rows(),
                   "floor strikes vs floor price rows not equal");
        QL_REQUIRE(cStrikes_.size() == cPrice.rows(),
                   "cap strikes vs cap price rows not equal");
        QL_REQUIRE(cfMaturities_.size() == fPrice.columns(),
                   "maturities vs floor price columns not equal");
        QL_REQUIRE(cfMaturities_.size() == cPrice.columns(),
                   "maturities vs cap price columns not equal");

        // data has correct properties (positive, monotonic)?
        for(Size j = 0; j <cfMaturities_.size(); j++) {
            QL_REQUIRE( cfMaturities[j] > Period(0,Days), "non-positive maturities");
            if(j>0) {
                QL_REQUIRE( cfMaturities[j] > cfMaturities[j-1],
                            "non-increasing maturities");
            }
            for(Size i = 0; i <fPrice_.rows(); i++) {
                QL_REQUIRE( fPrice_[i][j] > 0.0,
                            "non-positive floor price: " << fPrice_[i][j] );
                if(i>0) {
                    QL_REQUIRE( fPrice_[i][j] >= fPrice_[i-1][j],
                                "non-increasing floor prices");
                }
            }
            for(Size i = 0; i <cPrice_.rows(); i++) {
                QL_REQUIRE( cPrice_[i][j] > 0.0,
                            "non-positive cap price: " << cPrice_[i][j] );
                if(i>0) {
                    QL_REQUIRE( cPrice_[i][j] <= cPrice_[i-1][j],
                                "non-decreasing cap prices: " 
                               << cPrice_[i][j] << " then " << cPrice_[i-1][j]);
                }
            }
        }


        // Get the set of strikes, noting that repeats, overlaps are
        // expected between caps and floors but that no overlap in the
        // output is allowed so no repeats or overlaps are used
        cfStrikes_ = std::vector<Rate>();
        for(Size i = 0; i <fStrikes_.size(); i++)
            cfStrikes_.push_back( fStrikes[i] );
        Real eps = 0.0000001;
        Rate maxFstrike = fStrikes_.back();
        for(Size i = 0; i < cStrikes_.size(); i++) {
            Rate k = cStrikes[i];
            if (k > maxFstrike + eps) cfStrikes_.push_back(k);
        }

        // final consistency checking
        QL_REQUIRE(cfStrikes_.size() > 2, "overall not enough strikes");
        for (Size i = 1; i < cfStrikes_.size(); i++)
            QL_REQUIRE( cfStrikes_[i] > cfStrikes_[i-1],
                        "cfStrikes not increasing");
    }

    
    Date CPICapFloorTermPriceSurface::cpiOptionDateFromTenor(const Period& p) const
    {
        return Date(calendar().adjust(referenceDate() + p, businessDayConvention()));
    }

    
    Real CPICapFloorTermPriceSurface::price(const Period &d, Rate k) const {
        return this->price(cpiOptionDateFromTenor(d), k);
    }
    

    Real CPICapFloorTermPriceSurface::capPrice(const Period &d, Rate k) const {
        return this->capPrice(cpiOptionDateFromTenor(d), k);
    }
    

    Real CPICapFloorTermPriceSurface::floorPrice(const Period &d, Rate k) const {
        return this->floorPrice(cpiOptionDateFromTenor(d), k);
    }
    
    
    

}