QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
americanpayoffathit.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004 Ferdinando Ametrano
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
22
23namespace QuantLib {
24
26 Real spot, DiscountFactor discount, DiscountFactor dividendDiscount,
27 Real variance, const ext::shared_ptr<StrikedTypePayoff>& payoff)
28 : spot_(spot), discount_(discount), dividendDiscount_(dividendDiscount),
30
31 QL_REQUIRE(spot_>0.0,
32 "positive spot value required");
33
35 "positive discount required");
36
38 "positive dividend discount required");
39
41 "negative variance not allowed");
42
43 stdDev_ = std::sqrt(variance_);
44
45 Option::Type type = payoff->optionType();
46 strike_ = payoff->strike();
47
48
49 log_H_S_ = std::log(strike_/spot_);
50
51 Real n_d1, n_d2;
52 if (variance_>=QL_EPSILON) {
53 if (discount_==0.0 && dividendDiscount_==0.0) {
54 mu_ = - 0.5;
55 lambda_ = 0.5;
56 } else if (discount_==0.0) {
57 QL_FAIL("null discount not handled yet");
58 } else {
59 mu_ = std::log(dividendDiscount_/discount_)/variance_ - 0.5;
60 lambda_ = std::sqrt(mu_*mu_-2.0*std::log(discount_)/variance_);
61 }
63 D2_ = D1_ - 2.0*lambda_*stdDev_;
65 cum_d1_ = f(D1_);
66 cum_d2_ = f(D2_);
67 n_d1 = f.derivative(D1_);
68 n_d2 = f.derivative(D2_);
69 } else {
70 // not tested yet
71 mu_ = std::log(dividendDiscount_/discount_)/variance_ - 0.5;
72 lambda_ = std::sqrt(mu_*mu_-2.0*std::log(discount_)/variance_);
73 if (log_H_S_>0) {
74 cum_d1_= 1.0;
75 cum_d2_= 1.0;
76 } else {
77 cum_d1_= 0.0;
78 cum_d2_= 0.0;
79 }
80 n_d1 = 0.0;
81 n_d2 = 0.0;
82 }
83
84
85 switch (type) {
86 // up-and-in cash-(at-hit)-or-nothing option
87 // a.k.a. american call with cash-or-nothing payoff
88 case Option::Call:
89 if (strike_>spot_) {
90 alpha_ = 1.0-cum_d1_;// N(-d1)
91 DalphaDd1_ = - n_d1;// -n( d1)
92 beta_ = 1.0-cum_d2_;// N(-d2)
93 DbetaDd2_ = - n_d2;// -n( d2)
94 } else {
95 alpha_ = 0.5;
96 DalphaDd1_ = 0.0;
97 beta_ = 0.5;
98 DbetaDd2_ = 0.0;
99 }
100 break;
101 // down-and-in cash-(at-hit)-or-nothing option
102 // a.k.a. american put with cash-or-nothing payoff
103 case Option::Put:
104 if (strike_<spot_) {
105 alpha_ = cum_d1_;// N(d1)
106 DalphaDd1_ = n_d1;// n(d1)
107 beta_ = cum_d2_;// N(d2)
108 DbetaDd2_ = n_d2;// n(d2)
109 } else {
110 alpha_ = 0.5;
111 DalphaDd1_ = 0.0;
112 beta_ = 0.5;
113 DbetaDd2_ = 0.0;
114 }
115 break;
116 default:
117 QL_FAIL("invalid option type");
118 }
119
120
123 inTheMoney_ = (type==Option::Call && strike_<spot_) ||
124 (type==Option::Put && strike_>spot_);
125
126 if (inTheMoney_) {
127 forward_ = 1.0;
128 X_ = 1.0;
129 DXDstrike_ = 0.0;
130 } else {
131 forward_ = std::pow(strike_/spot_, muPlusLambda_);
132 X_ = std::pow(strike_/spot_, muMinusLambda_);
133// DXDstrike_ = ......;
134 }
135
136
137 // Binary Cash-Or-Nothing payoff?
138 ext::shared_ptr<CashOrNothingPayoff> coo =
139 ext::dynamic_pointer_cast<CashOrNothingPayoff>(payoff);
140 if (coo != nullptr) {
141 K_ = coo->cashPayoff();
142 DKDstrike_ = 0.0;
143 }
144
145 // Binary Asset-Or-Nothing payoff?
146 ext::shared_ptr<AssetOrNothingPayoff> aoo =
147 ext::dynamic_pointer_cast<AssetOrNothingPayoff>(payoff);
148 if (aoo != nullptr) {
149 if (inTheMoney_) {
150 K_ = spot_;
151 DKDstrike_ = 0.0;
152 } else {
153 K_ = aoo->strike();
154 DKDstrike_ = 1.0;
155 }
156 }
157 }
158
159
161 Real tempDelta = - spot_ * stdDev_;
162 Real DalphaDs = DalphaDd1_/tempDelta;
163 Real DbetaDs = DbetaDd2_/tempDelta;
164
165 Real DforwardDs, DXDs;
166 if (inTheMoney_) {
167 DforwardDs = 0.0;
168 DXDs = 0.0;
169 } else {
170 DforwardDs = -muPlusLambda_ * forward_ / spot_;
171 DXDs = -muMinusLambda_ * X_ / spot_;
172 }
173
174 return K_ * (
175 DalphaDs * forward_ + alpha_ * DforwardDs
176 + DbetaDs * X_ + beta_ * DXDs
177 );
178 }
179
180
182 Real tempDelta = - spot_ * stdDev_;
183 Real DalphaDs = DalphaDd1_/tempDelta;
184 Real DbetaDs = DbetaDd2_/tempDelta;
185 Real D2alphaDs2 = -DalphaDs/spot_*(1-D1_/stdDev_);
186 Real D2betaDs2 = -DbetaDs /spot_*(1-D2_/stdDev_);
187
188 Real DforwardDs, DXDs, D2forwardDs2, D2XDs2;
189 if (inTheMoney_) {
190 DforwardDs = 0.0;
191 DXDs = 0.0;
192 D2forwardDs2 = 0.0;
193 D2XDs2 = 0.0;
194 } else {
195 DforwardDs = -muPlusLambda_ * forward_ / spot_;
196 DXDs = -muMinusLambda_ * X_ / spot_;
197 D2forwardDs2 = muPlusLambda_ * forward_ / (spot_*spot_)*(1+muPlusLambda_);
198 D2XDs2 = muMinusLambda_ * X_ / (spot_*spot_)*(1+muMinusLambda_);
199 }
200
201 return K_ * (
202 D2alphaDs2 * forward_ + DalphaDs * DforwardDs
203 + DalphaDs * DforwardDs + alpha_ * D2forwardDs2
204 + D2betaDs2 * X_ + DbetaDs * DXDs
205 + DbetaDs * DXDs + beta_ * D2XDs2
206 );
207
208 }
209
210
212 QL_REQUIRE(maturity>=0.0,
213 "negative maturity not allowed");
214
215 // actually D.Dr / T
216 Real DalphaDr = -DalphaDd1_/(lambda_*stdDev_) * (1.0 + mu_);
217 Real DbetaDr = DbetaDd2_ /(lambda_*stdDev_) * (1.0 + mu_);
218 Real DforwardDr, DXDr;
219 if (inTheMoney_) {
220 DforwardDr = 0.0;
221 DXDr = 0.0;
222 } else {
223 DforwardDr = forward_ * (1.0+(1.0+mu_)/lambda_) * log_H_S_ / variance_;
224 DXDr = X_ * (1.0-(1.0+mu_)/lambda_) * log_H_S_ / variance_;
225 }
226
227 return maturity * K_ * (
228 DalphaDr * forward_
229 + alpha_ * DforwardDr
230 + DbetaDr * X_
231 + beta_ * DXDr
232 );
233 }
234
235}
236
Analytical formulae for american exercise with payoff at hit.
Real dividendDiscount_
AmericanPayoffAtHit(Real spot, DiscountFactor discount, DiscountFactor dividendDiscount, Real variance, const ext::shared_ptr< StrikedTypePayoff > &payoff)
Real rho(Time maturity) const
Cumulative normal distribution function.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
LinearInterpolation variance
#define QL_EPSILON
Definition: qldefines.hpp:178
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real variance_
ext::shared_ptr< QuantLib::Payoff > payoff
Definition: any.hpp:35
normal, cumulative and inverse cumulative distributions