Skip to content

Commit

Permalink
Move ArithmeticAveragedOvernightIndexedCouponPricer into overnightind…
Browse files Browse the repository at this point in the history
…exedcouponpricer files
  • Loading branch information
ralfkonrad committed Jul 30, 2024
1 parent 8425c50 commit 60422b7
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 206 deletions.
2 changes: 0 additions & 2 deletions QuantLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,6 @@
<ClInclude Include="ql\experimental\averageois\all.hpp" />
<ClInclude Include="ql\experimental\averageois\arithmeticaverageois.hpp" />
<ClInclude Include="ql\experimental\averageois\arithmeticoisratehelper.hpp" />
<ClInclude Include="ql\experimental\averageois\averageoiscouponpricer.hpp" />
<ClInclude Include="ql\experimental\averageois\makearithmeticaverageois.hpp" />
<ClInclude Include="ql\experimental\barrieroption\all.hpp" />
<ClInclude Include="ql\experimental\barrieroption\binomialdoublebarrierengine.hpp" />
Expand Down Expand Up @@ -1953,7 +1952,6 @@
<ClCompile Include="ql\experimental\asian\analytic_discr_geom_av_price_heston.cpp" />
<ClCompile Include="ql\experimental\averageois\arithmeticaverageois.cpp" />
<ClCompile Include="ql\experimental\averageois\arithmeticoisratehelper.cpp" />
<ClCompile Include="ql\experimental\averageois\averageoiscouponpricer.cpp" />
<ClCompile Include="ql\experimental\averageois\makearithmeticaverageois.cpp" />
<ClCompile Include="ql\experimental\barrieroption\discretizeddoublebarrieroption.cpp" />
<ClCompile Include="ql\experimental\barrieroption\mcdoublebarrierengine.cpp" />
Expand Down
6 changes: 0 additions & 6 deletions QuantLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -3603,9 +3603,6 @@
<ClInclude Include="ql\experimental\averageois\arithmeticoisratehelper.hpp">
<Filter>experimental\averageois</Filter>
</ClInclude>
<ClInclude Include="ql\experimental\averageois\averageoiscouponpricer.hpp">
<Filter>experimental\averageois</Filter>
</ClInclude>
<ClInclude Include="ql\experimental\averageois\makearithmeticaverageois.hpp">
<Filter>experimental\averageois</Filter>
</ClInclude>
Expand Down Expand Up @@ -6596,9 +6593,6 @@
<ClCompile Include="ql\experimental\averageois\arithmeticaverageois.cpp">
<Filter>experimental\averageois</Filter>
</ClCompile>
<ClCompile Include="ql\experimental\averageois\averageoiscouponpricer.cpp">
<Filter>experimental\averageois</Filter>
</ClCompile>
<ClCompile Include="ql\experimental\averageois\arithmeticoisratehelper.cpp">
<Filter>experimental\averageois</Filter>
</ClCompile>
Expand Down
2 changes: 0 additions & 2 deletions ql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ set(QL_SOURCES
experimental/asian/analytic_discr_geom_av_price_heston.cpp
experimental/averageois/arithmeticaverageois.cpp
experimental/averageois/arithmeticoisratehelper.cpp
experimental/averageois/averageoiscouponpricer.cpp
experimental/averageois/makearithmeticaverageois.cpp
experimental/barrieroption/mcdoublebarrierengine.cpp
experimental/barrieroption/discretizeddoublebarrieroption.cpp
Expand Down Expand Up @@ -994,7 +993,6 @@ set(QL_HEADERS
experimental/asian/analytic_discr_geom_av_price_heston.hpp
experimental/averageois/arithmeticaverageois.hpp
experimental/averageois/arithmeticoisratehelper.hpp
experimental/averageois/averageoiscouponpricer.hpp
experimental/averageois/makearithmeticaverageois.hpp
experimental/barrieroption/mcdoublebarrierengine.hpp
experimental/barrieroption/binomialdoublebarrierengine.hpp
Expand Down
1 change: 0 additions & 1 deletion ql/cashflows/overnightindexedcoupon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include <ql/cashflows/couponpricer.hpp>
#include <ql/cashflows/overnightindexedcouponpricer.hpp>
#include <ql/experimental/averageois/averageoiscouponpricer.hpp>
#include <ql/cashflows/overnightindexedcoupon.hpp>
#include <ql/termstructures/yieldtermstructure.hpp>
#include <ql/utilities/vectors.hpp>
Expand Down
114 changes: 107 additions & 7 deletions ql/cashflows/overnightindexedcouponpricer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Copyright (C) 2009 Roland Lichters
Copyright (C) 2009 Ferdinando Ametrano
Copyright (C) 2014 Peter Caspers
Copyright (C) 2016 Stefano Fondi
Copyright (C) 2017 Joseph Jeisman
Copyright (C) 2017 Fabrice Lecuyer
Expand All @@ -23,13 +24,11 @@

#include <ql/cashflows/overnightindexedcouponpricer.hpp>

using std::vector;

namespace QuantLib {

namespace {

Size determineNumberOfFixings(const vector<Date>& interestDates,
Size determineNumberOfFixings(const std::vector<Date>& interestDates,
const Date& date,
bool applyObservationShift) {
Size n = std::lower_bound(interestDates.begin(), interestDates.end(), date) -
Expand Down Expand Up @@ -59,10 +58,10 @@ namespace QuantLib {
ext::dynamic_pointer_cast<OvernightIndex>(coupon_->index());
const auto& pastFixings = IndexManager::instance().getHistory(index->name());

const vector<Date>& fixingDates = coupon_->fixingDates();
const vector<Date>& valueDates = coupon_->valueDates();
const vector<Date>& interestDates = coupon_->interestDates();
const vector<Time>& dt = coupon_->dt();
const auto& fixingDates = coupon_->fixingDates();
const auto& valueDates = coupon_->valueDates();
const auto& interestDates = coupon_->interestDates();
const auto& dt = coupon_->dt();
const bool applyObservationShift = coupon_->applyObservationShift();

Size i = 0;
Expand Down Expand Up @@ -176,4 +175,105 @@ namespace QuantLib {
const Rate rate = (compoundFactor - 1.0) / coupon_->accruedPeriod(date);
return coupon_->gearing() * rate + coupon_->spread();
}

void
ArithmeticAveragedOvernightIndexedCouponPricer::initialize(const FloatingRateCoupon& coupon) {
coupon_ = dynamic_cast<const OvernightIndexedCoupon*>(&coupon);
QL_ENSURE(coupon_, "wrong coupon type");
}

Rate ArithmeticAveragedOvernightIndexedCouponPricer::swapletRate() const {

ext::shared_ptr<OvernightIndex> index =
ext::dynamic_pointer_cast<OvernightIndex>(coupon_->index());

const auto& fixingDates = coupon_->fixingDates();
const auto& dt = coupon_->dt();

Size n = dt.size(), i = 0;

Real accumulatedRate = 0.0;

// already fixed part
Date today = Settings::instance().evaluationDate();
while (i < n && fixingDates[i] < today) {
// rate must have been fixed
Rate pastFixing = IndexManager::instance().getHistory(index->name())[fixingDates[i]];
QL_REQUIRE(pastFixing != Null<Real>(),
"Missing " << index->name() << " fixing for " << fixingDates[i]);
accumulatedRate += pastFixing * dt[i];
++i;
}

// today is a border case
if (i < n && fixingDates[i] == today) {
// might have been fixed
try {
Rate pastFixing =
IndexManager::instance().getHistory(index->name())[fixingDates[i]];
if (pastFixing != Null<Real>()) {
accumulatedRate += pastFixing * dt[i];
++i;
} else {
; // fall through and forecast
}
} catch (Error&) {
; // fall through and forecast
}
}

/* forward part using telescopic property in order
to avoid the evaluation of multiple forward fixings
(approximation proposed by Katsumi Takada)*/
if (byApprox_ && i < n) {
Handle<YieldTermStructure> curve = index->forwardingTermStructure();
QL_REQUIRE(!curve.empty(),
"null term structure set to this instance of " << index->name());

const auto& dates = coupon_->valueDates();
DiscountFactor startDiscount = curve->discount(dates[i]);
DiscountFactor endDiscount = curve->discount(dates[n]);

accumulatedRate +=
log(startDiscount / endDiscount) -
convAdj1(curve->timeFromReference(dates[i]), curve->timeFromReference(dates[n])) -
convAdj2(curve->timeFromReference(dates[i]), curve->timeFromReference(dates[n]));
}
// otherwise
else if (i < n) {
Handle<YieldTermStructure> curve = index->forwardingTermStructure();
QL_REQUIRE(!curve.empty(),
"null term structure set to this instance of " << index->name());

const auto& dates = coupon_->valueDates();
Time te = curve->timeFromReference(dates[n]);
while (i < n) {
// forcast fixing
Rate forecastFixing = index->fixing(fixingDates[i]);
Time ti1 = curve->timeFromReference(dates[i]);
Time ti2 = curve->timeFromReference(dates[i + 1]);
/*convexity adjustment due to payment dalay of each
overnight fixing, supposing an Hull-White short rate model*/
Real convAdj = exp(
0.5 * pow(vol_, 2.0) / pow(mrs_, 3.0) * (exp(2 * mrs_ * ti1) - 1) *
(exp(-mrs_ * ti2) - exp(-mrs_ * te)) * (exp(-mrs_ * ti2) - exp(-mrs_ * ti1)));
accumulatedRate += convAdj * (1 + forecastFixing * dt[i]) - 1;
++i;
}
}

Rate rate = accumulatedRate / coupon_->accrualPeriod();
return coupon_->gearing() * rate + coupon_->spread();
}

Real ArithmeticAveragedOvernightIndexedCouponPricer::convAdj1(Time ts, Time te) const {
return vol_ * vol_ / (4.0 * pow(mrs_, 3.0)) * (1.0 - exp(-2.0 * mrs_ * ts)) *
pow((1.0 - exp(-mrs_ * (te - ts))), 2.0);
}

Real ArithmeticAveragedOvernightIndexedCouponPricer::convAdj2(Time ts, Time te) const {
return vol_ * vol_ / (2.0 * pow(mrs_, 2.0)) *
((te - ts) - pow(1.0 - exp(-mrs_ * (te - ts)), 2.0) / mrs_ -
(1.0 - exp(-2.0 * mrs_ * (te - ts))) / (2.0 * mrs_));
}
}
34 changes: 34 additions & 0 deletions ql/cashflows/overnightindexedcouponpricer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Copyright (C) 2009 Roland Lichters
Copyright (C) 2009 Ferdinando Ametrano
Copyright (C) 2014 Peter Caspers
Copyright (C) 2016 Stefano Fondi
Copyright (C) 2017 Joseph Jeisman
Copyright (C) 2017 Fabrice Lecuyer
Expand Down Expand Up @@ -52,6 +53,39 @@ namespace QuantLib {
protected:
const OvernightIndexedCoupon* coupon_ = nullptr;
};

/*! pricer for arithmetically averaged overnight indexed coupons
Reference: Katsumi Takada 2011, Valuation of Arithmetically Average of
Fed Funds Rates and Construction of the US Dollar Swap Yield Curve
*/
class ArithmeticAveragedOvernightIndexedCouponPricer : public FloatingRateCouponPricer {
public:
explicit ArithmeticAveragedOvernightIndexedCouponPricer(
Real meanReversion = 0.03,
Real volatility = 0.00, // NO convexity adjustment by default
bool byApprox = false) // TRUE to use Katsumi Takada approximation
: byApprox_(byApprox), mrs_(meanReversion), vol_(volatility) {}

explicit ArithmeticAveragedOvernightIndexedCouponPricer(
bool byApprox) // Simplified constructor assuming no convexity correction
: ArithmeticAveragedOvernightIndexedCouponPricer(0.03, 0.0, byApprox) {}

void initialize(const FloatingRateCoupon& coupon) override;
Rate swapletRate() const override;
Real swapletPrice() const override { QL_FAIL("swapletPrice not available"); }
Real capletPrice(Rate) const override { QL_FAIL("capletPrice not available"); }
Rate capletRate(Rate) const override { QL_FAIL("capletRate not available"); }
Real floorletPrice(Rate) const override { QL_FAIL("floorletPrice not available"); }
Rate floorletRate(Rate) const override { QL_FAIL("floorletRate not available"); }

protected:
Real convAdj1(Time ts, Time te) const;
Real convAdj2(Time ts, Time te) const;
const OvernightIndexedCoupon* coupon_;

Check notice on line 84 in ql/cashflows/overnightindexedcouponpricer.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

ql/cashflows/overnightindexedcouponpricer.hpp#L84

class member 'ArithmeticAveragedOvernightIndexedCouponPricer::coupon_' is never used.
bool byApprox_;
Real mrs_;
Real vol_;
};
}

#endif
1 change: 0 additions & 1 deletion ql/experimental/averageois/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ this_include_HEADERS = \
makearithmeticaverageois.hpp

cpp_files = \
averageoiscouponpricer.cpp \
arithmeticaverageois.cpp \
arithmeticoisratehelper.cpp \
makearithmeticaverageois.cpp
Expand Down
2 changes: 1 addition & 1 deletion ql/experimental/averageois/arithmeticaverageois.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

#include <ql/cashflows/fixedratecoupon.hpp>
#include <ql/cashflows/overnightindexedcoupon.hpp>
#include <ql/cashflows/overnightindexedcouponpricer.hpp>
#include <ql/experimental/averageois/arithmeticaverageois.hpp>
#include <ql/experimental/averageois/averageoiscouponpricer.hpp>
#include <utility>

namespace QuantLib {
Expand Down
Loading

0 comments on commit 60422b7

Please sign in to comment.