19#include <ql/math/interpolations/bicubicsplineinterpolation.hpp>
20#include <ql/math/interpolations/bilinearinterpolation.hpp>
21#include <ql/quotes/simplequote.hpp>
22#include <ql/utilities/dataformatters.hpp>
32 BusinessDayConvention bdc,
const std::vector<Period>& optionTenors,
33 const std::vector<Rate>&
strikes,
34 const std::vector<std::vector<Handle<Quote> > >& vols,
35 const DayCounter& dc, InterpolationMethod interpolationMethod)
36 : CapFloorTermVolSurface(settlementDays, calendar, bdc, dc, optionTenors,
strikes), nOptionTenors_(optionTenors.size()),
37 optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_), nStrikes_(
strikes.size()), volHandles_(vols),
38 vols_(vols.size(), vols[0].size()), interpolationMethod_(interpolationMethod) {
40 initializeOptionDatesAndTimes();
41 for (Size i = 0; i < nOptionTenors_; ++i)
42 QL_REQUIRE(volHandles_[i].size() == nStrikes_, io::ordinal(i + 1)
43 <<
" row of vol handles has size " << volHandles_[i].size()
44 <<
" instead of " << nStrikes_);
45 registerWithMarketData();
46 for (Size i = 0; i < vols_.rows(); ++i)
47 for (Size j = 0; j < vols_.columns(); ++j)
48 vols_[i][j] = volHandles_[i][j]->value();
53CapFloorTermVolSurfaceExact::CapFloorTermVolSurfaceExact(
const Date& settlementDate,
const Calendar& calendar,
54 BusinessDayConvention bdc,
const std::vector<Period>& optionTenors,
55 const std::vector<Rate>&
strikes,
56 const std::vector<std::vector<Handle<Quote> > >& vols,
57 const DayCounter& dc, InterpolationMethod interpolationMethod)
58 : CapFloorTermVolSurface(settlementDate, calendar, bdc, dc, optionTenors,
strikes), nOptionTenors_(optionTenors.size()),
59 optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_), nStrikes_(
strikes.size()), volHandles_(vols),
60 vols_(vols.size(), vols[0].size()), interpolationMethod_(interpolationMethod) {
62 initializeOptionDatesAndTimes();
63 for (Size i = 0; i < nOptionTenors_; ++i)
64 QL_REQUIRE(volHandles_[i].size() == nStrikes_, io::ordinal(i + 1)
65 <<
" row of vol handles has size " << volHandles_[i].size()
66 <<
" instead of " << nStrikes_);
67 registerWithMarketData();
68 for (Size i = 0; i < vols_.rows(); ++i)
69 for (Size j = 0; j < vols_.columns(); ++j)
70 vols_[i][j] = volHandles_[i][j]->value();
75CapFloorTermVolSurfaceExact::CapFloorTermVolSurfaceExact(
const Date& settlementDate,
const Calendar& calendar,
76 BusinessDayConvention bdc,
const std::vector<Period>& optionTenors,
77 const std::vector<Rate>&
strikes,
const Matrix& vols,
78 const DayCounter& dc, InterpolationMethod interpolationMethod)
79 : CapFloorTermVolSurface(settlementDate, calendar, bdc, dc, optionTenors,
strikes), nOptionTenors_(optionTenors.size()),
80 optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_), nStrikes_(
strikes.size()), volHandles_(vols.rows()), vols_(vols),
81 interpolationMethod_(interpolationMethod) {
83 initializeOptionDatesAndTimes();
85 for (Size i = 0; i < nOptionTenors_; ++i) {
86 volHandles_[i].resize(nStrikes_);
87 for (Size j = 0; j < nStrikes_; ++j)
88 volHandles_[i][j] = Handle<Quote>(ext::shared_ptr<Quote>(
new SimpleQuote(vols_[i][j])));
94CapFloorTermVolSurfaceExact::CapFloorTermVolSurfaceExact(Natural settlementDays,
const Calendar& calendar,
95 BusinessDayConvention bdc,
const std::vector<Period>& optionTenors,
96 const std::vector<Rate>&
strikes,
const Matrix& vols,
97 const DayCounter& dc, InterpolationMethod interpolationMethod)
98 : CapFloorTermVolSurface(settlementDays, calendar, bdc, dc, optionTenors,
strikes), nOptionTenors_(optionTenors.size()),
99 optionDates_(nOptionTenors_), optionTimes_(nOptionTenors_),
100 nStrikes_(
strikes.size()), volHandles_(vols.rows()), vols_(vols),
101 interpolationMethod_(interpolationMethod) {
103 initializeOptionDatesAndTimes();
105 for (Size i = 0; i < nOptionTenors_; ++i) {
106 volHandles_[i].resize(nStrikes_);
107 for (Size j = 0; j < nStrikes_; ++j)
108 volHandles_[i][j] = Handle<Quote>(ext::shared_ptr<Quote>(
new SimpleQuote(vols_[i][j])));
113void CapFloorTermVolSurfaceExact::checkInputs()
const {
115 QL_REQUIRE(!optionTenors_.empty(),
"empty option tenor vector");
116 QL_REQUIRE(nOptionTenors_ == vols_.rows(),
"mismatch between number of option tenors ("
117 << nOptionTenors_ <<
") and number of volatility rows ("
118 << vols_.rows() <<
")");
119 QL_REQUIRE(optionTenors_[0] > 0 * Days,
"negative first option tenor: " << optionTenors_[0]);
120 for (Size i = 1; i < nOptionTenors_; ++i)
121 QL_REQUIRE(optionTenors_[i] > optionTenors_[i - 1],
122 "non increasing option tenor: " << io::ordinal(i) <<
" is " << optionTenors_[i - 1] <<
", "
123 << io::ordinal(i + 1) <<
" is " << optionTenors_[i]);
125 QL_REQUIRE(nStrikes_ == vols_.columns(),
126 "mismatch between strikes(" << strikes_.size() <<
") and vol columns (" << vols_.columns() <<
")");
127 for (Size j = 1; j < nStrikes_; ++j)
128 QL_REQUIRE(strikes_[j - 1] < strikes_[j],
129 "non increasing strikes: " << io::ordinal(j) <<
" is " << io::rate(strikes_[j - 1]) <<
", "
130 << io::ordinal(j + 1) <<
" is " << io::rate(strikes_[j]));
133void CapFloorTermVolSurfaceExact::registerWithMarketData() {
134 for (Size i = 0; i < nOptionTenors_; ++i)
135 for (Size j = 0; j < nStrikes_; ++j)
136 registerWith(volHandles_[i][j]);
139void CapFloorTermVolSurfaceExact::interpolate() {
140 if (interpolationMethod_ == BicubicSpline)
142 QuantLib::BicubicSpline(strikes_.begin(), strikes_.end(), optionTimes_.begin(), optionTimes_.end(), vols_);
143 else if (interpolationMethod_ == Bilinear)
145 BilinearInterpolation(strikes_.begin(), strikes_.end(), optionTimes_.begin(), optionTimes_.end(), vols_);
147 QL_FAIL(
"Invalid InterpolationMethod");
151void CapFloorTermVolSurfaceExact::update() {
154 Date d = Settings::instance().evaluationDate();
155 if (evaluationDate_ != d) {
157 initializeOptionDatesAndTimes();
160 CapFloorTermVolSurface::update();
163void CapFloorTermVolSurfaceExact::initializeOptionDatesAndTimes()
const {
164 for (Size i = 0; i < nOptionTenors_; ++i) {
165 optionDates_[i] = optionDateFromTenor(optionTenors_[i]);
166 optionTimes_[i] = timeFromReference(optionDates_[i]);
170void CapFloorTermVolSurfaceExact::performCalculations()
const {
173 for (Size i = 0; i < nOptionTenors_; ++i)
174 for (Size j = 0; j < nStrikes_; ++j)
175 vols_[i][j] = volHandles_[i][j]->value();
177 interpolation_.update();
182 case CapFloorTermVolSurfaceExact::BicubicSpline:
183 return out <<
"BicubicSpline";
184 case CapFloorTermVolSurfaceExact::Bilinear:
185 return out <<
"Bilinear";
187 QL_FAIL(
"Unknown CapFloorTermVolSurface::InterpolationMethod (" << Integer(method) <<
")");
Cap/floor smile volatility surface.
CapFloorTermVolSurfaceExact(Natural settlementDays, const Calendar &calendar, BusinessDayConvention bdc, const std::vector< Period > &optionTenors, const std::vector< Rate > &strikes, const std::vector< std::vector< Handle< Quote > > > &, const DayCounter &dc=Actual365Fixed(), InterpolationMethod interpolationMethod=BicubicSpline)
floating reference date, floating market data
std::ostream & operator<<(std::ostream &out, EquityReturnType t)