QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
extendedbinomialtree.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) 2001, 2002, 2003 Sadruddin Rejeb
5 Copyright (C) 2003 Ferdinando Ametrano
6 Copyright (C) 2005 StatPro Italia srl
7 Copyright (C) 2008 John Maiden
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
25
26namespace QuantLib {
27
29 const ext::shared_ptr<StochasticProcess1D>& process,
30 Time end, Size steps, Real)
32 process, end, steps) {
33 // drift removed
34 up_ = process->stdDeviation(0.0, x0_, dt_);
35 }
36
38 return treeProcess_->stdDeviation(stepTime, x0_, dt_);
39 }
40
41
42
44 const ext::shared_ptr<StochasticProcess1D>& process,
45 Time end, Size steps, Real)
47 process, end, steps) {
48
49 dx_ = process->stdDeviation(0.0, x0_, dt_);
50 pu_ = 0.5 + 0.5*this->driftStep(0.0)/dx_;
51 pd_ = 1.0 - pu_;
52
53 QL_REQUIRE(pu_<=1.0, "negative probability");
54 QL_REQUIRE(pu_>=0.0, "negative probability");
55 }
56
58 return this->treeProcess_->stdDeviation(stepTime, x0_, dt_);
59 }
60
62 return 0.5 + 0.5*this->driftStep(stepTime)/dxStep(stepTime);
63 }
64
65
67 const ext::shared_ptr<StochasticProcess1D>& process,
68 Time end, Size steps, Real)
70 process, end, steps) {
71
72 up_ = - 0.5 * this->driftStep(0.0) + 0.5 *
73 std::sqrt(4.0*process->variance(0.0, x0_, dt_)-
74 3.0*this->driftStep(0.0)*this->driftStep(0.0));
75 }
76
78 return (- 0.5 * this->driftStep(stepTime) + 0.5 *
79 std::sqrt(4.0*this->treeProcess_->variance(stepTime, x0_, dt_)-
80 3.0*this->driftStep(stepTime)*this->driftStep(stepTime)));
81 }
82
83
84
85
87 const ext::shared_ptr<StochasticProcess1D>& process,
88 Time end, Size steps, Real)
90
91 dx_ = std::sqrt(process->variance(0.0, x0_, dt_)+
92 this->driftStep(0.0)*this->driftStep(0.0));
93 pu_ = 0.5 + 0.5*this->driftStep(0.0) / ExtendedTrigeorgis::dxStep(0.0);
94 pd_ = 1.0 - pu_;
95
96 QL_REQUIRE(pu_<=1.0, "negative probability");
97 QL_REQUIRE(pu_>=0.0, "negative probability");
98 }
99
101 return std::sqrt(this->treeProcess_->variance(stepTime, x0_, dt_)+
102 this->driftStep(stepTime)*this->driftStep(stepTime));
103 }
104
106 return 0.5 + 0.5*this->driftStep(stepTime)/dxStep(stepTime);
107 }
108
109
111 const ext::shared_ptr<StochasticProcess1D>& process,
112 Time end, Size steps, Real)
113 : ExtendedBinomialTree<ExtendedTian>(process, end, steps) {
114
115 Real q = std::exp(process->variance(0.0, x0_, dt_));
116
117 Real r = std::exp(this->driftStep(0.0))*std::sqrt(q);
118
119 up_ = 0.5 * r * q * (q + 1 + std::sqrt(q * q + 2 * q - 3));
120 down_ = 0.5 * r * q * (q + 1 - std::sqrt(q * q + 2 * q - 3));
121
122 pu_ = (r - down_) / (up_ - down_);
123 pd_ = 1.0 - pu_;
124
125 // doesn't work
126 // treeCentering_ = (up_+down_)/2.0;
127 // up_ = up_-treeCentering_;
128
129 QL_REQUIRE(pu_<=1.0, "negative probability");
130 QL_REQUIRE(pu_>=0.0, "negative probability");
131 }
132
134 Time stepTime = i*this->dt_;
135 Real q = std::exp(this->treeProcess_->variance(stepTime, x0_, dt_));
136 Real r = std::exp(this->driftStep(stepTime))*std::sqrt(q);
137
138 Real up = 0.5 * r * q * (q + 1 + std::sqrt(q * q + 2 * q - 3));
139 Real down = 0.5 * r * q * (q + 1 - std::sqrt(q * q + 2 * q - 3));
140
141 return x0_ * std::pow(down, Real(BigInteger(i)-BigInteger(index)))
142 * std::pow(up, Real(index));
143 }
144
146 Time stepTime = i*this->dt_;
147 Real q = std::exp(this->treeProcess_->variance(stepTime, x0_, dt_));
148 Real r = std::exp(this->driftStep(stepTime))*std::sqrt(q);
149
150 Real up = 0.5 * r * q * (q + 1 + std::sqrt(q * q + 2 * q - 3));
151 Real down = 0.5 * r * q * (q + 1 - std::sqrt(q * q + 2 * q - 3));
152
153 Real pu = (r - down) / (up - down);
154 Real pd = 1.0 - pu;
155
156 return (branch == 1 ? pu : pd);
157 }
158
159
160 ExtendedLeisenReimer::ExtendedLeisenReimer(const ext::shared_ptr<StochasticProcess1D>& process,
161 Time end,
162 Size steps,
163 Real strike)
165 process, end, ((steps % 2) != 0U ? steps : steps + 1)),
166 end_(end), oddSteps_((steps % 2) != 0U ? steps : steps + 1), strike_(strike) {
167
168 QL_REQUIRE(strike>0.0, "strike " << strike << "must be positive");
169 Real variance = process->variance(0.0, x0_, end);
170
171 Real ermqdt = std::exp(this->driftStep(0.0) + 0.5*variance/oddSteps_);
172 Real d2 = (std::log(x0_/strike) + this->driftStep(0.0)*oddSteps_ ) /
173 std::sqrt(variance);
174
176 pd_ = 1.0 - pu_;
177 Real pdash = PeizerPrattMethod2Inversion(d2+std::sqrt(variance),
178 oddSteps_);
179 up_ = ermqdt * pdash / pu_;
180 down_ = (ermqdt - pu_ * up_) / (1.0 - pu_);
181 }
182
184 Time stepTime = i*this->dt_;
185 Real variance = this->treeProcess_->variance(stepTime, x0_, end_);
186 Real ermqdt = std::exp(this->driftStep(stepTime) + 0.5*variance/oddSteps_);
187 Real d2 = (std::log(x0_/strike_) + this->driftStep(stepTime)*oddSteps_ ) /
188 std::sqrt(variance);
189
191 Real pdash = PeizerPrattMethod2Inversion(d2+std::sqrt(variance),
192 oddSteps_);
193 Real up = ermqdt * pdash / pu;
194 Real down = (ermqdt - pu * up) / (1.0 - pu);
195
196 return x0_ * std::pow(down, Real(BigInteger(i)-BigInteger(index)))
197 * std::pow(up, Real(index));
198 }
199
201 Time stepTime = i*this->dt_;
202 Real variance = this->treeProcess_->variance(stepTime, x0_, end_);
203 Real d2 = (std::log(x0_/strike_) + this->driftStep(stepTime)*oddSteps_ ) /
204 std::sqrt(variance);
205
207 Real pd = 1.0 - pu;
208
209 return (branch == 1 ? pu : pd);
210 }
211
212
213
215 Real alpha = dj/(std::sqrt(8.0));
216 Real alpha2 = alpha*alpha;
217 Real alpha3 = alpha*alpha2;
218 Real alpha5 = alpha3*alpha2;
219 Real alpha7 = alpha5*alpha2;
220 Real beta = -0.375*alpha-alpha3;
221 Real gamma = (5.0/6.0)*alpha5 + (13.0/12.0)*alpha3
222 +(25.0/128.0)*alpha;
223 Real delta = -0.1025 *alpha- 0.9285 *alpha3
224 -1.43 *alpha5 -0.5 *alpha7;
225 Real p =0.5;
226 Real rootk= std::sqrt(k);
227 p+= alpha/rootk;
228 p+= beta /(k*rootk);
229 p+= gamma/(k*k*rootk);
230 // delete next line to get results for j three tree
231 p+= delta/(k*k*k*rootk);
232 return p;
233 }
234
235 ExtendedJoshi4::ExtendedJoshi4(const ext::shared_ptr<StochasticProcess1D>& process,
236 Time end,
237 Size steps,
238 Real strike)
239 : ExtendedBinomialTree<ExtendedJoshi4>(process, end, ((steps % 2) != 0U ? steps : steps + 1)),
240 end_(end), oddSteps_((steps % 2) != 0U ? steps : steps + 1), strike_(strike) {
241
242 QL_REQUIRE(strike>0.0, "strike " << strike << "must be positive");
243 Real variance = process->variance(0.0, x0_, end);
244
245 Real ermqdt = std::exp(this->driftStep(0.0) + 0.5*variance/oddSteps_);
246 Real d2 = (std::log(x0_/strike) + this->driftStep(0.0)*oddSteps_ ) /
247 std::sqrt(variance);
248
249 pu_ = computeUpProb((oddSteps_-1.0)/2.0,d2 );
250 pd_ = 1.0 - pu_;
251 Real pdash = computeUpProb((oddSteps_-1.0)/2.0,d2+std::sqrt(variance));
252 up_ = ermqdt * pdash / pu_;
253 down_ = (ermqdt - pu_ * up_) / (1.0 - pu_);
254 }
255
257 Time stepTime = i*this->dt_;
258 Real variance = this->treeProcess_->variance(stepTime, x0_, end_);
259 Real ermqdt = std::exp(this->driftStep(stepTime) + 0.5*variance/oddSteps_);
260 Real d2 = (std::log(x0_/strike_) + this->driftStep(stepTime)*oddSteps_ ) /
261 std::sqrt(variance);
262
263 Real pu = computeUpProb((oddSteps_-1.0)/2.0,d2 );
264 Real pdash = computeUpProb((oddSteps_-1.0)/2.0,d2+std::sqrt(variance));
265 Real up = ermqdt * pdash / pu;
266 Real down = (ermqdt - pu * up) / (1.0 - pu);
267
268 return x0_ * std::pow(down, Real(BigInteger(i)-BigInteger(index)))
269 * std::pow(up, Real(index));
270 }
271
273 Time stepTime = i*this->dt_;
274 Real variance = this->treeProcess_->variance(stepTime, x0_, end_);
275 Real d2 = (std::log(x0_/strike_) + this->driftStep(stepTime)*oddSteps_ ) /
276 std::sqrt(variance);
277
278 Real pu = computeUpProb((oddSteps_-1.0)/2.0,d2 );
279 Real pd = 1.0 - pu;
280
281 return (branch == 1 ? pu : pd);
282 }
283
284}
Binomial distribution.
Additive equal probabilities binomial tree.
Real upStep(Time stepTime) const override
ExtendedAdditiveEQPBinomialTree(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
Real driftStep(Time driftTime) const
ext::shared_ptr< StochasticProcess1D > treeProcess_
Cox-Ross-Rubinstein (multiplicative) equal jumps binomial tree.
Real probUp(Time stepTime) const override
Real dxStep(Time stepTime) const override
ExtendedCoxRossRubinstein(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
Base class for equal jumps binomial tree.
Base class for equal probabilities binomial tree.
Jarrow-Rudd (multiplicative) equal probabilities binomial tree.
Real upStep(Time stepTime) const override
ExtendedJarrowRudd(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
ExtendedJoshi4(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
Real underlying(Size i, Size index) const
Real probability(Size, Size, Size branch) const
Real computeUpProb(Real k, Real dj) const
Leisen & Reimer tree: multiplicative approach.
Real underlying(Size i, Size index) const
Real probability(Size, Size, Size branch) const
ExtendedLeisenReimer(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
Tian tree: third moment matching, multiplicative approach
Real underlying(Size i, Size index) const
ExtendedTian(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
Real probability(Size, Size, Size branch) const
Trigeorgis (additive equal jumps) binomial tree
Real probUp(Time stepTime) const override
Real dxStep(Time stepTime) const override
ExtendedTrigeorgis(const ext::shared_ptr< StochasticProcess1D > &, Time end, Size steps, Real strike)
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Time-dependent binomial tree class.
LinearInterpolation variance
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
QL_BIG_INTEGER BigInteger
large integer number
Definition: types.hpp:39
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Real PeizerPrattMethod2Inversion(Real z, BigNatural n)
ext::shared_ptr< YieldTermStructure > q
ext::shared_ptr< YieldTermStructure > r
Real beta
Definition: sabr.cpp:200
Real alpha
Definition: sabr.cpp:200