Skip to content

Commit 50e286f

Browse files
committed
Remove day counter argument from spreaded curves
Spreaded curves always use the same day counter as the original curve. It's not possible to support a different day counter without some API changes on the base YieldTermStructure. Currently these classes simply ignore the passed day counter. Deprecate the current constructors and add new ones that do not take a day counter.
1 parent d823f4e commit 50e286f

File tree

6 files changed

+99
-97
lines changed

6 files changed

+99
-97
lines changed

ql/cashflows/cashflows.cpp

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,55 +1142,6 @@ namespace QuantLib {
11421142
}
11431143

11441144
// Z-spread utility functions
1145-
namespace {
1146-
1147-
class ZSpreadFinder {
1148-
public:
1149-
ZSpreadFinder(const Leg& leg,
1150-
const ext::shared_ptr<YieldTermStructure>& discountCurve,
1151-
Real npv,
1152-
const DayCounter& dc,
1153-
Compounding comp,
1154-
Frequency freq,
1155-
bool includeSettlementDateFlows,
1156-
Date settlementDate,
1157-
Date npvDate)
1158-
: leg_(leg), npv_(npv), zSpread_(new SimpleQuote(0.0)),
1159-
curve_(Handle<YieldTermStructure>(discountCurve),
1160-
Handle<Quote>(zSpread_), comp, freq, dc),
1161-
includeSettlementDateFlows_(includeSettlementDateFlows),
1162-
settlementDate_(settlementDate),
1163-
npvDate_(npvDate) {
1164-
1165-
if (settlementDate_ == Date())
1166-
settlementDate_ = Settings::instance().evaluationDate();
1167-
1168-
if (npvDate_ == Date())
1169-
npvDate_ = settlementDate_;
1170-
1171-
// if the discount curve allows extrapolation, let's
1172-
// the spreaded curve do too.
1173-
curve_.enableExtrapolation(
1174-
discountCurve->allowsExtrapolation());
1175-
}
1176-
Real operator()(Rate zSpread) const {
1177-
zSpread_->setValue(zSpread);
1178-
Real NPV = CashFlows::npv(leg_, curve_,
1179-
includeSettlementDateFlows_,
1180-
settlementDate_, npvDate_);
1181-
return npv_ - NPV;
1182-
}
1183-
private:
1184-
const Leg& leg_;
1185-
Real npv_;
1186-
ext::shared_ptr<SimpleQuote> zSpread_;
1187-
ZeroSpreadedTermStructure curve_;
1188-
bool includeSettlementDateFlows_;
1189-
Date settlementDate_, npvDate_;
1190-
};
1191-
1192-
} // anonymous namespace ends here
1193-
11941145
Real CashFlows::npv(const Leg& leg,
11951146
const ext::shared_ptr<YieldTermStructure>& discountCurve,
11961147
Spread zSpread,
@@ -1216,9 +1167,7 @@ namespace QuantLib {
12161167

12171168
ZeroSpreadedTermStructure spreadedCurve(discountCurveHandle,
12181169
zSpreadQuoteHandle,
1219-
comp, freq, dc);
1220-
1221-
spreadedCurve.enableExtrapolation(discountCurveHandle->allowsExtrapolation());
1170+
comp, freq);
12221171

12231172
return npv(leg, spreadedCurve,
12241173
includeSettlementDateFlows,
@@ -1244,13 +1193,21 @@ namespace QuantLib {
12441193
if (npvDate == Date())
12451194
npvDate = settlementDate;
12461195

1196+
auto zSpreadQuote = ext::make_shared<SimpleQuote>();
1197+
ZeroSpreadedTermStructure spreadedCurve(Handle<YieldTermStructure>(discount),
1198+
Handle<Quote>(zSpreadQuote),
1199+
compounding,
1200+
frequency);
1201+
auto objFunction = [&](Rate zSpread) {
1202+
zSpreadQuote->setValue(zSpread);
1203+
Real NPV = CashFlows::npv(leg, spreadedCurve,
1204+
includeSettlementDateFlows,
1205+
settlementDate, npvDate);
1206+
return npv - NPV;
1207+
};
1208+
12471209
Brent solver;
12481210
solver.setMaxEvaluations(maxIterations);
1249-
ZSpreadFinder objFunction(leg,
1250-
discount,
1251-
npv,
1252-
dayCounter, compounding, frequency, includeSettlementDateFlows,
1253-
settlementDate, npvDate);
12541211
Real step = 0.01;
12551212
return solver.solve(objFunction, accuracy, guess, step);
12561213
}

ql/methods/finitedifferences/operators/fdmbatesop.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ namespace QuantLib {
4949
Handle<YieldTermStructure>(ext::make_shared<ZeroSpreadedTermStructure>(
5050
batesProcess->dividendYield(),
5151
Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(lambda_ * m_))),
52-
Continuous,
53-
NoFrequency,
54-
batesProcess->dividendYield()->dayCounter())),
52+
Continuous)),
5553
batesProcess->s0(),
5654
batesProcess->v0(),
5755
batesProcess->kappa(),

ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,16 @@ namespace QuantLib {
4949
class InterpolatedPiecewiseForwardSpreadedTermStructure : public ForwardRateStructure {
5050
public:
5151
InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure>,
52-
std::vector<Handle<Quote> > spreads,
53-
const std::vector<Date>& dates,
54-
DayCounter dc = DayCounter(),
55-
const Interpolator& factory = Interpolator());
52+
std::vector<Handle<Quote>> spreads,
53+
std::vector<Date> dates,
54+
Interpolator factory = Interpolator());
55+
56+
[[deprecated("Use the constructor without DayCounter")]]
57+
InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure>,
58+
std::vector<Handle<Quote>> spreads,
59+
std::vector<Date> dates,
60+
DayCounter dc,
61+
Interpolator factory = Interpolator());
5662
//! \name YieldTermStructure interface
5763
//@{
5864
DayCounter dayCounter() const override;
@@ -78,23 +84,22 @@ namespace QuantLib {
7884
std::vector<Spread> spreadValues_;
7985
Compounding comp_;
8086
Frequency freq_;
81-
DayCounter dc_;
8287
Interpolator factory_;
8388
Interpolation interpolator_;
8489
};
8590

