Coverage Report

Created: 2025-08-28 06:30

/src/quantlib/ql/instruments/payoffs.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) 2003, 2006 Ferdinando Ametrano
5
 Copyright (C) 2006 Warren Chou
6
 Copyright (C) 2006, 2008 StatPro Italia srl
7
 Copyright (C) 2006 Chiara Fornarola
8
9
 This file is part of QuantLib, a free-software/open-source library
10
 for financial quantitative analysts and developers - http://quantlib.org/
11
12
 QuantLib is free software: you can redistribute it and/or modify it
13
 under the terms of the QuantLib license.  You should have received a
14
 copy of the license along with this program; if not, please email
15
 <quantlib-dev@lists.sf.net>. The license is also available online at
16
 <http://quantlib.org/license.shtml>.
17
18
 This program is distributed in the hope that it will be useful, but WITHOUT
19
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20
 FOR A PARTICULAR PURPOSE.  See the license for more details.
21
*/
22
23
#include <ql/instruments/payoffs.hpp>
24
25
namespace QuantLib {
26
27
0
    std::string NullPayoff::name() const {
28
0
        return "Null";
29
0
    }
30
31
0
    std::string NullPayoff::description() const {
32
0
        return name();
33
0
    }
34
35
0
    Real NullPayoff::operator()(Real) const {
36
0
        QL_FAIL("dummy payoff given");
37
0
    }
38
39
0
    void NullPayoff::accept(AcyclicVisitor& v) {
40
0
        auto* v1 = dynamic_cast<Visitor<NullPayoff>*>(&v);
41
0
        if (v1 != nullptr)
42
0
            v1->visit(*this);
43
0
        else
44
0
            Payoff::accept(v);
45
0
    }
46
47
48
49
0
    std::string TypePayoff::description() const {
50
0
        std::ostringstream result;
51
0
        result << name() << " " << optionType();
52
0
        return result.str();
53
0
    }
54
55
    //std::string StrikedPayoff::description() const {
56
    //    std::ostringstream result;
57
    //    result << ", " << strike() << " strike";
58
    //    return result.str();
59
    //}
60
61
0
    Real FloatingTypePayoff::operator()(Real) const {
62
0
        QL_FAIL("floating payoff not handled");
63
0
    }
64
65
0
    Real FloatingTypePayoff::operator()(Real price, Real strike) const {
66
0
        switch (type_) {
67
0
            case Option::Call:
68
0
                return std::max<Real>(price - strike,0.0);
69
0
            case Option::Put:
70
0
                return std::max<Real>(strike - price,0.0);
71
0
            default:
72
0
                QL_FAIL("unknown/illegal option type");
73
0
        }
74
0
    }
75
76
0
    std::string StrikedTypePayoff::description() const {
77
0
        std::ostringstream result;
78
0
        result << TypePayoff::description() << ", " <<
79
0
                  strike() << " strike";
80
0
        return result.str();
81
0
    }
82
83
0
    void FloatingTypePayoff::accept(AcyclicVisitor& v) {
84
0
        auto* v1 = dynamic_cast<Visitor<FloatingTypePayoff>*>(&v);
85
0
        if (v1 != nullptr)
86
0
            v1->visit(*this);
87
0
        else
88
0
            Payoff::accept(v);
89
0
    }
90
91
0
    Real PlainVanillaPayoff::operator()(Real price) const {
92
0
        switch (type_) {
93
0
          case Option::Call:
94
0
            return std::max<Real>(price-strike_,0.0);
95
0
          case Option::Put:
96
0
            return std::max<Real>(strike_-price,0.0);
97
0
          default:
98
0
            QL_FAIL("unknown/illegal option type");
99
0
        }
100
0
    }
101
102
0
    void PlainVanillaPayoff::accept(AcyclicVisitor& v) {
103
0
        auto* v1 = dynamic_cast<Visitor<PlainVanillaPayoff>*>(&v);
104
0
        if (v1 != nullptr)
105
0
            v1->visit(*this);
106
0
        else
107
0
            Payoff::accept(v);
108
0
    }
109
110
0
    Real PercentageStrikePayoff::operator()(Real price) const {
111
0
        switch (type_) {
112
0
          case Option::Call:
113
0
            return price*std::max<Real>(Real(1.0)-strike_,0.0);
114
0
          case Option::Put:
115
0
            return price*std::max<Real>(strike_-Real(1.0),0.0);
116
0
          default:
117
0
            QL_FAIL("unknown/illegal option type");
118
0
        }
119
0
    }
120
121
0
    void PercentageStrikePayoff::accept(AcyclicVisitor& v) {
122
0
        auto* v1 = dynamic_cast<Visitor<PercentageStrikePayoff>*>(&v);
123
0
        if (v1 != nullptr)
124
0
            v1->visit(*this);
125
0
        else
126
0
            Payoff::accept(v);
127
0
    }
128
129
0
    Real AssetOrNothingPayoff::operator()(Real price) const {
130
0
        switch (type_) {
131
0
          case Option::Call:
132
0
            return (price-strike_ > 0.0 ? price : 0.0);
133
0
          case Option::Put:
134
0
            return (strike_-price > 0.0 ? price : 0.0);
135
0
          default:
136
0
            QL_FAIL("unknown/illegal option type");
137
0
        }
138
0
    }
139
140
0
    void AssetOrNothingPayoff::accept(AcyclicVisitor& v) {
141
0
        auto* v1 = dynamic_cast<Visitor<AssetOrNothingPayoff>*>(&v);
142
0
        if (v1 != nullptr)
143
0
            v1->visit(*this);
144
0
        else
145
0
            Payoff::accept(v);
146
0
    }
147
148
0
    std::string CashOrNothingPayoff::description() const {
149
0
        std::ostringstream result;
150
0
        result << StrikedTypePayoff::description() << ", " << cashPayoff() << " cash payoff";
151
0
        return result.str();
152
0
    }
153
154
0
    Real CashOrNothingPayoff::operator()(Real price) const {
155
0
        switch (type_) {
156
0
          case Option::Call:
157
0
            return (price-strike_ > 0.0 ? cashPayoff_ : 0.0);
158
0
          case Option::Put:
159
0
            return (strike_-price > 0.0 ? cashPayoff_ : 0.0);
160
0
          default:
161
0
            QL_FAIL("unknown/illegal option type");
162
0
        }
163
0
    }
164
165
0
    void CashOrNothingPayoff::accept(AcyclicVisitor& v) {
166
0
        auto* v1 = dynamic_cast<Visitor<CashOrNothingPayoff>*>(&v);
167
0
        if (v1 != nullptr)
168
0
            v1->visit(*this);
169
0
        else
170
0
            Payoff::accept(v);}
171
172
0
    std::string GapPayoff::description() const {
173
0
        std::ostringstream result;
174
0
        result << StrikedTypePayoff::description() << ", " << secondStrike() << " strike payoff";
175
0
        return result.str();
176
0
    }
177
178
0
    Real GapPayoff::operator()(Real price) const {
179
0
        switch (type_) {
180
0
          case Option::Call:
181
0
            return (price-strike_ >= 0.0 ? Real(price-secondStrike_) : 0.0);
182
0
          case Option::Put:
183
0
              return (strike_ - price >= 0.0 ? Real(secondStrike_ - price) : 0.0);
184
0
          default:
185
0
            QL_FAIL("unknown/illegal option type");
186
0
        }
187
0
    }
188
189
0
    void GapPayoff::accept(AcyclicVisitor& v) {
190
0
        auto* v1 = dynamic_cast<Visitor<GapPayoff>*>(&v);
191
0
        if (v1 != nullptr)
192
0
            v1->visit(*this);
193
0
        else
194
0
            Payoff::accept(v);
195
0
    }
196
197
0
    Real SuperFundPayoff::operator()(Real price) const {
198
0
        return (price>=strike_ && price<secondStrike_) ? Real(price/strike_) : 0.0;
199
0
    }
200
201
0
    void SuperFundPayoff::accept(AcyclicVisitor& v) {
202
0
        auto* v1 = dynamic_cast<Visitor<SuperFundPayoff>*>(&v);
203
0
        if (v1 != nullptr)
204
0
            v1->visit(*this);
205
0
        else
206
0
            Payoff::accept(v);
207
0
    }
208
0
    std::string SuperSharePayoff::description() const {
209
0
        std::ostringstream result;
210
0
        result << StrikedTypePayoff::description() << ", " << secondStrike() << " second strike"<< ", " << cashPayoff() << " amount";
211
0
        return result.str();
212
0
    }
213
214
0
    Real SuperSharePayoff::operator()(Real price) const {
215
0
        return (price>=strike_ && price<secondStrike_) ? cashPayoff_ : 0.0;
216
0
    }
217
218
0
    void SuperSharePayoff::accept(AcyclicVisitor& v) {
219
0
        auto* v1 = dynamic_cast<Visitor<SuperSharePayoff>*>(&v);
220
0
        if (v1 != nullptr)
221
0
            v1->visit(*this);
222
0
        else
223
0
            Payoff::accept(v);
224
0
    }
225
226
}