Coverage Report

Created: 2025-08-11 06:28

/src/quantlib/ql/instruments/payoffs.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) 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
/*! \file payoffs.hpp
24
    \brief Payoffs for various options
25
*/
26
27
#ifndef quantlib_payoffs_hpp
28
#define quantlib_payoffs_hpp
29
30
#include <ql/option.hpp>
31
#include <ql/payoff.hpp>
32
33
namespace QuantLib {
34
35
    //! Dummy %payoff class
36
    class NullPayoff : public Payoff {
37
      public:
38
        //! \name Payoff interface
39
        //@{
40
        std::string name() const override;
41
        std::string description() const override;
42
        Real operator()(Real price) const override;
43
        void accept(AcyclicVisitor&) override;
44
        //@}
45
    };
46
47
48
    //! Intermediate class for put/call payoffs
49
    class TypePayoff : public Payoff {
50
      public:
51
0
        Option::Type optionType() const { return type_; };
52
        //! \name Payoff interface
53
        //@{
54
        std::string description() const override;
55
        //@}
56
      protected:
57
521k
        explicit TypePayoff(Option::Type type) : type_(type) {}
58
        Option::Type type_;
59
    };
60
61
    ////! Intermediate class for payoffs based on a fixed strike
62
    //class StrikedPayoff : public Payoff {
63
    //  public:
64
    //    StrikedPayoff(Real strike) : strike_(strike) {}
65
    //    Real strike() const { return strike_; };
66
    //    //! \name Payoff interface
67
    //    //@{
68
    //    std::string description() const;
69
    //    //@}
70
    //  protected:
71
    //    Real strike_;
72
    //};
73
74
    //! %Payoff based on a floating strike
75
    class FloatingTypePayoff : public TypePayoff {
76
      public:
77
0
        FloatingTypePayoff(Option::Type type) : TypePayoff(type) {}
78
        //! \name Payoff interface
79
        //@{
80
0
        std::string name() const override { return "FloatingType"; }
81
        Real operator()(Real price, Real strike) const;
82
        Real operator()(Real price) const override;
83
        void accept(AcyclicVisitor&) override;
84
        //@}
85
    };
86
87
    //! Intermediate class for payoffs based on a fixed strike
88
    class StrikedTypePayoff : public TypePayoff
89
                              //, public StrikedPayoff
90
    {
91
      public:
92
        //! \name Payoff interface
93
        //@{
94
        std::string description() const override;
95
        //@}
96
0
        Real strike() const { return strike_; };
97
      protected:
98
        StrikedTypePayoff(Option::Type type,
99
                          Real strike)
100
521k
        : TypePayoff(type), strike_(strike) {}
101
        Real strike_;
102
    };
103
104
    //! Plain-vanilla payoff
105
    class PlainVanillaPayoff : public StrikedTypePayoff {
106
      public:
107
        PlainVanillaPayoff(Option::Type type,
108
                           Real strike)
109
521k
        : StrikedTypePayoff(type, strike) {}
110
        //! \name Payoff interface
111
        //@{
112
0
        std::string name() const override { return "Vanilla"; }
113
        Real operator()(Real price) const override;
114
        void accept(AcyclicVisitor&) override;
115
        //@}
116
    };
117
118
    //! %Payoff with strike expressed as percentage
119
    class PercentageStrikePayoff : public StrikedTypePayoff {
120
      public:
121
        PercentageStrikePayoff(Option::Type type,
122
                               Real moneyness)
123
0
        : StrikedTypePayoff(type, moneyness) {}
124
        //! \name Payoff interface
125
        //@{
126
0
        std::string name() const override { return "PercentageStrike"; }
127
        Real operator()(Real price) const override;
128
        void accept(AcyclicVisitor&) override;
129
        //@}
130
    };
131
132
    /*! Definitions of Binary path-independent payoffs used below,
133
        can be found in M. Rubinstein, E. Reiner:"Unscrambling The Binary Code", Risk, Vol.4 no.9,1991.
134
        (see: http://www.in-the-money.com/artandpap/Binary%20Options.doc)
135
    */
136
137
    //! Binary asset-or-nothing payoff
138
    class AssetOrNothingPayoff : public StrikedTypePayoff {
139
      public:
140
        AssetOrNothingPayoff(Option::Type type,
141
                             Real strike)
142
0
        : StrikedTypePayoff(type, strike) {}
143
        //! \name Payoff interface
144
        //@{
145
0
        std::string name() const override { return "AssetOrNothing"; }
146
        Real operator()(Real price) const override;
147
        void accept(AcyclicVisitor&) override;
148
        //@}
149
    };
150
151
    //! Binary cash-or-nothing payoff
152
    class CashOrNothingPayoff : public StrikedTypePayoff {
153
      public:
154
        CashOrNothingPayoff(Option::Type type,
155
                            Real strike,
156
                            Real cashPayoff)
157
0
        : StrikedTypePayoff(type, strike), cashPayoff_(cashPayoff) {}
158
        //! \name Payoff interface
159
        //@{
160
0
        std::string name() const override { return "CashOrNothing"; }
161
        std::string description() const override;
162
        Real operator()(Real price) const override;
163
        void accept(AcyclicVisitor&) override;
164
        //@}
165
0
        Real cashPayoff() const { return cashPayoff_;}
166
      protected:
167
        Real cashPayoff_;
168
    };
169
170
    //! Binary gap payoff
171
    /*! This payoff is equivalent to being a) long a PlainVanillaPayoff at
172
        the first strike (same Call/Put type) and b) short a
173
        CashOrNothingPayoff at the first strike (same Call/Put type) with
174
        cash payoff equal to the difference between the second and the first
175
        strike.
176
        \warning this payoff can be negative depending on the strikes
177
    */
178
    class GapPayoff : public StrikedTypePayoff {
179
      public:
180
        GapPayoff(Option::Type type,
181
                  Real strike,
182
                  Real secondStrike) // a.k.a. payoff strike
183
0
        : StrikedTypePayoff(type, strike), secondStrike_(secondStrike) {}
184
        //! \name Payoff interface
185
        //@{
186
0
        std::string name() const override { return "Gap"; }
187
        std::string description() const override;
188
        Real operator()(Real price) const override;
189
        void accept(AcyclicVisitor&) override;
190
        //@}
191
0
        Real secondStrike() const { return secondStrike_;}
192
      protected:
193
        Real secondStrike_;
194
    };
195
196
    //! Binary supershare and superfund payoffs
197
198
    //! Binary superfund payoff
199
    /*! Superfund sometimes also called "supershare", which can lead to ambiguity; within QuantLib
200
        the terms supershare and superfund are used consistently according to the definitions in
201
        Bloomberg OVX function's help pages.
202
    */
203
    /*! This payoff is equivalent to being (1/lowerstrike) a) long (short) an AssetOrNothing
204
        Call (Put) at the lower strike and b) short (long) an AssetOrNothing
205
        Call (Put) at the higher strike
206
    */
207
    class SuperFundPayoff : public StrikedTypePayoff {
208
      public:
209
        SuperFundPayoff(Real strike,
210
                        Real secondStrike)
211
        : StrikedTypePayoff(Option::Call, strike),
212
0
          secondStrike_(secondStrike) {
213
0
            QL_REQUIRE(strike>0.0,
214
0
                       "strike (" <<  strike << ") must be "
215
0
                       "positive");
216
0
            QL_REQUIRE(secondStrike>strike,
217
0
                       "second strike (" <<  secondStrike << ") must be "
218
0
                       "higher than first strike (" << strike << ")");
219
0
        }
220
        //! \name Payoff interface
221
        //@{
222
0
        std::string name() const override { return "SuperFund"; }
223
        Real operator()(Real price) const override;
224
        void accept(AcyclicVisitor&) override;
225
        //@}
226
0
        Real secondStrike() const { return secondStrike_;}
227
      protected:
228
        Real secondStrike_;
229
    };
230
231
    //! Binary supershare payoff
232
    class SuperSharePayoff : public StrikedTypePayoff {
233
      public:
234
        SuperSharePayoff(Real strike,
235
                         Real secondStrike,
236
                         Real cashPayoff)
237
        : StrikedTypePayoff(Option::Call, strike),
238
          secondStrike_(secondStrike),
239
0
          cashPayoff_(cashPayoff){
240
0
              QL_REQUIRE(secondStrike>strike,
241
0
              "second strike (" <<  secondStrike << ") must be "
242
0
              "higher than first strike (" << strike << ")");}
243
244
        //! \name Payoff interface
245
        //@{
246
0
        std::string name() const override { return "SuperShare"; }
247
        std::string description() const override;
248
        Real operator()(Real price) const override;
249
        void accept(AcyclicVisitor&) override;
250
        //@}
251
0
        Real secondStrike() const { return secondStrike_;}
252
0
        Real cashPayoff() const { return cashPayoff_;}
253
      protected:
254
        Real secondStrike_;
255
        Real cashPayoff_;
256
    };
257
}
258
259
#endif