8691
// inline definitions
8792

93+
#ifndef __DOXYGEN__
94+
8895
template <class T>
8996
inline InterpolatedPiecewiseForwardSpreadedTermStructure<
9097
T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure> h,
91-
std::vector<Handle<Quote> > spreads,
92-
const std::vector<Date>& dates,
93-
DayCounter dc,
94-
const T& factory)
95-
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates),
96-
times_(dates.size()), spreadValues_(dates.size()), dc_(std::move(dc)),
97-
factory_(factory) {
98+
std::vector<Handle<Quote>> spreads,
99+
std::vector<Date> dates,
100+
T factory)
101+
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)),
102+
times_(dates.size()), spreadValues_(dates.size()), factory_(std::move(factory)) {
98103
QL_REQUIRE(!spreads_.empty(), "no spreads given");
99104
QL_REQUIRE(spreads_.size() == dates_.size(),
100105
"spread and date vector have different sizes");
@@ -105,6 +110,19 @@ namespace QuantLib {
105110
updateInterpolation();
106111
}
107112

113+
template <class T>
114+
inline InterpolatedPiecewiseForwardSpreadedTermStructure<
115+
T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure> h,
116+
std::vector<Handle<Quote>> spreads,
117+
std::vector<Date> dates,
118+
DayCounter dc,
119+
T factory)
120+
: InterpolatedPiecewiseForwardSpreadedTermStructure(
121+
std::move(h), std::move(spreads), std::move(dates), std::move(factory)
122+
) {}
123+
124+
#endif
125+
108126
template <class T>
109127
inline DayCounter InterpolatedPiecewiseForwardSpreadedTermStructure<T>::dayCounter() const {
110128
return originalCurve_->dayCounter();

ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,20 @@ namespace QuantLib {
4949
class InterpolatedPiecewiseZeroSpreadedTermStructure : public ZeroYieldStructure {
5050
public:
5151
InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure>,
52-
std::vector<Handle<Quote> > spreads,
53-
const std::vector<Date>& dates,
52+
std::vector<Handle<Quote>> spreads,
53+
std::vector<Date> dates,
5454
Compounding comp = Continuous,
5555
Frequency freq = NoFrequency,
56-
DayCounter dc = DayCounter(),
57-
const Interpolator& factory = Interpolator());
56+
Interpolator factory = Interpolator());
57+
58+
[[deprecated("Use the constructor without DayCounter")]]
59+
InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure>,
60+
std::vector<Handle<Quote>> spreads,
61+
std::vector<Date> dates,
62+
Compounding comp,
63+
Frequency freq,
64+
DayCounter dc,
65+
Interpolator factory = Interpolator());
5866
//! \name YieldTermStructure interface
5967
//@{
6068
DayCounter dayCounter() const override;
@@ -78,7 +86,6 @@ namespace QuantLib {
7886
std::vector<Spread> spreadValues_;
7987
Compounding comp_;
8088
Frequency freq_;
81-
DayCounter dc_;
8289
Interpolator factory_;
8390
Interpolation interpolator_;
8491
};
@@ -91,18 +98,19 @@ namespace QuantLib {
9198

9299
// inline definitions
93100

101+
#ifndef __DOXYGEN__
102+
94103
template <class T>
95104
inline InterpolatedPiecewiseZeroSpreadedTermStructure<
96105
T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
97-
std::vector<Handle<Quote> > spreads,
98-
const std::vector<Date>& dates,
106+
std::vector<Handle<Quote>> spreads,
107+
std::vector<Date> dates,
99108
Compounding comp,
100109
Frequency freq,
101-
DayCounter dc,
102-
const T& factory)
103-
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates),
110+
T factory)
111+
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)),
104112
times_(dates.size()), spreadValues_(dates.size()), comp_(comp), freq_(freq),
105-
dc_(std::move(dc)), factory_(factory) {
113+
factory_(std::move(factory)) {
106114
QL_REQUIRE(!spreads_.empty(), "no spreads given");
107115
QL_REQUIRE(spreads_.size() == dates_.size(),
108116
"spread and date vector have different sizes");
@@ -113,6 +121,21 @@ namespace QuantLib {
113121
updateInterpolation();
114122
}
115123

124+
template <class T>
125+
inline InterpolatedPiecewiseZeroSpreadedTermStructure<
126+
T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
127+
std::vector<Handle<Quote>> spreads,
128+
std::vector<Date> dates,
129+
Compounding comp,
130+
Frequency freq,
131+
DayCounter dc,
132+
T factory)
133+
: InterpolatedPiecewiseZeroSpreadedTermStructure(
134+
std::move(h), std::move(spreads), std::move(dates), comp, freq, std::move(factory)
135+
) {}
136+
137+
#endif
138+
116139
template <class T>
117140
inline DayCounter InterpolatedPiecewiseZeroSpreadedTermStructure<T>::dayCounter() const {
118141
return originalCurve_->dayCounter();
@@ -192,4 +215,4 @@ namespace QuantLib {
192215
}
193216

194217

195-
#endif
218+
#endif

ql/termstructures/yield/zerospreadedtermstructure.hpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ namespace QuantLib {
4949
ZeroSpreadedTermStructure(Handle<YieldTermStructure>,
5050
Handle<Quote> spread,
5151
Compounding comp = Continuous,
52-
Frequency freq = NoFrequency,
53-
DayCounter dc = DayCounter());
52+
Frequency freq = NoFrequency);
53+
54+
[[deprecated("Use the constructor without DayCounter")]]
55+
ZeroSpreadedTermStructure(Handle<YieldTermStructure>,
56+
Handle<Quote> spread,
57+
Compounding comp,
58+
Frequency freq,
59+
DayCounter dc);
5460
//! \name YieldTermStructure interface
5561
//@{
5662
DayCounter dayCounter() const override;
@@ -75,22 +81,26 @@ namespace QuantLib {
7581
Handle<Quote> spread_;
7682
Compounding comp_;
7783
Frequency freq_;
78-
DayCounter dc_;
7984
};
8085

8186
inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
8287
Handle<Quote> spread,
8388
Compounding comp,
84-
Frequency freq,
85-
DayCounter dc)
86-
: originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq),
87-
dc_(std::move(dc)) {
89+
Frequency freq)
90+
: originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq) {
8891
if (!originalCurve_.empty())
8992
enableExtrapolation(originalCurve_->allowsExtrapolation());
9093
registerWith(originalCurve_);
9194
registerWith(spread_);
9295
}
9396

