Skip to content

Commit ece7be2

Browse files
pcaspersjenkins
authored andcommitted
QPR-12159 add mixed interpolation schemes to curve builder
1 parent c7830fb commit ece7be2

2 files changed

Lines changed: 186 additions & 19 deletions

File tree

OREData/ored/marketdata/yieldcurve.cpp

Lines changed: 174 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <ql/indexes/ibor/all.hpp>
4040
#include <ql/math/interpolations/convexmonotoneinterpolation.hpp>
41+
#include <ql/math/interpolations/mixedinterpolation.hpp>
4142
#include <qle/indexes/ibor/brlcdi.hpp>
4243
#include <qle/math/logquadraticinterpolation.hpp>
4344
#include <qle/math/quadraticinterpolation.hpp>
@@ -100,7 +101,7 @@ namespace data {
100101
template <template <class> class CurveType>
101102
boost::shared_ptr<YieldTermStructure> buildYieldCurve(const vector<Date>& dates, const vector<QuantLib::Real>& rates,
102103
const DayCounter& dayCounter,
103-
YieldCurve::InterpolationMethod interpolationMethod) {
104+
YieldCurve::InterpolationMethod interpolationMethod, Size n) {
104105

105106
boost::shared_ptr<YieldTermStructure> yieldts;
106107
switch (interpolationMethod) {
@@ -140,28 +141,45 @@ boost::shared_ptr<YieldTermStructure> buildYieldCurve(const vector<Date>& dates,
140141
CubicInterpolation::SecondDerivative, 0.0,
141142
CubicInterpolation::SecondDerivative, 0.0)));
142143
break;
143-
default:
144-
QL_FAIL("Interpolation method not recognised.");
144+
case YieldCurve::InterpolationMethod::DefaultLogMixedLinearCubic:
145+
yieldts.reset(
146+
new CurveType<DefaultLogMixedLinearCubic>(dates, rates, dayCounter, DefaultLogMixedLinearCubic(n)));
147+
break;
148+
case YieldCurve::InterpolationMethod::MonotonicLogMixedLinearCubic:
149+
yieldts.reset(
150+
new CurveType<MonotonicLogMixedLinearCubic>(dates, rates, dayCounter, MonotonicLogMixedLinearCubic(n)));
151+
break;
152+
case YieldCurve::InterpolationMethod::KrugerLogMixedLinearCubic:
153+
yieldts.reset(
154+
new CurveType<KrugerLogMixedLinearCubic>(dates, rates, dayCounter, KrugerLogMixedLinearCubic(n)));
155+
break;
156+
case YieldCurve::InterpolationMethod::LogMixedLinearCubicNaturalSpline:
157+
yieldts.reset(new CurveType<LogMixedLinearCubicNaturalSpline>(dates, rates, dayCounter,
158+
LogMixedLinearCubicNaturalSpline(n)));
159+
break;
160+
161+
default:
162+
QL_FAIL("Interpolation method '" << interpolationMethod_ << "' not recognised.");
145163
}
146164
return yieldts;
147165
}
148166

149167
boost::shared_ptr<YieldTermStructure> zerocurve(const vector<Date>& dates, const vector<Rate>& yields,
150168
const DayCounter& dayCounter,
151-
YieldCurve::InterpolationMethod interpolationMethod) {
152-
return buildYieldCurve<InterpolatedZeroCurve>(dates, yields, dayCounter, interpolationMethod);
169+
YieldCurve::InterpolationMethod interpolationMethod, Size n) {
170+
return buildYieldCurve<InterpolatedZeroCurve>(dates, yields, dayCounter, interpolationMethod, n);
153171
}
154172

155173
boost::shared_ptr<YieldTermStructure> discountcurve(const vector<Date>& dates, const vector<DiscountFactor>& dfs,
156174
const DayCounter& dayCounter,
157-
YieldCurve::InterpolationMethod interpolationMethod) {
158-
return buildYieldCurve<InterpolatedDiscountCurve>(dates, dfs, dayCounter, interpolationMethod);
175+
YieldCurve::InterpolationMethod interpolationMethod, Size n) {
176+
return buildYieldCurve<InterpolatedDiscountCurve>(dates, dfs, dayCounter, interpolationMethod, n);
159177
}
160178

