Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 14 additions & 57 deletions ql/cashflows/cashflows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,55 +1142,6 @@ namespace QuantLib {
}

// Z-spread utility functions
namespace {

class ZSpreadFinder {
public:
ZSpreadFinder(const Leg& leg,
const ext::shared_ptr<YieldTermStructure>& discountCurve,
Real npv,
const DayCounter& dc,
Compounding comp,
Frequency freq,
bool includeSettlementDateFlows,
Date settlementDate,
Date npvDate)
: leg_(leg), npv_(npv), zSpread_(new SimpleQuote(0.0)),
curve_(Handle<YieldTermStructure>(discountCurve),
Handle<Quote>(zSpread_), comp, freq, dc),
includeSettlementDateFlows_(includeSettlementDateFlows),
settlementDate_(settlementDate),
npvDate_(npvDate) {

if (settlementDate_ == Date())
settlementDate_ = Settings::instance().evaluationDate();

if (npvDate_ == Date())
npvDate_ = settlementDate_;

// if the discount curve allows extrapolation, let's
// the spreaded curve do too.
curve_.enableExtrapolation(
discountCurve->allowsExtrapolation());
}
Real operator()(Rate zSpread) const {
zSpread_->setValue(zSpread);
Real NPV = CashFlows::npv(leg_, curve_,
includeSettlementDateFlows_,
settlementDate_, npvDate_);
return npv_ - NPV;
}
private:
const Leg& leg_;
Real npv_;
ext::shared_ptr<SimpleQuote> zSpread_;
ZeroSpreadedTermStructure curve_;
bool includeSettlementDateFlows_;
Date settlementDate_, npvDate_;
};

} // anonymous namespace ends here

Real CashFlows::npv(const Leg& leg,
const ext::shared_ptr<YieldTermStructure>& discountCurve,
Spread zSpread,
Expand All @@ -1216,9 +1167,7 @@ namespace QuantLib {

ZeroSpreadedTermStructure spreadedCurve(discountCurveHandle,
zSpreadQuoteHandle,
comp, freq, dc);

spreadedCurve.enableExtrapolation(discountCurveHandle->allowsExtrapolation());
comp, freq);

return npv(leg, spreadedCurve,
includeSettlementDateFlows,
Expand All @@ -1244,13 +1193,21 @@ namespace QuantLib {
if (npvDate == Date())
npvDate = settlementDate;

auto zSpreadQuote = ext::make_shared<SimpleQuote>();
ZeroSpreadedTermStructure spreadedCurve(Handle<YieldTermStructure>(discount),
Handle<Quote>(zSpreadQuote),
compounding,
frequency);
auto objFunction = [&](Rate zSpread) {
zSpreadQuote->setValue(zSpread);
Real NPV = CashFlows::npv(leg, spreadedCurve,
includeSettlementDateFlows,
settlementDate, npvDate);
return npv - NPV;
};

Brent solver;
solver.setMaxEvaluations(maxIterations);
ZSpreadFinder objFunction(leg,
discount,
npv,
dayCounter, compounding, frequency, includeSettlementDateFlows,
settlementDate, npvDate);
Real step = 0.01;
return solver.solve(objFunction, accuracy, guess, step);
}
Expand Down
4 changes: 1 addition & 3 deletions ql/methods/finitedifferences/operators/fdmbatesop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ namespace QuantLib {
Handle<YieldTermStructure>(ext::make_shared<ZeroSpreadedTermStructure>(
batesProcess->dividendYield(),
Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(lambda_ * m_))),
Continuous,
NoFrequency,
batesProcess->dividendYield()->dayCounter())),
Continuous)),
batesProcess->s0(),
batesProcess->v0(),
batesProcess->kappa(),
Expand Down
45 changes: 33 additions & 12 deletions ql/termstructures/yield/piecewiseforwardspreadedtermstructure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,19 @@ namespace QuantLib {
class InterpolatedPiecewiseForwardSpreadedTermStructure : public ForwardRateStructure {
public:
InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure>,
std::vector<Handle<Quote> > spreads,
const std::vector<Date>& dates,
DayCounter dc = DayCounter(),
const Interpolator& factory = Interpolator());
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
Interpolator factory = Interpolator());

