23#ifndef quantext_option_interpolator_2d_hpp
24#define quantext_option_interpolator_2d_hpp
26#include <ql/math/interpolation.hpp>
27#include <ql/patterns/observable.hpp>
28#include <ql/time/date.hpp>
29#include <ql/time/daycounters/actual365fixed.hpp>
37 bool operator()(
const QuantLib::Real w)
const {
return QuantLib::close_enough(
v_, w); }
51 virtual QuantLib::Real
getValue(QuantLib::Time t, QuantLib::Real strike)
const = 0;
52 virtual QuantLib::Real
getValue(QuantLib::Date d, QuantLib::Real strike)
const = 0;
58 std::vector<std::vector<QuantLib::Real> >
values()
const {
return values_; };
63 std::vector<std::vector<QuantLib::Real> >
strikes_;
64 std::vector<std::vector<QuantLib::Real> >
values_;
70template <
class InterpolatorStrike,
class InterpolatorExpiry>
76 bool lowerStrikeConstExtrap =
true,
bool upperStrikeConstExtrap =
true,
77 const InterpolatorStrike& interpolatorStrike = InterpolatorStrike(),
78 const InterpolatorExpiry& interpolatorExpiry = InterpolatorExpiry(),
79 const QuantLib::Date& baseDate = QuantLib::Date())
87 const std::vector<QuantLib::Date>& dates,
const std::vector<QuantLib::Real>&
strikes,
88 const std::vector<QuantLib::Real>&
values,
bool lowerStrikeConstExtrap =
true,
89 bool upperStrikeConstExtrap =
true,
90 const InterpolatorStrike& interpolatorStrike = InterpolatorStrike(),
91 const InterpolatorExpiry& interpolatorExpiry = InterpolatorExpiry(),
92 const QuantLib::Date& baseDate = QuantLib::Date());
96 const QuantLib::BusinessDayConvention& bdc,
const QuantLib::DayCounter&
dayCounter,
97 const std::vector<QuantLib::Period>& tenors,
const std::vector<QuantLib::Real>&
strikes,
98 const std::vector<QuantLib::Real>&
values,
bool lowerStrikeConstExtrap =
true,
99 bool upperStrikeConstExtrap =
true,
100 const InterpolatorStrike& interpolatorStrike = InterpolatorStrike(),
101 const InterpolatorExpiry& interpolatorExpiry = InterpolatorExpiry(),
102 const QuantLib::Date& baseDate = QuantLib::Date());
110 void initialise(
const std::vector<QuantLib::Date>& dates,
const std::vector<QuantLib::Real>&
strikes,
111 const std::vector<QuantLib::Real>&
values);
112 void initialise(
const std::vector<QuantLib::Period>& tenors,
const std::vector<QuantLib::Real>&
strikes,
113 const std::vector<QuantLib::Real>&
values,
const QuantLib::Calendar& calendar,
114 const QuantLib::BusinessDayConvention& bdc);
118 std::vector<QuantLib::Time>
times()
const;
120 std::vector<std::vector<QuantLib::Real> >
strikes()
const;
121 std::vector<std::vector<QuantLib::Real> >
values()
const;
123 QuantLib::Real
getValue(QuantLib::Time t, QuantLib::Real strike)
const override;
124 QuantLib::Real
getValue(QuantLib::Date d, QuantLib::Real strike)
const override;
132 QuantLib::Real
getValueForStrike(QuantLib::Real strike,
const std::vector<QuantLib::Real>& strks,
133 const std::vector<QuantLib::Real>& vars,
134 const QuantLib::Interpolation& intrp)
const;
145template <
class InterpolatorStrike,
class InterpolatorExpiry>
147 const QuantLib::Date& referenceDate,
const QuantLib::DayCounter& dayCounter,
148 const std::vector<QuantLib::Date>& dates,
const std::vector<QuantLib::Real>&
strikes,
149 const std::vector<QuantLib::Real>& values,
bool lowerStrikeConstExtrap,
bool upperStrikeConstExtrap,
150 const InterpolatorStrike& interpolatorStrike,
151 const InterpolatorExpiry& interpolatorExpiry,
152 const QuantLib::Date& baseDate)
153 :
OptionInterpolatorBase(referenceDate), dayCounter_(dayCounter), lowerStrikeConstExtrap_(lowerStrikeConstExtrap),
154 upperStrikeConstExtrap_(upperStrikeConstExtrap), interpolatorStrike_(interpolatorStrike),
155 interpolatorExpiry_(interpolatorExpiry), initialised_(false),
156 baseDate_(baseDate ==
QuantLib::Date() ? referenceDate : baseDate) {
161template <
class InterpolatorStrike,
class InterpolatorExpiry>
163 const QuantLib::Date& referenceDate,
const QuantLib::Calendar& calendar,
164 const QuantLib::BusinessDayConvention& bdc,
const QuantLib::DayCounter& dayCounter,
165 const std::vector<QuantLib::Period>& tenors,
const std::vector<QuantLib::Real>&
strikes,
166 const std::vector<QuantLib::Real>& values,
bool lowerStrikeConstExtrap,
bool upperStrikeConstExtrap,
const InterpolatorStrike& interpolatorStrike,
167 const InterpolatorExpiry& interpolatorExpiry,
const QuantLib::Date& baseDate)
168 :
OptionInterpolatorBase(referenceDate), dayCounter_(dayCounter), lowerStrikeConstExtrap_(lowerStrikeConstExtrap),
169 upperStrikeConstExtrap_(upperStrikeConstExtrap), interpolatorStrike_(interpolatorStrike),
170 interpolatorExpiry_(interpolatorExpiry), initialised_(false),
171 baseDate_(baseDate ==
QuantLib::Date() ? referenceDate : baseDate) {
176template <
class IS,
class IE>
178 const std::vector<QuantLib::Real>&
strikes,
179 const std::vector<QuantLib::Real>& values) {
180 using QuantLib::Date;
181 using QuantLib::Interpolation;
182 using QuantLib::Real;
183 using QuantLib::Size;
184 using QuantLib::Time;
188 QL_REQUIRE((
strikes.size() == dates.size()) && (dates.size() == values.size()),
189 "dates, strikes and values vectors not of equal size.");
192 set<Date> datesSet(dates.begin(), dates.end());
193 expiries_ = vector<Date>(datesSet.begin(), datesSet.end());
194 vector<bool> dateDone(expiries_.size(),
false);
195 times_ = vector<Time>(expiries_.size());
196 interpolations_ = vector<Interpolation>(expiries_.size());
197 values_ = vector<vector<Real> >(expiries_.size());
198 strikes_ = vector<vector<Real> >(expiries_.size());
201 for (Size i = 0; i < dates.size(); i++) {
202 vector<Date>::iterator found = find(expiries_.begin(), expiries_.end(), dates[i]);
203 QL_REQUIRE(found != expiries_.end(),
"Date should already be loaded" << dates[i]);
205 ii = distance(expiries_.begin(), found);
209 QL_REQUIRE(dates[i] >= referenceDate_,
210 "Expiry date:" << dates[i] <<
" before asof date: " << referenceDate_);
211 times_[ii] = dayCounter_.yearFraction(referenceDate_, dates[i]);
212 strikes_[ii].push_back(
strikes[i]);
213 values_[ii].push_back(values[i]);
218 vector<Real>::iterator fnd =
220 if (fnd == strikes_[ii].end()) {
222 strikes_[ii].push_back(
strikes[i]);
223 values_[ii].push_back(values[i]);
229 for (Size i = 0; i < expiries_.size(); i++)
230 QL_REQUIRE(strikes_[i].size() == values_[i].size(),
231 "different number of variances and strikes for date: " << expiries_[i]);
234 for (Size i = 0; i < expiries_.size(); i++) {
236 vector<pair<Real, Real> > tmpPairs(strikes_[i].size());
237 vector<Real> sortedStrikes;
238 vector<Real> sortedVals;
239 for (Size j = 0; j < strikes_[i].size(); j++) {
240 tmpPairs[j] = pair<Real, Real>(strikes_[i][j], values_[i][j]);
242 sort(tmpPairs.begin(), tmpPairs.end());
243 for (vector<pair<Real, Real> >::iterator it = tmpPairs.begin(); it != tmpPairs.end(); it++) {
244 sortedStrikes.push_back(it->first);
245 sortedVals.push_back(it->second);
247 strikes_[i] = sortedStrikes;
248 values_[i] = sortedVals;
251 if (strikes_[i].size() == 1) {
255 interpolatorStrike_.interpolate(strikes_[i].begin(), strikes_[i].end(), values_[i].begin());
257 interpolations_[i].enableExtrapolation();
262template <
class IS,
class IE>
264 const std::vector<QuantLib::Real>&
strikes,
265 const std::vector<QuantLib::Real>& values,
266 const QuantLib::Calendar& calendar,
267 const QuantLib::BusinessDayConvention& bdc) {
269 std::vector<QuantLib::Date> dates;
270 for (
auto t : tenors)
271 dates.push_back(calendar.advance(referenceDate(), t, bdc));
273 initialise(dates,
strikes, values);
276template <
class IS,
class IE>
278 const std::vector<QuantLib::Real>& strks,
279 const std::vector<QuantLib::Real>& vars,
280 const QuantLib::Interpolation& intrp)
const {
281 QL_REQUIRE(!strks.empty(),
"OptionInterpolator2d: no strikes given");
282 QL_REQUIRE(strks.size() == vars.size(),
"OptionInterpolator2d: strikes size ("
283 << strks.size() <<
") does not match vars size (" << vars.size()
285 QuantLib::Real retVar;
286 if (strike > strks.back() && upperStrikeConstExtrap_) {
287 retVar = vars.back();
288 }
else if (strike < strks.front() && lowerStrikeConstExtrap_) {
289 retVar = vars.front();
291 retVar = intrp(strike);
296template <
class IS,
class IE>
298 using QuantLib::Interpolation;
299 using QuantLib::Real;
300 using QuantLib::Size;
301 using QuantLib::Time;
303 Time baseTime = dayCounter_.yearFraction(referenceDate_, baseDate_);
304 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
305 QL_REQUIRE(t >= baseTime,
"Variance requested for date before base date: " << baseDate_);
306 if (QuantLib::close_enough(t,baseTime)) {
308 QL_REQUIRE(!values_.empty(),
"OptionInterpolator2d: no expiries given");
309 QL_REQUIRE(!values_.front().empty(),
"OptionInterpolator2d: no value for first expiry given");
310 return values_[0][0];
312 QL_REQUIRE(!expiries_.empty(),
"OptionInterpolator2d: no expiry given");
313 if (expiries_.size() == 1) {
314 return getValueForStrike(strike, strikes_[0], values_[0], interpolations_[0]);
318 if (t <= times_.front()) {
322 }
else if (t > times_.back()) {
324 ind1 = times_.size() - 2;
325 ind2 = times_.size() - 1;
328 ind2 = distance(times_.begin(), lower_bound(times_.begin(), times_.end(), t));
329 ind1 = (ind2 != 0) ? ind2 - 1 : 0;
332 vector<Real> tmpVars(2);
334 xAxis.push_back(times_[ind1]);
335 xAxis.push_back(times_[ind2]);
337 tmpVars[0] = getValueForStrike(strike, strikes_[ind1], values_[ind1], interpolations_[ind1]);
338 tmpVars[1] = getValueForStrike(strike, strikes_[ind2], values_[ind2], interpolations_[ind2]);
339 Interpolation interp = interpolatorExpiry_.interpolate(xAxis.begin(), xAxis.end(), tmpVars.begin());
341 interp.enableExtrapolation(
true);
346template <
class IS,
class IE>
348 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
349 QL_REQUIRE(d >= baseDate_,
"Variance requested for date before reference date: " << baseDate_);
350 QuantLib::Real valueReturn;
352 std::vector<QuantLib::Date>::const_iterator it = find(expiries_.begin(), expiries_.end(), d);
354 if (it != expiries_.end()) {
355 QuantLib::Size dis = distance(expiries_.begin(), it);
356 valueReturn = getValueForStrike(strike, strikes_[dis], values_[dis], interpolations_[dis]);
358 QuantLib::Time t = dayCounter_.yearFraction(referenceDate_, d);
359 valueReturn = getValue(t, strike);
365 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
370 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
375 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
380 QL_REQUIRE(initialised_,
"No data provided to OptionInterpolator2d");
Constant-interpolation factory and traits
QuantLib::Interpolation interpolate(const Real &y) const
std::vector< QuantLib::Date > expiries() const
bool upperStrikeConstExtrap_
std::vector< QuantLib::Interpolation > interpolations_
OptionInterpolator2d & operator=(const OptionInterpolator2d &)=delete
OptionInterpolator2d(const OptionInterpolator2d &)=delete
QuantLib::Real getValueForStrike(QuantLib::Real strike, const std::vector< QuantLib::Real > &strks, const std::vector< QuantLib::Real > &vars, const QuantLib::Interpolation &intrp) const
std::vector< std::vector< QuantLib::Real > > strikes() const
OptionInterpolator2d(const QuantLib::Date &referenceDate, const QuantLib::Calendar &calendar, const QuantLib::BusinessDayConvention &bdc, const QuantLib::DayCounter &dayCounter, const std::vector< QuantLib::Period > &tenors, const std::vector< QuantLib::Real > &strikes, const std::vector< QuantLib::Real > &values, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, const InterpolatorStrike &interpolatorStrike=InterpolatorStrike(), const InterpolatorExpiry &interpolatorExpiry=InterpolatorExpiry(), const QuantLib::Date &baseDate=QuantLib::Date())
OptionInterpolator2d Constructor with Tenors.
void initialise(const std::vector< QuantLib::Period > &tenors, const std::vector< QuantLib::Real > &strikes, const std::vector< QuantLib::Real > &values, const QuantLib::Calendar &calendar, const QuantLib::BusinessDayConvention &bdc)
std::vector< std::vector< QuantLib::Real > > values() const
void initialise(const std::vector< QuantLib::Date > &dates, const std::vector< QuantLib::Real > &strikes, const std::vector< QuantLib::Real > &values)
Initialise.
InterpolatorStrike interpolatorStrike_
OptionInterpolator2d(const QuantLib::Date &referenceDate, const QuantLib::DayCounter &dayCounter, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, const InterpolatorStrike &interpolatorStrike=InterpolatorStrike(), const InterpolatorExpiry &interpolatorExpiry=InterpolatorExpiry(), const QuantLib::Date &baseDate=QuantLib::Date())
OptionInterpolator2d default Constructor.
QuantLib::Real getValue(QuantLib::Date d, QuantLib::Real strike) const override
QuantLib::DayCounter dayCounter_
InterpolatorExpiry interpolatorExpiry_
bool lowerStrikeConstExtrap_
QuantLib::DayCounter dayCounter() const
OptionInterpolator2d(const QuantLib::Date &referenceDate, const QuantLib::DayCounter &dayCounter, const std::vector< QuantLib::Date > &dates, const std::vector< QuantLib::Real > &strikes, const std::vector< QuantLib::Real > &values, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, const InterpolatorStrike &interpolatorStrike=InterpolatorStrike(), const InterpolatorExpiry &interpolatorExpiry=InterpolatorExpiry(), const QuantLib::Date &baseDate=QuantLib::Date())
OptionInterpolator2d Constructor with dates.
QuantLib::Real getValue(QuantLib::Time t, QuantLib::Real strike) const override
virtual access methods
std::vector< QuantLib::Time > times() const
Option surface interpolator base.
std::vector< QuantLib::Date > expiries() const
std::vector< std::vector< QuantLib::Real > > strikes_
virtual QuantLib::Real getValue(QuantLib::Date d, QuantLib::Real strike) const =0
std::vector< std::vector< QuantLib::Real > > strikes() const
OptionInterpolatorBase(const QuantLib::Date &referenceDate)
std::vector< std::vector< QuantLib::Real > > values() const
QuantLib::Date referenceDate_
std::vector< QuantLib::Time > times_
std::vector< QuantLib::Date > expiries_
virtual QuantLib::Real getValue(QuantLib::Time t, QuantLib::Real strike) const =0
virtual access methods
virtual ~OptionInterpolatorBase()
const QuantLib::Date & referenceDate() const
std::vector< std::vector< QuantLib::Real > > values_
std::vector< QuantLib::Time > times() const
flat interpolation decorator
CloseEnoughComparator(const QuantLib::Real v)
bool operator()(const QuantLib::Real w) const