24#ifndef quantlib_binomial_barrier_engine_hpp
25#define quantlib_binomial_barrier_engine_hpp
27#include <ql/math/distributions/normaldistribution.hpp>
28#include <ql/methods/lattices/binomialtree.hpp>
29#include <ql/methods/lattices/bsmlattice.hpp>
30#include <ql/pricingengines/barrier/discretizedbarrieroption.hpp>
31#include <ql/processes/blackscholesprocess.hpp>
32#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
33#include <ql/termstructures/yield/flatforward.hpp>
49 template <
class T,
class D>
63 Size maxTimeSteps = 0)
65 QL_REQUIRE(timeSteps>0,
66 "timeSteps must be positive, " << timeSteps <<
68 QL_REQUIRE(maxTimeSteps==0 || maxTimeSteps>=timeSteps,
69 "maxTimeSteps must be zero or "
70 "greater than or equal to timeSteps, "
71 << maxTimeSteps <<
" not allowed");
79 ext::shared_ptr<GeneralizedBlackScholesProcess>
process_;
87 template <
class T,
class D>
90 ext::shared_ptr<StrikedTypePayoff> payoff =
91 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
92 QL_REQUIRE(payoff,
"non-striked payoff given");
93 QL_REQUIRE(payoff->strike() > 0.0,
"strike must be positive");
95 Real s0 = process_->stateVariable()->value();
96 QL_REQUIRE(s0 > 0.0,
"negative or null underlying given");
97 QL_REQUIRE(!triggered(s0),
"barrier touched");
99 DayCounter rfdc = process_->riskFreeRate()->dayCounter();
100 DayCounter divdc = process_->dividendYield()->dayCounter();
101 DayCounter voldc = process_->blackVolatility()->dayCounter();
102 Calendar volcal = process_->blackVolatility()->calendar();
104 Volatility v = process_->blackVolatility()->blackVol(
105 arguments_.exercise->lastDate(), s0);
106 Date maturityDate = arguments_.exercise->lastDate();
107 Rate r = process_->riskFreeRate()->zeroRate(maturityDate,
109 Rate q = process_->dividendYield()->zeroRate(maturityDate,
111 Date referenceDate = process_->riskFreeRate()->referenceDate();
115 ext::shared_ptr<YieldTermStructure>(
118 ext::shared_ptr<YieldTermStructure>(
121 ext::shared_ptr<BlackVolTermStructure>(
126 ext::shared_ptr<StochasticProcess1D> bs(
128 process_->stateVariable(),
129 flatDividends, flatRiskFree, flatVol));
136 Size optimum_steps = timeSteps_;
137 if (std::is_base_of<CoxRossRubinstein, T>::value &&
138 maxTimeSteps_ > timeSteps_ && s0 > 0 && arguments_.barrier > 0) {
140 if (s0 > arguments_.barrier)
141 divisor = std::pow(std::log(s0 / arguments_.barrier), 2);
143 divisor = std::pow(std::log(arguments_.barrier / s0), 2);
144 if (!
close(divisor,0)) {
145 for (
Size i=1; i < timeSteps_ ; ++i) {
146 Size optimum =
Size(( i*i * v*v * maturity) / divisor);
147 if (timeSteps_ < optimum) {
148 optimum_steps = optimum;
154 if (optimum_steps > maxTimeSteps_)
155 optimum_steps = maxTimeSteps_;
158 TimeGrid grid(maturity, optimum_steps);
160 ext::shared_ptr<T> tree(
new T(bs, maturity, optimum_steps,
163 ext::shared_ptr<BlackScholesLattice<T> > lattice(
166 D option(arguments_, *process_, grid);
167 option.initialize(lattice, maturity);
175 option.rollback(grid[2]);
176 Array va2(option.values());
177 QL_ENSURE(va2.
size() == 3,
"Expect 3 nodes in grid at second step");
181 Real s2u = lattice->underlying(2, 2);
182 Real s2m = lattice->underlying(2, 1);
183 Real s2d = lattice->underlying(2, 0);
186 Real delta2u = (p2u - p2m)/(s2u-s2m);
187 Real delta2d = (p2m-p2d)/(s2m-s2d);
188 Real gamma = (delta2u - delta2d) / ((s2u-s2d)/2);
192 option.rollback(grid[1]);
193 Array va(option.values());
194 QL_ENSURE(va.
size() == 2,
"Expect 2 nodes in grid at first step");
197 Real s1u = lattice->underlying(1, 1);
198 Real s1d = lattice->underlying(1, 0);
200 Real delta = (p1u - p1d) / (s1u - s1d);
203 option.rollback(0.0);
204 Real p0 = option.presentValue();
208 results_.delta = delta;
209 results_.gamma = gamma;
213 results_.theta = (p2m - p0) / grid[2];
1-D array used in linear algebra.
Size size() const
dimension of the array
Barrier-option engine base class
Pricing engine for barrier options using binomial trees.
void calculate() const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
BinomialBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process, Size timeSteps, Size maxTimeSteps=0)
Constant Black volatility, no time-strike dependence.
Simple binomial lattice approximating the Black-Scholes model.
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Flat interest-rate curve.
Generalized Black-Scholes stochastic process.
Shared handle to an observable.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
@ NoFrequency
null frequency
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
std::size_t Size
size of a container
bool close(const Quantity &m1, const Quantity &m2, Size n)