/*! \deprecated Use the constructor without a day counter.
Deprecated in version 1.41.
*/
[[deprecated("Use the constructor without DayCounter")]]
InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure>,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
DayCounter dc,
Interpolator factory = Interpolator());
//! \name YieldTermStructure interface
//@{
DayCounter dayCounter() const override;
Expand All @@ -78,23 +87,22 @@ namespace QuantLib {
std::vector<Spread> spreadValues_;
Compounding comp_;
Frequency freq_;
DayCounter dc_;
Interpolator factory_;
Interpolation interpolator_;
};

// inline definitions

#ifndef __DOXYGEN__

template <class T>
inline InterpolatedPiecewiseForwardSpreadedTermStructure<
T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure> h,
std::vector<Handle<Quote> > spreads,
const std::vector<Date>& dates,
DayCounter dc,
const T& factory)
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates),
times_(dates.size()), spreadValues_(dates.size()), dc_(std::move(dc)),
factory_(factory) {
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
T factory)
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)),
times_(dates_.size()), spreadValues_(dates_.size()), factory_(std::move(factory)) {
QL_REQUIRE(!spreads_.empty(), "no spreads given");
QL_REQUIRE(spreads_.size() == dates_.size(),
"spread and date vector have different sizes");
Expand All @@ -105,6 +113,19 @@ namespace QuantLib {
updateInterpolation();
}

template <class T>
inline InterpolatedPiecewiseForwardSpreadedTermStructure<
T>::InterpolatedPiecewiseForwardSpreadedTermStructure(Handle<YieldTermStructure> h,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
DayCounter dc,
T factory)
: InterpolatedPiecewiseForwardSpreadedTermStructure(
std::move(h), std::move(spreads), std::move(dates), std::move(factory)
) {}

#endif

template <class T>
inline DayCounter InterpolatedPiecewiseForwardSpreadedTermStructure<T>::dayCounter() const {
return originalCurve_->dayCounter();
Expand Down
52 changes: 39 additions & 13 deletions ql/termstructures/yield/piecewisezerospreadedtermstructure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,23 @@ namespace QuantLib {
class InterpolatedPiecewiseZeroSpreadedTermStructure : public ZeroYieldStructure {
public:
InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure>,
std::vector<Handle<Quote> > spreads,
const std::vector<Date>& dates,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
Compounding comp = Continuous,
Frequency freq = NoFrequency,
DayCounter dc = DayCounter(),
const Interpolator& factory = Interpolator());
Interpolator factory = Interpolator());

/*! \deprecated Use the constructor without a day counter.
Deprecated in version 1.41.
*/
[[deprecated("Use the constructor without DayCounter")]]
InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure>,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
Compounding comp,
Frequency freq,
DayCounter dc,
Interpolator factory = Interpolator());
//! \name YieldTermStructure interface
//@{
DayCounter dayCounter() const override;
Expand All @@ -78,7 +89,6 @@ namespace QuantLib {
std::vector<Spread> spreadValues_;
Compounding comp_;
Frequency freq_;
DayCounter dc_;
Interpolator factory_;
Interpolation interpolator_;
};
Expand All @@ -91,18 +101,19 @@ namespace QuantLib {

// inline definitions

#ifndef __DOXYGEN__

template <class T>
inline InterpolatedPiecewiseZeroSpreadedTermStructure<
T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
std::vector<Handle<Quote> > spreads,
const std::vector<Date>& dates,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
Compounding comp,
Frequency freq,
DayCounter dc,
const T& factory)
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(dates),
times_(dates.size()), spreadValues_(dates.size()), comp_(comp), freq_(freq),
dc_(std::move(dc)), factory_(factory) {
T factory)
: originalCurve_(std::move(h)), spreads_(std::move(spreads)), dates_(std::move(dates)),
times_(dates_.size()), spreadValues_(dates_.size()), comp_(comp), freq_(freq),
factory_(std::move(factory)) {
QL_REQUIRE(!spreads_.empty(), "no spreads given");
QL_REQUIRE(spreads_.size() == dates_.size(),
"spread and date vector have different sizes");
Expand All @@ -113,6 +124,21 @@ namespace QuantLib {
updateInterpolation();
}

template <class T>
inline InterpolatedPiecewiseZeroSpreadedTermStructure<
T>::InterpolatedPiecewiseZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
std::vector<Handle<Quote>> spreads,
std::vector<Date> dates,
Compounding comp,
Frequency freq,
DayCounter dc,
T factory)
: InterpolatedPiecewiseZeroSpreadedTermStructure(
std::move(h), std::move(spreads), std::move(dates), comp, freq, std::move(factory)
) {}

#endif

template <class T>
inline DayCounter InterpolatedPiecewiseZeroSpreadedTermStructure<T>::dayCounter() const {
return originalCurve_->dayCounter();
Expand Down Expand Up @@ -192,4 +218,4 @@ namespace QuantLib {
}


#endif
#endif
27 changes: 20 additions & 7 deletions ql/termstructures/yield/zerospreadedtermstructure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,17 @@ namespace QuantLib {
ZeroSpreadedTermStructure(Handle<YieldTermStructure>,
Handle<Quote> spread,
Compounding comp = Continuous,
Frequency freq = NoFrequency,
DayCounter dc = DayCounter());
Frequency freq = NoFrequency);

/*! \deprecated Use the constructor without a day counter.
Deprecated in version 1.41.
*/
[[deprecated("Use the constructor without DayCounter")]]
ZeroSpreadedTermStructure(Handle<YieldTermStructure>,
Handle<Quote> spread,
Compounding comp,
Frequency freq,
DayCounter dc);
//! \name YieldTermStructure interface
//@{
DayCounter dayCounter() const override;
Expand All @@ -75,22 +84,26 @@ namespace QuantLib {
Handle<Quote> spread_;
Compounding comp_;
Frequency freq_;
DayCounter dc_;
};

inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
Handle<Quote> spread,
Compounding comp,
Frequency freq,
DayCounter dc)
: originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq),
dc_(std::move(dc)) {
Frequency freq)
: originalCurve_(std::move(h)), spread_(std::move(spread)), comp_(comp), freq_(freq) {
if (!originalCurve_.empty())
enableExtrapolation(originalCurve_->allowsExtrapolation());
registerWith(originalCurve_);
registerWith(spread_);
}

