QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
suowangdoublebarrierengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2013 Yue Tian
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
20#include <ql/exercise.hpp>
21#include <ql/experimental/barrieroption/suowangdoublebarrierengine.hpp>
22#include <ql/instruments/europeanoption.hpp>
23#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
24#include <utility>
25
26namespace QuantLib {
27
29 ext::shared_ptr<GeneralizedBlackScholesProcess> process, int series)
30 : process_(std::move(process)), series_(series) {
32 }
33
35
36 ext::shared_ptr<PlainVanillaPayoff> payoff =
37 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
38 QL_REQUIRE(payoff, "non-plain payoff given");
39 QL_REQUIRE(payoff->strike()>0.0,
40 "strike must be positive");
41
42 Real K = payoff->strike();
43 Real S = process_->x0();
44 QL_REQUIRE(S > 0.0, "negative or null underlying given");
45 QL_REQUIRE(!triggered(S), "barrier touched");
46
48 QL_REQUIRE(barrierType == DoubleBarrier::KnockOut ||
49 barrierType == DoubleBarrier::KnockIn,
50 "only KnockIn and KnockOut options supported");
51
54 Real K_up = std::min(H, K);
55 Real K_down = std::max(L, K);
56 Time T = residualTime();
57 Real rd = riskFreeRate();
59 Real rf = dividendYield();
61 Real vol = volatility();
62 Real mu = rd - rf - vol*vol/2.0;
63 Real sgn = mu > 0 ? 1.0 :(mu < 0 ? -1.0: 0.0);
64 //rebate
67
68 //european option
69 EuropeanOption europeanOption(payoff, arguments_.exercise);
70 ext::shared_ptr<PricingEngine> analyticEuropeanEngine =
71 ext::make_shared<AnalyticEuropeanEngine>(process_);
72 europeanOption.setPricingEngine(analyticEuropeanEngine);
73 Real european = europeanOption.NPV();
74
75 Real barrierOut = 0;
76 Real rebateIn = 0;
77 for(int n = -series_; n < series_; n++){
78 Real d1 = D(S/H*std::pow(L/H, 2.0*n), vol*vol+mu, vol, T);
79 Real d2 = d1 - vol*std::sqrt(T);
80 Real g1 = D(H/S*std::pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T);
81 Real g2 = g1 - vol*std::sqrt(T);
82 Real h1 = D(S/H*std::pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T);
83 Real h2 = h1 - vol*std::sqrt(T);
84 Real k1 = D(L/S*std::pow(L/H, 2.0*n - 1.0), vol*vol+mu, vol, T);
85 Real k2 = k1 - vol*std::sqrt(T);
86 Real d1_down = D(S/K_down*std::pow(L/H, 2.0*n), vol*vol+mu, vol, T);
87 Real d2_down = d1_down - vol*std::sqrt(T);
88 Real d1_up = D(S/K_up*std::pow(L/H, 2.0*n), vol*vol+mu, vol, T);
89 Real d2_up = d1_up - vol*std::sqrt(T);
90 Real k1_down = D((H*H)/(K_down*S)*std::pow(L/H, 2.0*n), vol*vol+mu, vol, T);
91 Real k2_down = k1_down - vol*std::sqrt(T);
92 Real k1_up = D((H*H)/(K_up*S)*std::pow(L/H, 2.0*n), vol*vol+mu, vol, T);
93 Real k2_up = k1_up - vol*std::sqrt(T);
94
95 if( payoff->optionType() == Option::Call) {
96 barrierOut += std::pow(L/H, 2.0 * n * mu/(vol*vol))*
97 (df*S*std::pow(L/H, 2.0*n)*(f_(d1_down)-f_(d1))
98 -dd*K*(f_(d2_down)-f_(d2))
99 -df*std::pow(L/H, 2.0*n)*H*H/S*std::pow(H/S, 2.0*mu/(vol*vol))*(f_(k1_down)-f_(k1))
100 +dd*K*std::pow(H/S,2.0*mu/(vol*vol))*(f_(k2_down)-f_(k2)));
101 }
102 else if(payoff->optionType() == Option::Put){
103 barrierOut += std::pow(L/H, 2.0 * n * mu/(vol*vol))*
104 (dd*K*(f_(h2)-f_(d2_up))
105 -df*S*std::pow(L/H, 2.0*n)*(f_(h1)-f_(d1_up))
106 -dd*K*std::pow(H/S,2.0*mu/(vol*vol))*(f_(g2)-f_(k2_up))
107 +df*std::pow(L/H, 2.0*n)*H*H/S*std::pow(H/S, 2.0*mu/(vol*vol))*(f_(g1)-f_(k1_up)));
108 }
109 else {
110 QL_FAIL("option type not recognized");
111 }
112
113 Real v1 = D(H/S*std::pow(H/L, 2.0*n), -mu, vol, T);
114 Real v2 = D(H/S*std::pow(H/L, 2.0*n), mu, vol, T);
115 Real v3 = D(S/L*std::pow(H/L, 2.0*n), -mu, vol, T);
116 Real v4 = D(S/L*std::pow(H/L, 2.0*n), mu, vol, T);
117 rebateIn += dd * R_H * sgn * (std::pow(L/H, 2.0*n*mu/(vol*vol)) * f_(sgn * v1) - std::pow(H/S, 2.0*mu/(vol*vol)) * f_(-sgn * v2))
118 + dd * R_L * sgn * (std::pow(L/S, 2.0*mu/(vol*vol)) * f_(-sgn * v3) - std::pow(H/L, 2.0*n*mu/(vol*vol)) * f_(sgn * v4));
119 }
120
121 //rebate paid at maturity
122 if(barrierType == DoubleBarrier::KnockOut)
123 results_.value = barrierOut ;
124 else
125 results_.value = european - barrierOut;
126 results_.additionalResults["vanilla"] = european;
127 results_.additionalResults["barrierOut"] = barrierOut;
128 results_.additionalResults["barrierIn"] = Real(european - barrierOut);
129 results_.additionalResults["rebateIn"] = rebateIn;
130 }
131
132
134 ext::shared_ptr<PlainVanillaPayoff> payoff =
135 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
136 QL_REQUIRE(payoff, "non-plain payoff given");
137 return payoff->strike();
138 }
139
141 return process_->time(arguments_.exercise->lastDate());
142 }
143
145 return process_->blackVolatility()->blackVol(residualTime(), strike());
146 }
147
149 return process_->riskFreeRate()->zeroRate(residualTime(), Continuous,
151 }
152
154 return process_->riskFreeRate()->discount(residualTime());
155 }
156
158 return process_->dividendYield()->zeroRate(residualTime(),
160 }
161
163 return process_->dividendYield()->discount(residualTime());
164 }
165
167 return (std::log(X) + lambda * T)/(sigma * std::sqrt(T));
168 }
169
170}
171
European option on a single asset.
std::map< std::string, ext::any > additionalResults
Definition: instrument.hpp:123
Real NPV() const
returns the net present value of the instrument.
Definition: instrument.hpp:167
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
Definition: instrument.cpp:35
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
SuoWangDoubleBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process, int series=5)
Real D(Real X, Real lambda, Real sigma, Real T) const
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
@ NoFrequency
null frequency
Definition: frequency.hpp:37
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 Volatility
volatility
Definition: types.hpp:78
Real Rate
interest rates
Definition: types.hpp:70
Definition: any.hpp:35
STL namespace.