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
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22#include <ql/methods/lattices/binomialtree.hpp>
23#include <ql/math/distributions/binomialdistribution.hpp>
24#include <ql/stochasticprocess.hpp>
25
26namespace QuantLib {
27
28 JarrowRudd::JarrowRudd(
29 const ext::shared_ptr<StochasticProcess1D>& process,
30 Time end, Size steps, Real)
31 : EqualProbabilitiesBinomialTree<JarrowRudd>(process, end, steps) {
32 // drift removed
33 up_ = process->stdDeviation(t0: 0.0, x0: x0_, dt: dt_);
34 }
35
36
37 CoxRossRubinstein::CoxRossRubinstein(
38 const ext::shared_ptr<StochasticProcess1D>& process,
39 Time end, Size steps, Real)
40 : EqualJumpsBinomialTree<CoxRossRubinstein>(process, end, steps) {
41
42 dx_ = process->stdDeviation(t0: 0.0, x0: x0_, dt: dt_);
43 pu_ = 0.5 + 0.5*driftPerStep_/dx_;;
44 pd_ = 1.0 - pu_;
45
46 QL_REQUIRE(pu_<=1.0, "negative probability");
47 QL_REQUIRE(pu_>=0.0, "negative probability");
48 }
49
50
51 AdditiveEQPBinomialTree::AdditiveEQPBinomialTree(
52 const ext::shared_ptr<StochasticProcess1D>& process,
53 Time end, Size steps, Real)
54 : EqualProbabilitiesBinomialTree<AdditiveEQPBinomialTree>(process,
55 end, steps) {
56 up_ = - 0.5 * driftPerStep_ + 0.5 *
57 std::sqrt(x: 4.0*process->variance(t0: 0.0, x0: x0_, dt: dt_)-
58 3.0*driftPerStep_*driftPerStep_);
59 }
60
61
62 Trigeorgis::Trigeorgis(
63 const ext::shared_ptr<StochasticProcess1D>& process,
64 Time end, Size steps, Real)
65 : EqualJumpsBinomialTree<Trigeorgis>(process, end, steps) {
66
67 dx_ = std::sqrt(x: process->variance(t0: 0.0, x0: x0_, dt: dt_)+
68 driftPerStep_*driftPerStep_);
69 pu_ = 0.5 + 0.5*driftPerStep_/dx_;;
70 pd_ = 1.0 - pu_;
71
72 QL_REQUIRE(pu_<=1.0, "negative probability");
73 QL_REQUIRE(pu_>=0.0, "negative probability");
74 }
75
76
77 Tian::Tian(const ext::shared_ptr<StochasticProcess1D>& process,
78 Time end, Size steps, Real)
79 : BinomialTree<Tian>(process, end, steps) {
80
81 Real q = std::exp(x: process->variance(t0: 0.0, x0: x0_, dt: dt_));
82 Real r = std::exp(x: driftPerStep_)*std::sqrt(x: q);
83
84 up_ = 0.5 * r * q * (q + 1 + std::sqrt(x: q * q + 2 * q - 3));
85 down_ = 0.5 * r * q * (q + 1 - std::sqrt(x: q * q + 2 * q - 3));
86
87 pu_ = (r - down_) / (up_ - down_);
88 pd_ = 1.0 - pu_;
89
90 // doesn't work
91 // treeCentering_ = (up_+down_)/2.0;
92 // up_ = up_-treeCentering_;
93
94 QL_REQUIRE(pu_<=1.0, "negative probability");
95 QL_REQUIRE(pu_>=0.0, "negative probability");
96 }
97
98
99 LeisenReimer::LeisenReimer(const ext::shared_ptr<StochasticProcess1D>& process,
100 Time end,
101 Size steps,
102 Real strike)
103 : BinomialTree<LeisenReimer>(process, end, ((steps % 2) != 0U ? steps : (steps + 1))) {
104
105 QL_REQUIRE(strike>0.0, "strike must be positive");
106 Size oddSteps = ((steps % 2) != 0U ? steps : (steps + 1));
107 Real variance = process->variance(t0: 0.0, x0: x0_, dt: end);
108 Real ermqdt = std::exp(x: driftPerStep_ + 0.5*variance/oddSteps);
109 Real d2 = (std::log(x: x0_/strike) + driftPerStep_*oddSteps ) /
110 std::sqrt(x: variance);
111 pu_ = PeizerPrattMethod2Inversion(z: d2, n: oddSteps);
112 pd_ = 1.0 - pu_;
113 Real pdash = PeizerPrattMethod2Inversion(z: d2+std::sqrt(x: variance),
114 n: oddSteps);
115 up_ = ermqdt * pdash / pu_;
116 down_ = (ermqdt - pu_ * up_) / (1.0 - pu_);
117 }
118
119 Real Joshi4::computeUpProb(Real k, Real dj) const {
120 Real alpha = dj/(std::sqrt(x: 8.0));
121 Real alpha2 = alpha*alpha;
122 Real alpha3 = alpha*alpha2;
123 Real alpha5 = alpha3*alpha2;
124 Real alpha7 = alpha5*alpha2;
125 Real beta = -0.375*alpha-alpha3;
126 Real gamma = (5.0/6.0)*alpha5 + (13.0/12.0)*alpha3
127 +(25.0/128.0)*alpha;
128 Real delta = -0.1025 *alpha- 0.9285 *alpha3
129 -1.43 *alpha5 -0.5 *alpha7;
130 Real p =0.5;
131 Real rootk = std::sqrt(x: k);
132 p+= alpha/rootk;
133 p+= beta /(k*rootk);
134 p+= gamma/(k*k*rootk);
135 // delete next line to get results for j three tree
136 p+= delta/(k*k*k*rootk);
137 return p;
138 }
139
140 Joshi4::Joshi4(const ext::shared_ptr<StochasticProcess1D>& process,
141 Time end,
142 Size steps,
143 Real strike)
144 : BinomialTree<Joshi4>(process, end, (steps % 2) != 0U ? steps : (steps + 1)) {
145
146 QL_REQUIRE(strike>0.0, "strike must be positive");
147 Size oddSteps = (steps % 2) != 0U ? steps : (steps + 1);
148 Real variance = process->variance(t0: 0.0, x0: x0_, dt: end);
149 Real ermqdt = std::exp(x: driftPerStep_ + 0.5*variance/oddSteps);
150 Real d2 = (std::log(x: x0_/strike) + driftPerStep_*oddSteps ) /
151 std::sqrt(x: variance);
152 pu_ = computeUpProb(k: (oddSteps-1.0)/2.0,dj: d2 );
153 pd_ = 1.0 - pu_;
154 Real pdash = computeUpProb(k: (oddSteps-1.0)/2.0,dj: d2+std::sqrt(x: variance));
155 up_ = ermqdt * pdash / pu_;
156 down_ = (ermqdt - pu_ * up_) / (1.0 - pu_);
157 }
158}
159

source code of quantlib/ql/methods/lattices/binomialtree.cpp