inline ZeroSpreadedTermStructure::ZeroSpreadedTermStructure(Handle<YieldTermStructure> h,
Handle<Quote> spread,
Compounding comp,
Frequency freq,
DayCounter dc)
: ZeroSpreadedTermStructure(std::move(h), std::move(spread), comp, freq) {}

inline DayCounter ZeroSpreadedTermStructure::dayCounter() const {
return originalCurve_->dayCounter();
}
Expand Down
8 changes: 2 additions & 6 deletions test-suite/capfloor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,9 +663,7 @@ BOOST_AUTO_TEST_CASE(testOptionLetsDelta) {
ext::shared_ptr<YieldTermStructure> spreadCurve(new ZeroSpreadedTermStructure(
baseCurveHandle,
Handle<Quote>(spread),
Continuous,
Annual,
Actual360()));
Continuous));
vars.termStructure.linkTo(spreadCurve);
Date startDate = vars.termStructure->referenceDate();
Leg leg = vars.makeLeg(startDate,20);
Expand Down Expand Up @@ -784,9 +782,7 @@ BOOST_AUTO_TEST_CASE(testBachelierOptionLetsDelta) {
ext::shared_ptr<YieldTermStructure> spreadCurve(new ZeroSpreadedTermStructure(
baseCurveHandle,
Handle<Quote>(spread),
Continuous,
Annual,
Actual360()));
Continuous));
vars.termStructure.linkTo(spreadCurve);
Date startDate = vars.termStructure->referenceDate();
Leg leg = vars.makeLeg(startDate,20);
Expand Down
5 changes: 1 addition & 4 deletions test-suite/piecewisezerospreadedtermstructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,11 @@ BOOST_AUTO_TEST_CASE(testSetInterpolationFactory) {

Frequency freq = NoFrequency;

Cubic factory;
factory = Cubic(CubicInterpolation::Spline, false);

spreadedTermStructure =
ext::make_shared<InterpolatedPiecewiseZeroSpreadedTermStructure<Cubic> >(
Handle<YieldTermStructure>(vars.termStructure),
spreads, spreadDates, vars.compounding,
freq, vars.dayCount,factory);
freq, Cubic(CubicInterpolation::Spline, false));

Time t = vars.dayCount.yearFraction(vars.today, interpolationDate);
Rate interpolatedZeroRate = spreadedTermStructure->zeroRate(t,vars.compounding);
Expand Down
Loading