Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow swaptions to take OvernightIndexedSwap #1593

Merged
merged 14 commits into from
Mar 28, 2024
1 change: 1 addition & 0 deletions Examples/BermudanSwaption/BermudanSwaption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC)
# include <ql/auto_link.hpp>
#endif
#include <ql/instruments/vanillaswap.hpp>
#include <ql/instruments/swaption.hpp>
#include <ql/pricingengines/swap/discountingswapengine.hpp>
#include <ql/pricingengines/swaption/treeswaptionengine.hpp>
Expand Down
2 changes: 1 addition & 1 deletion ql/cashflows/overnightindexedcoupon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace QuantLib {
overnightIndex,
gearing, spread,
refPeriodStart, refPeriodEnd,
dayCounter, false) {
dayCounter, false), averagingMethod_(averagingMethod) {

// value dates
Date tmpEndDate = endDate;
Expand Down
3 changes: 3 additions & 0 deletions ql/cashflows/overnightindexedcoupon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ namespace QuantLib {
const std::vector<Rate>& indexFixings() const;
//! value dates for the rates to be compounded
const std::vector<Date>& valueDates() const { return valueDates_; }
//! averaging method
const RateAveraging::Type averagingMethod() const { return averagingMethod_; }
//@}
//! \name FloatingRateCoupon interface
//@{
Expand All @@ -87,6 +89,7 @@ namespace QuantLib {
mutable std::vector<Rate> fixings_;
Size n_;
std::vector<Time> dt_;
RateAveraging::Type averagingMethod_;

Rate averageRate(const Date& date) const;
};
Expand Down
2 changes: 1 addition & 1 deletion ql/experimental/basismodels/swaptioncfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace QuantLib {
floatWeights_.push_back(k->amount());
}

SwapCashFlows::SwapCashFlows(const ext::shared_ptr<VanillaSwap>& swap,
SwapCashFlows::SwapCashFlows(const ext::shared_ptr<FixedVsFloatingSwap>& swap,
const Handle<YieldTermStructure>& discountCurve,
bool contTenorSpread)
: IborLegCashFlows(swap->floatingLeg(), discountCurve, contTenorSpread) {
Expand Down
2 changes: 1 addition & 1 deletion ql/experimental/basismodels/swaptioncfs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace QuantLib {
std::vector<Real> annuityWeights_;

public:
SwapCashFlows(const ext::shared_ptr<VanillaSwap>& swap,
SwapCashFlows(const ext::shared_ptr<FixedVsFloatingSwap>& swap,
const Handle<YieldTermStructure>& discountCurve,
bool contTenorSpread = true);
SwapCashFlows() = default;
Expand Down
13 changes: 7 additions & 6 deletions ql/experimental/basismodels/tenorswaptionvts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ FOR A PARTICULAR PURPOSE. See the license for more details.

#include <ql/experimental/basismodels/tenorswaptionvts.hpp>
#include <ql/experimental/basismodels/swaptioncfs.hpp>
#include <ql/instruments/vanillaswap.hpp>
#include <ql/exercise.hpp>
#include <ql/indexes/iborindex.hpp>
#include <ql/math/rounding.hpp>
Expand Down Expand Up @@ -60,15 +61,15 @@ namespace QuantLib {
volTS.baseIndex_->fixingCalendar(), ModifiedFollowing,
Unadjusted, DateGeneration::Backward, false);
// and swaps
ext::shared_ptr<VanillaSwap> baseSwap(new VanillaSwap(
auto baseSwap = ext::make_shared<VanillaSwap>(
Swap::Payer, 1.0, baseFixedSchedule, 1.0, volTS.baseFixedDC_, baseFloatSchedule,
volTS.baseIndex_, 0.0, volTS.baseIndex_->dayCounter()));
ext::shared_ptr<VanillaSwap> targSwap(new VanillaSwap(
volTS.baseIndex_, 0.0, volTS.baseIndex_->dayCounter());
auto targSwap = ext::make_shared<VanillaSwap>(
Swap::Payer, 1.0, baseFixedSchedule, 1.0, volTS.baseFixedDC_, targFloatSchedule,
volTS.targIndex_, 0.0, volTS.targIndex_->dayCounter()));
ext::shared_ptr<VanillaSwap> finlSwap(new VanillaSwap(
volTS.targIndex_, 0.0, volTS.targIndex_->dayCounter());
auto finlSwap = ext::make_shared<VanillaSwap>(
Swap::Payer, 1.0, finlFixedSchedule, 1.0, volTS.targFixedDC_, targFloatSchedule,
volTS.targIndex_, 0.0, volTS.targIndex_->dayCounter()));
volTS.targIndex_, 0.0, volTS.targIndex_->dayCounter());
// adding engines
baseSwap->setPricingEngine(
ext::shared_ptr<PricingEngine>(new DiscountingSwapEngine(volTS.discountCurve_)));
Expand Down
52 changes: 35 additions & 17 deletions ql/instruments/makeswaption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <ql/cashflows/cashflows.hpp>
#include <ql/exercise.hpp>
#include <ql/indexes/swapindex.hpp>
#include <ql/instruments/makeois.hpp>
#include <ql/instruments/makeswaption.hpp>
#include <ql/instruments/makevanillaswap.hpp>
#include <ql/pricingengines/swap/discountingswapengine.hpp>
Expand Down Expand Up @@ -72,13 +73,13 @@ namespace QuantLib {
}

Rate usedStrike = strike_;
ext::shared_ptr<OvernightIndexedSwapIndex> OIswap_index = ext::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIndex_);
if (strike_ == Null<Rate>()) {
// ATM on curve(s) attached to index
QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(),
"null term structure set to this instance of " <<
swapIndex_->name());
ext::shared_ptr<VanillaSwap> temp =
swapIndex_->underlyingSwap(fixingDate_);
ext::shared_ptr<FixedVsFloatingSwap> temp = swapIndex_->underlyingSwap(fixingDate_);
lballabio marked this conversation as resolved.
Show resolved Hide resolved
temp->setPricingEngine(
ext::shared_ptr<PricingEngine>(new DiscountingSwapEngine(
swapIndex_->exogenousDiscount()
Expand All @@ -89,21 +90,38 @@ namespace QuantLib {
}

BusinessDayConvention bdc = swapIndex_->fixedLegConvention();
underlyingSwap_ =
MakeVanillaSwap(swapIndex_->tenor(),
swapIndex_->iborIndex(), usedStrike)
.withEffectiveDate(swapIndex_->valueDate(fixingDate_))
.withFixedLegCalendar(swapIndex_->fixingCalendar())
.withFixedLegDayCount(swapIndex_->dayCounter())
.withFixedLegTenor(swapIndex_->fixedLegTenor())
.withFixedLegConvention(bdc)
.withFixedLegTerminationDateConvention(bdc)
.withType(underlyingType_)
.withNominal(nominal_)
.withIndexedCoupons(useIndexedCoupons_);

ext::shared_ptr<Swaption> swaption(new Swaption(
underlyingSwap_, exercise_, delivery_, settlementMethod_));
if (OIswap_index) {
underlyingSwap_ =
(ext::shared_ptr<OvernightIndexedSwap>)(
MakeOIS(swapIndex_->tenor(),
OIswap_index->overnightIndex(), usedStrike)
.withEffectiveDate(swapIndex_->valueDate(fixingDate_))
.withPaymentCalendar(swapIndex_->fixingCalendar())
.withFixedLegDayCount(swapIndex_->dayCounter())
.withPaymentAdjustment(bdc)
.withFixedLegConvention(bdc)
.withFixedLegTerminationDateConvention(bdc)
.withType(underlyingType_)
.withNominal(nominal_)
);
} else {
underlyingSwap_ =
(ext::shared_ptr<VanillaSwap>)(
MakeVanillaSwap(swapIndex_->tenor(),
swapIndex_->iborIndex(), usedStrike)
.withEffectiveDate(swapIndex_->valueDate(fixingDate_))
.withFixedLegCalendar(swapIndex_->fixingCalendar())
.withFixedLegDayCount(swapIndex_->dayCounter())
.withFixedLegTenor(swapIndex_->fixedLegTenor())
.withFixedLegConvention(bdc)
.withFixedLegTerminationDateConvention(bdc)
.withType(underlyingType_)
.withNominal(nominal_)
.withIndexedCoupons(useIndexedCoupons_)
);
}
ext::shared_ptr<Swaption> swaption = ext::make_shared<Swaption>(
underlyingSwap_, exercise_, delivery_, settlementMethod_);
swaption->setPricingEngine(engine_);
return swaption;
}
Expand Down
2 changes: 1 addition & 1 deletion ql/instruments/makeswaption.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace QuantLib {
ext::shared_ptr<SwapIndex> swapIndex_;
Settlement::Type delivery_;
Settlement::Method settlementMethod_;
mutable ext::shared_ptr<VanillaSwap> underlyingSwap_;
mutable ext::shared_ptr<FixedVsFloatingSwap> underlyingSwap_;

Period optionTenor_;
BusinessDayConvention optionConvention_;
Expand Down
2 changes: 1 addition & 1 deletion ql/instruments/nonstandardswap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

namespace QuantLib {

NonstandardSwap::NonstandardSwap(const VanillaSwap &fromVanilla)
NonstandardSwap::NonstandardSwap(const FixedVsFloatingSwap &fromVanilla)
: Swap(2), type_(fromVanilla.type()),
fixedNominal_(std::vector<Real>(fromVanilla.fixedLeg().size(),
fromVanilla.nominal())),
Expand Down
4 changes: 2 additions & 2 deletions ql/instruments/nonstandardswap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#define quantlib_nonstandard_swap_hpp

#include <ql/instruments/swap.hpp>
#include <ql/instruments/vanillaswap.hpp>
#include <ql/instruments/fixedvsfloatingswap.hpp>
#include <ql/time/daycounter.hpp>
#include <ql/time/schedule.hpp>
#include <ql/optional.hpp>
Expand All @@ -42,7 +42,7 @@ namespace QuantLib {
class arguments;
class results;
class engine;
NonstandardSwap(const VanillaSwap &fromVanilla);
explicit NonstandardSwap(const FixedVsFloatingSwap &fromVanilla);
NonstandardSwap(Swap::Type type,
std::vector<Real> fixedNominal,
const std::vector<Real>& floatingNominal,
Expand Down
10 changes: 4 additions & 6 deletions ql/instruments/swaption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ namespace QuantLib {
}
}

Swaption::Swaption(ext::shared_ptr<VanillaSwap> swap,
Swaption::Swaption(ext::shared_ptr<FixedVsFloatingSwap> swap,
const ext::shared_ptr<Exercise>& exercise,
Settlement::Type delivery,
Settlement::Method settlementMethod)
Expand Down Expand Up @@ -160,7 +160,6 @@ namespace QuantLib {
void Swaption::setupArguments(PricingEngine::arguments* args) const {

swap_->setupArguments(args);

auto* arguments = dynamic_cast<Swaption::arguments*>(args);

QL_REQUIRE(arguments != nullptr, "wrong argument type");
Expand All @@ -172,11 +171,10 @@ namespace QuantLib {
}

void Swaption::arguments::validate() const {
VanillaSwap::arguments::validate();
QL_REQUIRE(swap, "vanilla swap not set");
FixedVsFloatingSwap::arguments::validate();
QL_REQUIRE(swap, "swap not set");
QL_REQUIRE(exercise, "exercise not set");
Settlement::checkTypeAndMethodConsistency(settlementType,
settlementMethod);
Settlement::checkTypeAndMethodConsistency(settlementType, settlementMethod);
}

Volatility Swaption::impliedVolatility(Real targetValue,
Expand Down
12 changes: 6 additions & 6 deletions ql/instruments/swaption.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define quantlib_instruments_swaption_hpp

#include <ql/option.hpp>
#include <ql/instruments/vanillaswap.hpp>
#include <ql/instruments/fixedvsfloatingswap.hpp>
#include <ql/termstructures/yieldtermstructure.hpp>
#include <ql/termstructures/volatility/volatilitytype.hpp>

Expand Down Expand Up @@ -82,7 +82,7 @@ namespace QuantLib {
public:
class arguments;
class engine;
Swaption(ext::shared_ptr<VanillaSwap> swap,
Swaption(ext::shared_ptr<FixedVsFloatingSwap> swap,
const ext::shared_ptr<Exercise>& exercise,
Settlement::Type delivery = Settlement::Physical,
Settlement::Method settlementMethod = Settlement::PhysicalOTC);
Expand All @@ -102,7 +102,7 @@ namespace QuantLib {
return settlementMethod_;
}
Swap::Type type() const { return swap_->type(); }
const ext::shared_ptr<VanillaSwap>& underlyingSwap() const {
const ext::shared_ptr<FixedVsFloatingSwap>& underlyingSwap() const {
return swap_;
}
//@}
Expand All @@ -119,18 +119,18 @@ namespace QuantLib {
Real displacement = 0.0) const;
private:
// arguments
ext::shared_ptr<VanillaSwap> swap_;
ext::shared_ptr<FixedVsFloatingSwap> swap_;
//Handle<YieldTermStructure> termStructure_;
Settlement::Type settlementType_;
Settlement::Method settlementMethod_;
};

//! %Arguments for swaption calculation
class Swaption::arguments : public VanillaSwap::arguments,
class Swaption::arguments : public FixedVsFloatingSwap::arguments,
public Option::arguments {
public:
arguments() = default;
ext::shared_ptr<VanillaSwap> swap;
ext::shared_ptr<FixedVsFloatingSwap> swap;
Settlement::Type settlementType = Settlement::Physical;
Settlement::Method settlementMethod;
void validate() const override;
Expand Down
17 changes: 8 additions & 9 deletions ql/legacy/libormarketmodels/lfmswaptionengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ namespace QuantLib {

static const Spread basisPoint = 1.0e-4;

VanillaSwap swap = *arguments_.swap;
swap.setPricingEngine(ext::shared_ptr<PricingEngine>(
new DiscountingSwapEngine(discountCurve_, false)));
auto swap = arguments_.swap;
swap->setPricingEngine(ext::shared_ptr<PricingEngine>(
new DiscountingSwapEngine(discountCurve_, false)));

Spread correction = swap.spread() *
std::fabs(swap.floatingLegBPS()/swap.fixedLegBPS());
Rate fixedRate = swap.fixedRate() - correction;
Rate fairRate = swap.fairRate() - correction;
Spread correction = swap->spread() *
std::fabs(swap->floatingLegBPS()/swap->fixedLegBPS());
Rate fixedRate = swap->fixedRate() - correction;
Rate fairRate = swap->fairRate() - correction;

ext::shared_ptr<SwaptionVolatilityMatrix> volatility =
model_->getSwaptionVolatilityMatrix();
Expand All @@ -65,9 +65,8 @@ namespace QuantLib {
Option::Type w = arguments_.type==Swap::Payer ? Option::Call : Option::Put;
Volatility vol = volatility->volatility(exercise, swapLength,
fairRate, true);
results_.value = (swap.fixedLegBPS()/basisPoint) *
results_.value = (swap->fixedLegBPS()/basisPoint) *
blackFormula(w, fixedRate, fairRate, vol*std::sqrt(exercise));
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace QuantLib {
public:
FdmAffineModelSwapInnerValue(ext::shared_ptr<ModelType> disModel,
ext::shared_ptr<ModelType> fwdModel,
const ext::shared_ptr<VanillaSwap>& swap,
const ext::shared_ptr<FixedVsFloatingSwap>& swap,
std::map<Time, Date> exerciseDates,
ext::shared_ptr<FdmMesher> mesher,
Size direction);
Expand All @@ -58,7 +58,7 @@ namespace QuantLib {
const ext::shared_ptr<ModelType> disModel_, fwdModel_;

const ext::shared_ptr<IborIndex> index_;
const ext::shared_ptr<VanillaSwap> swap_;
const ext::shared_ptr<FixedVsFloatingSwap> swap_;
const std::map<Time, Date> exerciseDates_;
const ext::shared_ptr<FdmMesher> mesher_;
const Size direction_;
Expand All @@ -68,21 +68,21 @@ namespace QuantLib {
inline FdmAffineModelSwapInnerValue<ModelType>::FdmAffineModelSwapInnerValue(
ext::shared_ptr<ModelType> disModel,
ext::shared_ptr<ModelType> fwdModel,
const ext::shared_ptr<VanillaSwap>& swap,
const ext::shared_ptr<FixedVsFloatingSwap>& swap,
std::map<Time, Date> exerciseDates,
ext::shared_ptr<FdmMesher> mesher,
Size direction)
: disModel_(std::move(disModel)), fwdModel_(std::move(fwdModel)), index_(swap->iborIndex()),
swap_(ext::shared_ptr<VanillaSwap>(new VanillaSwap(swap->type(),
swap->nominal(),
swap->fixedSchedule(),
swap->fixedRate(),
swap->fixedDayCount(),
swap->floatingSchedule(),
swap->iborIndex()->clone(fwdTs_),
swap->spread(),
swap->floatingDayCount(),
swap->paymentConvention()))),
swap_(ext::make_shared<VanillaSwap>(swap->type(),
swap->nominal(),
swap->fixedSchedule(),
swap->fixedRate(),
swap->fixedDayCount(),
swap->floatingSchedule(),
swap->iborIndex()->clone(fwdTs_),
swap->spread(),
swap->floatingDayCount(),
swap->paymentConvention())),
exerciseDates_(std::move(exerciseDates)), mesher_(std::move(mesher)), direction_(direction) {}

template <class ModelType> inline
Expand Down
Loading
Loading