Coverage Report

Created: 2025-08-05 06:45

/src/quantlib/ql/pricingengines/bond/riskybondengine.hpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2008 Roland Lichters
5
 Copyright (C) 2021 Lew Wei Hao
6
7
 This file is part of QuantLib, a free-software/open-source library
8
 for financial quantitative analysts and developers - http://quantlib.org/
9
10
 QuantLib is free software: you can redistribute it and/or modify it
11
 under the terms of the QuantLib license.  You should have received a
12
 copy of the license along with this program; if not, please email
13
 <quantlib-dev@lists.sf.net>. The license is also available online at
14
 <http://quantlib.org/license.shtml>.
15
16
 This program is distributed in the hope that it will be useful, but WITHOUT
17
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 FOR A PARTICULAR PURPOSE.  See the license for more details.
19
*/
20
21
/*! \file riskybondengine.hpp
22
    \brief risky bond engine
23
*/
24
25
#ifndef quantlib_risky_bond_engine_hpp
26
#define quantlib_risky_bond_engine_hpp
27
28
#include <ql/instruments/bond.hpp>
29
#include <ql/termstructures/yieldtermstructure.hpp>
30
#include <ql/termstructures/defaulttermstructure.hpp>
31
#include <ql/handle.hpp>
32
33
namespace QuantLib {
34
35
    //! Risky pricing engine for bonds
36
    /*! The value of each cashflow is contingent to survival, i.e., the knockout
37
        probability is considered.
38
39
        In each of the \f$n\f$ coupon periods, we can calculate the value
40
        in the case of survival and default, assuming that the issuer
41
        can only default in the middle of a coupon period. We denote this time
42
        \f$T_{i}^{mid}=\frac{T_{i-1}+T_{i}}{2}\f$.
43
44
        Given survival we receive the full cash flow (both coupons and notional).
45
        The time \f$t\f$ value of these payments are given by
46
        \f[
47
            \sum_{i=1}^{n}CF_{i}P(t,T_{i})Q(T_{i}<\tau)
48
        \f]
49
        where \f$P(t,T)\f$ is the time \f$T\f$ discount bond
50
        and \f$Q(T<\tau)\f$ is the time \f$T\f$ survival probability.
51
        \f$n\f$ is the number of coupon periods. This takes care of the payments
52
        in the case of survival.
53
54
        Given default we receive only a fraction of the notional at default.
55
        \f[
56
            \sum_{i=1}^{n}Rec N(T_{i}^{mid}) P(t,T_{i}^{mid})Q(T_{i-1}<\tau\leq T_{i})
57
        \f]
58
        where \f$Rec\f$ is the recovery rate and \f$N(T)\f$ is the time T notional. The default probability can be
59
        rewritten as
60
        \f[
61
            Q(T_{i-1}<\tau\leq T_{i})=Q(T_{i}<\tau)-Q(T_{i-1}<\tau)=(1-Q(T_{i}\geq\tau))-(1-Q(T_{i-1}\geq\tau))=Q(T_{i-1}\geq\tau)-Q(T_{i}\geq\tau)
62
        \f]
63
    */
64
    class RiskyBondEngine : public Bond::engine {
65
      public:
66
        RiskyBondEngine(Handle<DefaultProbabilityTermStructure> defaultTS,
67
                        Real recoveryRate,
68
                        Handle<YieldTermStructure> yieldTS);
69
        void calculate() const override;
70
        Handle<DefaultProbabilityTermStructure> defaultTS() const;
71
        Real recoveryRate() const;
72
        Handle<YieldTermStructure> yieldTS() const;
73
      private:
74
        Handle<DefaultProbabilityTermStructure> defaultTS_;
75
        Real recoveryRate_;
76
        Handle<YieldTermStructure> yieldTS_;
77
    };
78
79
80
0
    inline Handle<DefaultProbabilityTermStructure> RiskyBondEngine::defaultTS() const {
81
0
        return defaultTS_;
82
0
    }
83
84
0
    inline Real RiskyBondEngine::recoveryRate() const { return recoveryRate_; }
85
86
0
    inline Handle<YieldTermStructure> RiskyBondEngine::yieldTS() const { return yieldTS_; }
87
88
}
89
90
#endif