Coverage Report

Created: 2026-02-03 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/experimental/swaptions/irregularswaption.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
5
 Copyright (C) 2006 Cristina Duminuco
6
 Copyright (C) 2006 Marco Bianchetti
7
 Copyright (C) 2007 StatPro Italia srl
8
 Copyright (C) 2010 Andre Miemiec
9
10
 This file is part of QuantLib, a free-software/open-source library
11
 for financial quantitative analysts and developers - http://quantlib.org/
12
13
 QuantLib is free software: you can redistribute it and/or modify it
14
 under the terms of the QuantLib license.  You should have received a
15
 copy of the license along with this program; if not, please email
16
 <quantlib-dev@lists.sf.net>. The license is also available online at
17
 <https://www.quantlib.org/license.shtml>.
18
19
 This program is distributed in the hope that it will be useful, but WITHOUT
20
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21
 FOR A PARTICULAR PURPOSE.  See the license for more details.
22
*/
23
24
#include <ql/any.hpp>
25
#include <ql/exercise.hpp>
26
#include <ql/experimental/swaptions/irregularswaption.hpp>
27
#include <ql/math/solvers1d/newtonsafe.hpp>
28
#include <ql/pricingengines/swaption/blackswaptionengine.hpp>
29
#include <ql/quotes/simplequote.hpp>
30
#include <utility>
31
32
namespace QuantLib {
33
34
    namespace {
35
36
        class IrregularImpliedVolHelper {
37
          public:
38
            IrregularImpliedVolHelper(const IrregularSwaption&,
39
                                      Handle<YieldTermStructure> discountCurve,
40
                                      Real targetValue);
41
            Real operator()(Volatility x) const;
42
            Real derivative(Volatility x) const;
43
          private:
44
            ext::shared_ptr<PricingEngine> engine_;
45
            Handle<YieldTermStructure> discountCurve_;
46
            Real targetValue_;
47
            ext::shared_ptr<SimpleQuote> vol_;
48
            const Instrument::results* results_;
49
        };
50
51
        IrregularImpliedVolHelper::IrregularImpliedVolHelper(
52
            const IrregularSwaption& swaption,
53
            Handle<YieldTermStructure> discountCurve,
54
            Real targetValue)
55
0
        : discountCurve_(std::move(discountCurve)), targetValue_(targetValue),
56
0
          vol_(ext::make_shared<SimpleQuote>(-1.0)) {
57
58
0
            Handle<Quote> h(vol_);
59
0
            engine_ = ext::shared_ptr<PricingEngine>(new
60
0
                                    BlackSwaptionEngine(discountCurve_, h));
61
0
            swaption.setupArguments(engine_->getArguments());
62
63
0
            results_ =
64
0
                dynamic_cast<const Instrument::results*>(engine_->getResults());
65
0
        }
66
67
0
        Real IrregularImpliedVolHelper::operator()(Volatility x) const {
68
0
            if (x!=vol_->value()) {
69
0
                vol_->setValue(x);
70
0
                engine_->calculate();
71
0
            }
72
0
            return results_->value-targetValue_;
73
0
        }
74
75
0
        Real IrregularImpliedVolHelper::derivative(Volatility x) const {
76
0
            if (x!=vol_->value()) {
77
0
                vol_->setValue(x);
78
0
                engine_->calculate();
79
0
            }
80
0
            auto vega_ = results_->additionalResults.find("vega");
81
0
            QL_REQUIRE(vega_ != results_->additionalResults.end(),
82
0
                       "vega not provided");
83
0
            return ext::any_cast<Real>(vega_->second);
84
0
        }
85
    }
86
87
    std::ostream& operator<<(std::ostream& out,
88
0
                             IrregularSettlement::Type t) {
89
0
        switch (t) {
90
0
          case IrregularSettlement::Physical:
91
0
            return out << "Delivery";
92
0
          case IrregularSettlement::Cash:
93
0
            return out << "Cash";
94
0
          default:
95
0
            QL_FAIL("unknown IrregularSettlement::Type(" << Integer(t) << ")");
96
0
        }
97
0
    }
98
99
    IrregularSwaption::IrregularSwaption(ext::shared_ptr<IrregularSwap> swap,
100
                                         const ext::shared_ptr<Exercise>& exercise,
101
                                         IrregularSettlement::Type delivery)
102
0
    : Option(ext::shared_ptr<Payoff>(), exercise), swap_(std::move(swap)),
103
0
      settlementType_(delivery) {
104
0
        registerWith(swap_);
105
0
    }
Unexecuted instantiation: QuantLib::IrregularSwaption::IrregularSwaption(boost::shared_ptr<QuantLib::IrregularSwap>, boost::shared_ptr<QuantLib::Exercise> const&, QuantLib::IrregularSettlement::Type)
Unexecuted instantiation: QuantLib::IrregularSwaption::IrregularSwaption(boost::shared_ptr<QuantLib::IrregularSwap>, boost::shared_ptr<QuantLib::Exercise> const&, QuantLib::IrregularSettlement::Type)
106
107
0
    bool IrregularSwaption::isExpired() const {
108
0
        return detail::simple_event(exercise_->dates().back()).hasOccurred();
109
0
    }
110
111
0
    void IrregularSwaption::setupArguments(PricingEngine::arguments* args) const {
112
113
0
        swap_->setupArguments(args);
114
115
0
        auto* arguments = dynamic_cast<IrregularSwaption::arguments*>(args);
116
117
0
        QL_REQUIRE(arguments != nullptr, "wrong argument type");
118
119
0
        arguments->swap = swap_;
120
0
        arguments->settlementType = settlementType_;
121
0
        arguments->exercise = exercise_;
122
0
    }
123
124
0
    void IrregularSwaption::arguments::validate() const {
125
0
        IrregularSwap::arguments::validate();
126
0
        QL_REQUIRE(swap, "Irregular swap not set");
127
0
        QL_REQUIRE(exercise, "exercise not set");
128
0
    }
129
130
    Volatility IrregularSwaption::impliedVolatility(
131
                              Real targetValue,
132
                              const Handle<YieldTermStructure>& discountCurve,
133
                              Volatility guess,
134
                              Real accuracy,
135
                              Natural maxEvaluations,
136
                              Volatility minVol,
137
0
                              Volatility maxVol) const {
138
0
        calculate();
139
0
        QL_REQUIRE(!isExpired(), "instrument expired");
140
141
0
        IrregularImpliedVolHelper f(*this, discountCurve, targetValue);
142
        //Brent solver;
143
0
        NewtonSafe solver;
144
0
        solver.setMaxEvaluations(maxEvaluations);
145
0
        return solver.solve(f, accuracy, guess, minVol, maxVol);
146
0
    }
147
148
}