Coverage Report

Created: 2025-08-11 06:28

/src/quantlib/ql/experimental/credit/blackcdsoptionengine.cpp
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 Stamm
5
 Copyright (C) 2009 Jose Aparicio
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
#include <ql/exercise.hpp>
22
#include <ql/experimental/credit/blackcdsoptionengine.hpp>
23
#include <ql/pricingengines/blackformula.hpp>
24
#include <ql/quote.hpp>
25
#include <ql/termstructures/yieldtermstructure.hpp>
26
#include <utility>
27
28
namespace QuantLib {
29
30
    BlackCdsOptionEngine::BlackCdsOptionEngine(Handle<DefaultProbabilityTermStructure> probability,
31
                                               Real recoveryRate,
32
                                               Handle<YieldTermStructure> termStructure,
33
                                               Handle<Quote> volatility)
34
0
    : probability_(std::move(probability)), recoveryRate_(recoveryRate),
35
0
      termStructure_(std::move(termStructure)), volatility_(std::move(volatility)) {
36
37
0
        registerWith(probability_);
38
0
        registerWith(termStructure_);
39
0
        registerWith(volatility_);
40
0
    }
41
42
0
    void BlackCdsOptionEngine::calculate() const {
43
44
0
        Date maturityDate = arguments_.swap->coupons().front()->date();
45
0
        Date exerciseDate = arguments_.exercise->date(0);
46
0
        QL_REQUIRE(maturityDate > exerciseDate,
47
0
                   "Underlying CDS should start after option maturity");
48
0
        Date settlement   = termStructure_->referenceDate();
49
50
0
        Rate spotFwdSpread = arguments_.swap->fairSpread();
51
0
        Rate swapSpread    = arguments_.swap->runningSpread();
52
53
0
        DayCounter tSDc = termStructure_->dayCounter();
54
55
        // The sense of the underlying/option has to be sent this way
56
        // to the Black formula, no sign.
57
0
        Real riskyAnnuity =
58
0
            std::fabs(arguments_.swap->couponLegNPV() / swapSpread);
59
0
        results_.riskyAnnuity = riskyAnnuity;
60
61
0
        Time T = tSDc.yearFraction(settlement, exerciseDate);
62
63
0
        Real stdDev = volatility_->value()  * std::sqrt(T);
64
0
        Option::Type callPut = (arguments_.side == Protection::Buyer) ?
65
0
                                                   Option::Call : Option::Put;
66
67
0
        results_.value =
68
0
            blackFormula(callPut, swapSpread, spotFwdSpread,
69
0
                         stdDev, riskyAnnuity);
70
71
        // if a non knock-out payer option, add front end protection value
72
0
        if (arguments_.side == Protection::Buyer && !arguments_.knocksOut) {
73
0
            Real frontEndProtection =
74
0
                Integer(callPut) * arguments_.swap->notional()
75
0
                * (1.-recoveryRate_)
76
0
                * probability_->defaultProbability(exerciseDate)
77
0
                * termStructure_->discount(exerciseDate);
78
0
            results_.value += frontEndProtection;
79
0
        }
80
0
    }
81
82
0
    Handle<YieldTermStructure> BlackCdsOptionEngine::termStructure() {
83
0
        return termStructure_;
84
0
    }
85
86
0
    Handle<Quote> BlackCdsOptionEngine::volatility() {
87
0
        return volatility_;
88
0
    }
89
90
}