Skip to content

Commit

Permalink
DEV: revise argument name of constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
shunmaruko committed Nov 19, 2023
1 parent cfa316b commit a70e7bd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 164 deletions.
206 changes: 54 additions & 152 deletions ql/instruments/assetswap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,18 @@ namespace QuantLib {
Real bondCleanPrice,
Real nonParRepayment,
Real gearing,
const ext::shared_ptr<IborIndex>& iborIndex,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Spread spread,
const DayCounter& floatingDayCounter,
Date dealMaturity,
bool payBondCoupon)
: Swap(2), bond_(std::move(bond)), bondCleanPrice_(bondCleanPrice),
nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parSwap) {
nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parSwap),
fairSpread_(Null<Real>()), fairCleanPrice_(Null<Real>()), fairNonParRepayment_(Null<Real>()) {
Schedule tempSch(bond_->settlementDate(),
bond_->maturityDate(),
iborIndex->tenor(),
iborIndex->fixingCalendar(),
iborIndex->businessDayConvention(),
iborIndex->businessDayConvention(),
bond_->maturityDate(), benchmarkIndex->tenor(),
benchmarkIndex->fixingCalendar(), benchmarkIndex->businessDayConvention(),
benchmarkIndex->businessDayConvention(),
DateGeneration::Backward,
false); // endOfMonth
if (dealMaturity==Date())
Expand Down Expand Up @@ -84,19 +83,28 @@ namespace QuantLib {
if (!parSwap_)
notional *= dirtyPrice/100.0;

if (floatingDayCounter==DayCounter())
legs_[1] = IborLeg(schedule, iborIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withGearings(gearing)
.withSpreads(spread);
else
legs_[1] = IborLeg(schedule, iborIndex)
.withNotionals(notional)
.withPaymentDayCounter(floatingDayCounter)
.withPaymentAdjustment(paymentAdjustment)
.withGearings(gearing)
.withSpreads(spread);
// check if benchmark index is ibor or ois
if (auto benchmarkOisIndex = ext::dynamic_pointer_cast<OvernightIndex>(benchmarkIndex)) {
OvernightLeg oisLeg = OvernightLeg(schedule, benchmarkOisIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (gearing != Null<Real>())
oisLeg = oisLeg.withGearings(gearing);
if (floatingDayCounter != DayCounter())
oisLeg = oisLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = oisLeg;
} else {
IborLeg iborLeg = IborLeg(schedule, benchmarkIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (gearing != Null<Real>())
iborLeg = iborLeg.withGearings(gearing);
if (floatingDayCounter != DayCounter())
iborLeg = iborLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = iborLeg;
}

Leg::const_iterator i;
for (i=legs_[1].begin(); i<legs_[1].end(); ++i)
Expand Down Expand Up @@ -165,21 +173,22 @@ namespace QuantLib {
AssetSwap::AssetSwap(bool payBondCoupon,
ext::shared_ptr<Bond> bond,
Real bondCleanPrice,
const ext::shared_ptr<IborIndex>& iborIndex,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Spread spread,
const Schedule& floatSchedule,
const DayCounter& floatingDayCounter,
bool parSwap)
: Swap(2), bond_(std::move(bond)), bondCleanPrice_(bondCleanPrice), nonParRepayment_(100),
spread_(spread), parSwap_(parSwap) {
spread_(spread), parSwap_(parSwap), fairSpread_(Null<Real>()), fairCleanPrice_(Null<Real>()),
fairNonParRepayment_(Null<Real>()) {
Schedule schedule = floatSchedule;
if (floatSchedule.empty())
schedule = Schedule(bond_->settlementDate(),
bond_->maturityDate(),
iborIndex->tenor(),
iborIndex->fixingCalendar(),
iborIndex->businessDayConvention(),
iborIndex->businessDayConvention(),
bond_->maturityDate(),
benchmarkIndex->tenor(),
benchmarkIndex->fixingCalendar(),
benchmarkIndex->businessDayConvention(),
benchmarkIndex->businessDayConvention(),
DateGeneration::Backward,
false); // endOfMonth

Expand Down Expand Up @@ -210,17 +219,24 @@ namespace QuantLib {
if (!parSwap_)
notional *= dirtyPrice/100.0;

if (floatingDayCounter==DayCounter())
legs_[1] = IborLeg(schedule, iborIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
else
legs_[1] = IborLeg(schedule, iborIndex)
.withNotionals(notional)
.withPaymentDayCounter(floatingDayCounter)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
// check if benchmark index is ibor or ois
if (auto benchmarkOisIndex = ext::dynamic_pointer_cast<OvernightIndex>(benchmarkIndex)) {
OvernightLeg oisLeg = OvernightLeg(schedule, benchmarkOisIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (floatingDayCounter != DayCounter())
oisLeg = oisLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = oisLeg;
} else {
IborLeg iborLeg = IborLeg(schedule, benchmarkIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (floatingDayCounter != DayCounter())
iborLeg = iborLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = iborLeg;
}

for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i)
registerWith(*i);
Expand Down Expand Up @@ -270,120 +286,6 @@ namespace QuantLib {
}
}

AssetSwap::AssetSwap(ext::shared_ptr<Bond> bond,
Real bondCleanPrice,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Real nonParRepayment,
Real gearing,
Spread spread,
const Schedule& floatSchedule,
const DayCounter& floatingDayCounter,
bool parAssetSwap,
bool payBondCoupon)
: Swap(2), bond_(std::move(bond)), bondCleanPrice_(bondCleanPrice),
nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parAssetSwap),
fairSpread_(Null<Real>()), fairCleanPrice_(Null<Real>()), fairNonParRepayment_(Null<Real>()) {

Schedule schedule = floatSchedule;
if (floatSchedule.empty())
schedule =
Schedule(bond_->settlementDate(), bond_->maturityDate(), benchmarkIndex->tenor(),
benchmarkIndex->fixingCalendar(), benchmarkIndex->businessDayConvention(),
benchmarkIndex->businessDayConvention(), DateGeneration::Backward,
false); // endOfMonth

// the following might become an input parameter
BusinessDayConvention paymentAdjustment = Following;

Date finalDate = schedule.calendar().adjust(schedule.endDate(), paymentAdjustment);
Date adjBondMaturityDate =
schedule.calendar().adjust(bond_->maturityDate(), paymentAdjustment);

QL_REQUIRE(finalDate == adjBondMaturityDate,
"adjusted schedule end date ("
<< finalDate << ") must be equal to adjusted bond maturity date ("
<< adjBondMaturityDate << ")");

// bondCleanPrice must be the (forward) clean price
// at the floating schedule start date
upfrontDate_ = schedule.startDate();
Real dirtyPrice = bondCleanPrice_ + bond_->accruedAmount(upfrontDate_);

Real notional = bond_->notional(upfrontDate_);
/* In the market asset swap, the bond is purchased in return for
payment of the full price. The notional of the floating leg is
then scaled by the full price. */
if (!parSwap_)
notional *= dirtyPrice / 100.0;

// check if benchmark index is ibor or ois
if (auto benchmarkOisIndex = ext::dynamic_pointer_cast<OvernightIndex>(benchmarkIndex)) {
OvernightLeg oisLeg = OvernightLeg(schedule, benchmarkOisIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (gearing != Null<Real>())
oisLeg = oisLeg.withGearings(gearing);
if (floatingDayCounter != DayCounter())
oisLeg = oisLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = oisLeg;
} else {
IborLeg iborLeg = IborLeg(schedule, benchmarkIndex)
.withNotionals(notional)
.withPaymentAdjustment(paymentAdjustment)
.withSpreads(spread);
if (gearing != Null<Real>())
iborLeg = iborLeg.withGearings(gearing);
if (floatingDayCounter != DayCounter())
iborLeg = iborLeg.withPaymentDayCounter(floatingDayCounter);
legs_[1] = iborLeg;
}

for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
registerWith(*i);

const Leg& bondLeg = bond_->cashflows();
for (auto i = bondLeg.begin(); i < bondLeg.end(); ++i) {
// whatever might be the choice for the discounting engine
// bond flows on upfrontDate_ must be discarded
bool upfrontDateBondFlows = false;
if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows))
legs_[0].push_back(*i);
}

QL_REQUIRE(!legs_[0].empty(), "empty bond leg to start with");

// special flows
if (parSwap_) {
// upfront on the floating leg
Real upfront = (dirtyPrice - 100.0) / 100.0 * notional;
ext::shared_ptr<CashFlow> upfrontCashFlow(new SimpleCashFlow(upfront, upfrontDate_));
legs_[1].insert(legs_[1].begin(), upfrontCashFlow);
// backpayment on the floating leg
// (accounts for non-par redemption, if any)
Real backPayment = notional;
ext::shared_ptr<CashFlow> backPaymentCashFlow(
new SimpleCashFlow(backPayment, finalDate));
legs_[1].push_back(backPaymentCashFlow);
} else {
// final notional exchange
ext::shared_ptr<CashFlow> finalCashFlow(new SimpleCashFlow(notional, finalDate));
legs_[1].push_back(finalCashFlow);
}

QL_REQUIRE(!legs_[0].empty(), "empty bond leg");
for (Leg::const_iterator i = legs_[0].begin(); i < legs_[0].end(); ++i)
registerWith(*i);

if (payBondCoupon) {
payer_[0] = -1.0;
payer_[1] = +1.0;
} else {
payer_[0] = +1.0;
payer_[1] = -1.0;
}
}

void AssetSwap::setupArguments(PricingEngine::arguments* args) const {

Swap::setupArguments(args);
Expand Down
14 changes: 2 additions & 12 deletions ql/instruments/assetswap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace QuantLib {
AssetSwap(bool payBondCoupon,
ext::shared_ptr<Bond> bond,
Real bondCleanPrice,
const ext::shared_ptr<IborIndex>& iborIndex,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Spread spread,
const Schedule& floatSchedule = Schedule(),
const DayCounter& floatingDayCount = DayCounter(),
Expand All @@ -67,22 +67,12 @@ namespace QuantLib {
Real bondCleanPrice,
Real nonParRepayment,
Real gearing,
const ext::shared_ptr<IborIndex>& iborIndex,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Spread spread = 0.0,
const DayCounter& floatingDayCount = DayCounter(),
Date dealMaturity = Date(),
bool payBondCoupon = false);

AssetSwap(ext::shared_ptr<Bond> bond,
Real bondCleanPrice,
const ext::shared_ptr<IborIndex>& benchmarkIndex,
Real nonParRepayment = 100.0,
Real gearing = Null<Real>(),
Spread spread = 0.0,
const Schedule& floatSchedule = Schedule(),
const DayCounter& floatingDayCounter = DayCounter(),
bool parAssetSwap = true,
bool payBondCoupon = false);
// results
Spread fairSpread() const;
Real floatingLegBPS() const;
Expand Down

0 comments on commit a70e7bd

Please sign in to comment.