161179
boost::shared_ptr<YieldTermStructure> forwardcurve(const vector<Date>& dates, const vector<Rate>& forwards,
162180
const DayCounter& dayCounter,
163-
YieldCurve::InterpolationMethod interpolationMethod) {
164-
return buildYieldCurve<InterpolatedForwardCurve>(dates, forwards, dayCounter, interpolationMethod);
181+
YieldCurve::InterpolationMethod interpolationMethod, Size n) {
182+
return buildYieldCurve<InterpolatedForwardCurve>(dates, forwards, dayCounter, interpolationMethod, n);
165183
}
166184

167185
/* Helper functions
@@ -187,6 +205,14 @@ YieldCurve::InterpolationMethod parseYieldCurveInterpolationMethod(const string&
187205
return YieldCurve::InterpolationMethod::Hermite;
188206
else if (s == "CubicSpline")
189207
return YieldCurve::InterpolationMethod::CubicSpline;
208+
else if (s == "DefaultLogMixedLinearCubic")
209+
return YieldCurve::InterpolationMethod::DefaultLogMixedLinearCubic;
210+
else if (s == "MonotonicLogMixedLinearCubic")
211+
return YieldCurve::InterpolationMethod::MonotonicLogMixedLinearCubic;
212+
else if (s == "KrugerLogMixedLinearCubic")
213+
return YieldCurve::InterpolationMethod::KrugerLogMixedLinearCubic;
214+
else if (s == "LogMixedLinearCubicNaturalSpline")
215+
return YieldCurve::InterpolationMethod::LogMixedLinearCubicNaturalSpline;
190216
else if (s == "NelsonSiegel")
191217
return YieldCurve::InterpolationMethod::NelsonSiegel;
192218
else if (s == "Svensson")
@@ -206,6 +232,43 @@ YieldCurve::InterpolationVariable parseYieldCurveInterpolationVariable(const str
206232
QL_FAIL("Yield curve interpolation variable " << s << " not recognized");
207233
};
208234

235+
std::ostream& operator<<(std::ostream& out, const YieldCurve::InterpolationMethod m) {
236+
if (m == YieldCurve::InterpolationMethod::Linear)
237+
return out << "Linear";
238+
else if (m == YieldCurve::InterpolationMethod::LogLinear)
239+
return out << "LogLinear";
240+
else if (m == YieldCurve::InterpolationMethod::NaturalCubic)
241+
return out << "NaturalCubic";
242+
else if (m == YieldCurve::InterpolationMethod::FinancialCubic)
243+
return out << "FinancialCubic";
244+
else if (m == YieldCurve::InterpolationMethod::ConvexMonotone)
245+
return out << "ConvexMonotone";
246+
else if (m == YieldCurve::InterpolationMethod::ExponentialSplines)
247+
return out << "ExponentialSplines";
248+
else if (m == YieldCurve::InterpolationMethod::Quadratic)
249+
return out << "Quadratic";
250+
else if (m == YieldCurve::InterpolationMethod::LogQuadratic)
251+
return out << "LogQuadratic";
252+
else if (m == YieldCurve::InterpolationMethod::Hermite)
253+
return out << "Hermite";
254+
else if (m == YieldCurve::InterpolationMethod::CubicSpline)
255+
return out << "CubicSpline";
256+
else if (m == YieldCurve::InterpolationMethod::DefaultLogMixedLinearCubic)
257+
return out << "DefaultLogMixedLinearCubic";
258+
else if (m == YieldCurve::InterpolationMethod::MonotonicLogMixedLinearCubic)
259+
return out << "MonotonicLogMixedLinearCubic";
260+
else if (m == YieldCurve::InterpolationMethod::KrugerLogMixedLinearCubic)
261+
return out << "KrugerLogMixedLinearCubic";
262+
else if (m == YieldCurve::InterpolationMethod::LogMixedLinearCubicNaturalSpline)
263+
return out << "LogMixedLinearCubicNaturalSpline";
264+
else if (m == YieldCurve::InterpolationMethod::NelsonSiegel)
265+
return out << "NelsonSiegel";
266+
else if (m == YieldCurve::InterpolationMethod::Svensson)
267+
return out << "Svensson";
268+
else
269+
QL_FAIL("Yield curve interpolation method " << static_cast<int>(m) << " not recognized");
270+
}
271+
209272
YieldCurve::YieldCurve(Date asof, YieldCurveSpec curveSpec, const CurveConfigurations& curveConfigs,
210273
const Loader& loader, const map<string, boost::shared_ptr<YieldCurve>>& requiredYieldCurves,
211274
const map<string, boost::shared_ptr<DefaultCurve>>& requiredDefaultCurves,
@@ -416,8 +479,40 @@ YieldCurve::piecewisecurve(vector<boost::shared_ptr<RateHelper>> instruments) {
416479
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
417480
minFactor, dontThrowSteps));
418481
} break;
482+
case InterpolationMethod::DefaultLogMixedLinearCubic: {
483+
typedef PiecewiseYieldCurve<ZeroYield, DefaultLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
484+
ATTR_UNUSED typedef my_curve::traits_type dummy;
485+
yieldts = boost::make_shared<my_curve>(
486+
asofDate_, instruments, zeroDayCounter_, DefaultLogMixedLinearCubic(n),
487+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
488+
minFactor, dontThrowSteps));
489+
} break;
490+
case InterpolationMethod::MonotonicLogMixedLinearCubic: {
491+
typedef PiecewiseYieldCurve<ZeroYield, MonotonicLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
492+
ATTR_UNUSED typedef my_curve::traits_type dummy;
493+
yieldts = boost::make_shared<my_curve>(
494+
asofDate_, instruments, zeroDayCounter_, MonotonicLogMixedLinearCubic(n),
495+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
496+
minFactor, dontThrowSteps));
497+
} break;
498+
case InterpolationMethod::KrugerLogMixedLinearCubic: {
499+
typedef PiecewiseYieldCurve<ZeroYield, KrugerLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
500+
ATTR_UNUSED typedef my_curve::traits_type dummy;
501+
yieldts = boost::make_shared<my_curve>(
502+
asofDate_, instruments, zeroDayCounter_, KrugerLogMixedLinearCubic(n),
503+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
504+
minFactor, dontThrowSteps));
505+
} break;
506+
case InterpolationMethod::LogMixedLinearCubicNaturalSpline: {
507+
typedef PiecewiseYieldCurve<ZeroYield, LogMixedLinearCubicNaturalSpline, QuantExt::IterativeBootstrap> my_curve;
508+
ATTR_UNUSED typedef my_curve::traits_type dummy;
509+
yieldts = boost::make_shared<my_curve>(
510+
asofDate_, instruments, zeroDayCounter_, LogMixedLinearCubicNaturalSpline(n),
511+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
512+
minFactor, dontThrowSteps));
513+
} break;
419514
default:
420-
QL_FAIL("Interpolation method not recognised.");
515+
QL_FAIL("Interpolation method '" << interpolationMethod_ << "' not recognised.");
421516
}
422517
break;
423518
case InterpolationVariable::Discount:
@@ -499,8 +594,40 @@ YieldCurve::piecewisecurve(vector<boost::shared_ptr<RateHelper>> instruments) {
499594
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
500595
minFactor, dontThrowSteps));
501596
} break;
597+
case InterpolationMethod::DefaultLogMixedLinearCubic: {
598+
typedef PiecewiseYieldCurve<Discount, DefaultLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
599+
ATTR_UNUSED typedef my_curve::traits_type dummy;
600+
yieldts = boost::make_shared<my_curve>(
601+
asofDate_, instruments, zeroDayCounter_, DefaultLogMixedLinearCubic(n),
602+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
603+
minFactor, dontThrowSteps));
604+
} break;
605+
case InterpolationMethod::MonotonicLogMixedLinearCubic: {
606+
typedef PiecewiseYieldCurve<Discount, MonotonicLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
607+
ATTR_UNUSED typedef my_curve::traits_type dummy;
608+
yieldts = boost::make_shared<my_curve>(
609+
asofDate_, instruments, zeroDayCounter_, MonotonicLogMixedLinearCubic(n),
610+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
611+
minFactor, dontThrowSteps));
612+
} break;
613+
case InterpolationMethod::KrugerLogMixedLinearCubic: {
614+
typedef PiecewiseYieldCurve<Discount, KrugerLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
615+
ATTR_UNUSED typedef my_curve::traits_type dummy;
616+
yieldts = boost::make_shared<my_curve>(
617+
asofDate_, instruments, zeroDayCounter_, KrugerLogMixedLinearCubic(n),
618+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
619+
minFactor, dontThrowSteps));
620+
} break;
621+
case InterpolationMethod::LogMixedLinearCubicNaturalSpline: {
622+
typedef PiecewiseYieldCurve<Discount, LogMixedLinearCubicNaturalSpline, QuantExt::IterativeBootstrap> my_curve;
623+
ATTR_UNUSED typedef my_curve::traits_type dummy;
624+
yieldts = boost::make_shared<my_curve>(
625+
asofDate_, instruments, zeroDayCounter_, LogMixedLinearCubicNaturalSpline(n),
626+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
627+
minFactor, dontThrowSteps));
628+
} break;
502629
default:
503-
QL_FAIL("Interpolation method not recognised.");
630+
QL_FAIL("Interpolation method '" << interpolationMethod_ << "' not recognised.");
504631
}
505632
break;
506633
case InterpolationVariable::Forward:
@@ -581,8 +708,40 @@ YieldCurve::piecewisecurve(vector<boost::shared_ptr<RateHelper>> instruments) {
581708
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
582709
minFactor, dontThrowSteps));
583710
} break;
711+
case InterpolationMethod::DefaultLogMixedLinearCubic: {
712+
typedef PiecewiseYieldCurve<ForwardRate, DefaultLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
713+
ATTR_UNUSED typedef my_curve::traits_type dummy;
714+
yieldts = boost::make_shared<my_curve>(
715+
asofDate_, instruments, zeroDayCounter_, DefaultLogMixedLinearCubic(n),
716+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
717+
minFactor, dontThrowSteps));
718+
} break;
719+
case InterpolationMethod::MonotonicLogMixedLinearCubic: {
720+
typedef PiecewiseYieldCurve<ForwardRate, MonotonicLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
721+
ATTR_UNUSED typedef my_curve::traits_type dummy;
722+
yieldts = boost::make_shared<my_curve>(
723+
asofDate_, instruments, zeroDayCounter_, MonotonicLogMixedLinearCubic(n),
724+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
725+
minFactor, dontThrowSteps));
726+
} break;
727+
case InterpolationMethod::KrugerLogMixedLinearCubic: {
728+
typedef PiecewiseYieldCurve<ForwardRate, KrugerLogMixedLinearCubic, QuantExt::IterativeBootstrap> my_curve;
729+
ATTR_UNUSED typedef my_curve::traits_type dummy;
730+
yieldts = boost::make_shared<my_curve>(
731+
asofDate_, instruments, zeroDayCounter_, KrugerLogMixedLinearCubic(n),
732+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
733+
minFactor, dontThrowSteps));
734+
} break;
735+
case InterpolationMethod::LogMixedLinearCubicNaturalSpline: {
736+
typedef PiecewiseYieldCurve<ForwardRate, LogMixedLinearCubicNaturalSpline, QuantExt::IterativeBootstrap> my_curve;
737+
ATTR_UNUSED typedef my_curve::traits_type dummy;
738+
yieldts = boost::make_shared<my_curve>(
739+
asofDate_, instruments, zeroDayCounter_, LogMixedLinearCubicNaturalSpline(n),
740+
QuantExt::IterativeBootstrap<my_curve>(accuracy, globalAccuracy, dontThrow, maxAttempts, maxFactor,
741+
minFactor, dontThrowSteps));
742+
} break;
584743
default:
585-
QL_FAIL("Interpolation method not recognised.");
744+
QL_FAIL("Interpolation method '" << interpolationMethod_ << "' not recognised.");
586745
}
587746
break;
588747
default:
@@ -615,11 +774,11 @@ YieldCurve::piecewisecurve(vector<boost::shared_ptr<RateHelper>> instruments) {
615774
zeros[0] = zeros[1];
616775
forwards[0] = forwards[1];
617776
if (interpolationVariable_ == InterpolationVariable::Zero)
618-
p_ = zerocurve(dates, zeros, zeroDayCounter_, interpolationMethod_);
777+
p_ = zerocurve(dates, zeros, zeroDayCounter_, interpolationMethod_, mixedInterpolationSize_);
619778
else if (interpolationVariable_ == InterpolationVariable::Discount)
620-
p_ = discountcurve(dates, discounts, zeroDayCounter_, interpolationMethod_);
779+
p_ = discountcurve(dates, discounts, zeroDayCounter_, interpolationMethod_, mixedInterpolationSize_);
621780
else if (interpolationVariable_ == InterpolationVariable::Forward)
622-
p_ = forwardcurve(dates, forwards, zeroDayCounter_, interpolationMethod_);
781+
p_ = forwardcurve(dates, forwards, zeroDayCounter_, interpolationMethod_, mixedInterpolationSize_);
623782
else
624783
QL_FAIL("Interpolation variable not recognised.");
625784
}

0 commit comments

Comments
 (0)