Pricing Defaultable Zero-Coupon Bonds with Recovery of Market Value
Summary
The document derives a pricing framework for a defaultable zero-coupon bond under recovery of market value. It begins with a hazard rate: conditional default probability over a short interval is approximated by the intensity times the interval length, while survival probability is the exponential of the negative integrated intensity. The question then combines discounted survival and recovery cash flows, but struggles to evaluate the recovery integral.
The accepted explanation defines the bond’s pre-default value and assumes recovery is a fraction of that value at default. Under a condition separating default information from market information, together with a filtration-switching identity, the valuation is rewritten using discounting at the short rate plus default intensity. A martingale argument then yields the initial value as a risk-neutral expectation discounted at the short rate plus the loss-given-default fraction times intensity. The derivation depends on the recovery convention and stated filtration assumptions; it is not a universal formula for recovery of par or other recovery mechanisms. A second answer only reiterates the hazard-rate identity.
Key ideas
- The hazard rate determines short-interval conditional default probability and the survival probability over time.
- The pricing setup assumes recovery equals a fraction of the bond’s pre-default market value.
- Filtration switching and conditional independence assumptions connect default information with market information in the valuation.
- The resulting discount rate includes the short rate and the hazard rate scaled by the loss fraction.
- The formula depends on its recovery convention and modeling assumptions, so other recovery mechanisms require different treatment.
Tags
Full text
# Setting up Schedule for an amortizing floater in QuantLib
# Setting up Schedule for an amortizing floater in QuantLib
I am unsure as to the exact arguments required for the Schedule function for an amortizing floater - my code is listed below. Specifically, my question pertains to whether the schedule should always start from the issue date of the bond or should it start from the settlement date if the bond is seasoned. I seem to have seen usage both ways in some of the examples on the web so I am a bit confused.
I would expect that the NPV functions index into the right cashflow based on the settlement date provided but just checking.
Also, if anyone has a working example of an AmortizingFloatingRateBond which calculates the DM given a price (or vice versa) using a notional schedule,that'd be much appreciated.
Code Snippet:
```
QuantLib::JointCalendar calendar = QuantLib::JointCalendar(QuantLib::UnitedStates(),QuantLib::UnitedKingdom(),
JoinBusinessDays);
QuantLib::DayCounter dayCounter = QuantLib::Actual360();
QuantLib::Integer fixingDays = 1;
QuantLib::Natural settlementDays = 3;
QuantLib::Date tradeDate(20, QuantLib::September, 2013);
QuantLib::Date settlementDate = calendar.advance(tradeDate, settlementDays, QuantLib::Days);
settlementDate = calendar.adjust(settlementDate);
QuantLib::Settings::instance().evaluationDate() = tradeDate;
QuantLib::Date issueDate(25,QuantLib::July,2013);
QuantLib::Period p1m = QuantLib::Period(1,QuantLib::Months);
// Number of payments
int num_cashflows = 120;
QuantLib::Date maturityDate = issueDate + num_cashflows * p1m;
QuantLib::Schedule mySchedule(issueDate,
maturityDate,
QuantLib::Period(QuantLib::Monthly),
calendar,
QuantLib::BusinessDayConvention::Unadjusted,
QuantLib::BusinessDayConvention::ModifiedFollowing,
QuantLib::DateGeneration::Forward,
false);
QuantLib::AmortizingFloatingRateBond MyFloater(settlementDays,
Notional,
mySchedule,
libor,
QuantLib::Actual360(),
QuantLib::BusinessDayConvention::ModifiedFollowing,
fixingDays,
std::vector<QuantLib::Real>(1,1.0),
std::vector<QuantLib::Spread>(1,Spread),
std::vector<QuantLib::Rate>(),
std::vector<QuantLib::Rate>(),
true,
issueDate);
MyFloater.setPricingEngine(bondEngine);
std::vector<QuantLib::Date> paySchedule = mySchedule.dates();
std::vector<QuantLib::Date>::iterator pIter;
QuantLib::Date priorDate;
for (pIter = paySchedule.begin(); pIter != paySchedule.end() && *pIter < settlementDate; ++pIter){
priorDate = *pIter;
libor->addFixing(calendar.advance(priorDate, QuantLib::Period(-fixingDays,QuantLib::Days)), 0.1805/100);
}
```
## Answer by Luigi Ballabio (score 3)
https://quant.stackexchange.com/a/8973
As for the first question, the schedule should start from the issue date. The bond will manage cash flows correctly based on the evaluation date.
The second is a bit trickier, and I don't think I have working code handy. The general idea is: if you want to add a spread to the rate of the bond (to go from discount margin to price) you'll have to modify the term structure you pass to your Libor instance. Instead of linking the term-structure handle to the Libor curve, create an instance of `ForwardSpreadedTermStructure` passing the Libor curve and a quote holding the spread; something like
```
boost::shared_ptr<SimpleQuote> spread(new SimpleQuote(0.0));
boost::shared_ptr<YieldTermStructure> spreadedCurve(
new ForwardSpreadedTermStructure(liborCurve,
Handle<Quote>(spread)));
libor = boost::shared_ptr<IborIndex>(
new USDLibor(1*Months,
Handle<YieldTermStructure>(spreadedCurve)));
```
If you initialize the bond with the Libor instance above, you should be able to write:
```
spread->setValue(0.002);
```
and see the bond price change accordingly.
To go from price to DM, you have to invert the above in some way. The easiest is probably to create a function object that takes a spread and returns the difference between the target price and the price calculated with the current DM (it will probably have to hold a reference to the bond and perform the calculation I outlined). Once you have the function object, you can pass it to any of the 1-D solvers available in the library. The solver will return the spread that gives a null price difference; that is, the spread for which the price equals the target price.
Update: as per Calculating Discount Margin on a floating rate bond using QuantLib, you should use the original LIBOR curve for forecast and the curve plus spread for discounting; thus, something like
```
shared_ptr<SimpleQuote> spread = make_shared<SimpleQuote>(0.0);
shared_ptr<YieldTermStructure> spreadedCurve =
make_shared<ForwardSpreadedTermStructure>(liborCurve,
Handle<Quote>(spread));
libor = make_shared<USDLibor>(1*Months,
Handle<YieldTermStructure>(liborCurve));
bondEngine = make_shared<DiscountingBondEngine>(
Handle<YieldTermStructure>(spreadedCurve));
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.