97+
inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
98+
Handle<Quote> spread,
99+
Compounding comp,
100+
Frequency freq,
101+
DayCounter dc)
102+
: ZeroSpreadedTermStructure(std::move(h), std::move(spread), comp, freq) {}
103+
94104
inline DayCounter ZeroSpreadedTermStructure::dayCounter() const {
95105
return originalCurve_->dayCounter();
96106
}

test-suite/capfloor.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,7 @@ BOOST_AUTO_TEST_CASE(testOptionLetsDelta) {
663663
ext::shared_ptr<YieldTermStructure> spreadCurve(new ZeroSpreadedTermStructure(
664664
baseCurveHandle,
665665
Handle<Quote>(spread),
666-
Continuous,
667-
Annual,
668-
Actual360()));
666+
Continuous));
669667
vars.termStructure.linkTo(spreadCurve);
670668
Date startDate = vars.termStructure->referenceDate();
671669
Leg leg = vars.makeLeg(startDate,20);
@@ -784,9 +782,7 @@ BOOST_AUTO_TEST_CASE(testBachelierOptionLetsDelta) {
784782
ext::shared_ptr<YieldTermStructure> spreadCurve(new ZeroSpreadedTermStructure(
785783
baseCurveHandle,
786784
Handle<Quote>(spread),
787-
Continuous,
788-
Annual,
789-
Actual360()));
785+
Continuous));
790786
vars.termStructure.linkTo(spreadCurve);
791787
Date startDate = vars.termStructure->referenceDate();
792788
Leg leg = vars.makeLeg(startDate,20);

0 commit comments

Comments
 (0)