32 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
33 : process_(
std::move(process)) {
40 const ext::shared_ptr<StrikedTypePayoff>&
payoff,
46 Real n= 2.0*std::log(dividendDiscount/riskFreeDiscount)/(
variance);
48 Real bT = std::log(dividendDiscount/riskFreeDiscount);
51 switch (
payoff->optionType()) {
53 qu = (-(
n-1.0) + std::sqrt(((
n-1.0)*(
n-1.0)) + 4.0*m))/2.0;
54 Su =
payoff->strike() / (1.0 - 1.0/qu);
61 qu = (-(
n-1.0) - std::sqrt(((
n-1.0)*(
n-1.0)) + 4.0*m))/2.0;
62 Su =
payoff->strike() / (1.0 - 1.0/qu);
65 Si = Su + (
payoff->strike() - Su) * std::exp(h);
74 Real forwardSi = Si * dividendDiscount / riskFreeDiscount;
78 Real K = (!
close(riskFreeDiscount, 1.0, 1000))
79 ?
Real(-2.0*std::log(riskFreeDiscount)
83 forwardSi, std::sqrt(
variance))*riskFreeDiscount;
84 switch (
payoff->optionType()) {
86 Q = (-(
n-1.0) + std::sqrt(((
n-1.0)*(
n-1.0)) + 4 * K)) / 2;
87 LHS = Si -
payoff->strike();
88 RHS = temp + (1 - dividendDiscount * cumNormalDist(d1)) * Si / Q;
89 bi = dividendDiscount * cumNormalDist(d1) * (1 - 1/Q) +
90 (1 - dividendDiscount *
92 while (std::fabs(LHS - RHS)/
payoff->strike() > tolerance) {
93 Si = (
payoff->strike() + RHS - bi * Si) / (1 - bi);
94 forwardSi = Si * dividendDiscount / riskFreeDiscount;
97 LHS = Si -
payoff->strike();
99 forwardSi, std::sqrt(
variance))*riskFreeDiscount;
100 RHS = temp2 + (1 - dividendDiscount * cumNormalDist(d1)) * Si / Q;
101 bi = dividendDiscount * cumNormalDist(d1) * (1 - 1 / Q)
102 + (1 - dividendDiscount *
108 Q = (-(
n-1.0) - std::sqrt(((
n-1.0)*(
n-1.0)) + 4 * K)) / 2;
109 LHS =
payoff->strike() - Si;
110 RHS = temp - (1 - dividendDiscount * cumNormalDist(-d1)) * Si / Q;
111 bi = -dividendDiscount * cumNormalDist(-d1) * (1 - 1/Q)
112 - (1 + dividendDiscount * cumNormalDist.
derivative(-d1)
114 while (std::fabs(LHS - RHS)/
payoff->strike() > tolerance) {
115 Si = (
payoff->strike() - RHS + bi * Si) / (1 + bi);
116 forwardSi = Si * dividendDiscount / riskFreeDiscount;
119 LHS =
payoff->strike() - Si;
121 forwardSi, std::sqrt(
variance))*riskFreeDiscount;
122 RHS = temp2 - (1 - dividendDiscount * cumNormalDist(-d1)) * Si / Q;
123 bi = -dividendDiscount * cumNormalDist(-d1) * (1 - 1 / Q)
124 - (1 + dividendDiscount * cumNormalDist.
derivative(-d1)
129 QL_FAIL(
"unknown option type");
138 "not an American Option");
140 ext::shared_ptr<AmericanExercise> ex =
141 ext::dynamic_pointer_cast<AmericanExercise>(arguments_.exercise);
142 QL_REQUIRE(ex,
"non-American exercise given");
144 "payoff at expiry not handled");
146 ext::shared_ptr<StrikedTypePayoff>
payoff =
147 ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
151 ex->lastDate(),
payoff->strike());
157 QL_REQUIRE(spot > 0.0,
"negative or null underlying given");
158 Real forwardPrice = spot * dividendDiscount / riskFreeDiscount;
175 arguments_.exercise->lastDate());
179 arguments_.exercise->lastDate());
183 arguments_.exercise->lastDate());
193 Real tolerance = 1e-6;
195 dividendDiscount,
variance, tolerance);
196 Real forwardSk = Sk * dividendDiscount / riskFreeDiscount;
199 Real n = 2.0*std::log(dividendDiscount/riskFreeDiscount)/
variance;
200 Real K = (!
close(riskFreeDiscount, 1.0, 1000))
201 ?
Real(-2.0*std::log(riskFreeDiscount)
202 / (
variance*(1.0-riskFreeDiscount)))
205 switch (
payoff->optionType()) {
207 Q = (-(
n-1.0) + std::sqrt(((
n-1.0)*(
n-1.0))+4.0*K))/2.0;
208 a = (Sk/Q) * (1.0 - dividendDiscount * cumNormalDist(d1));
211 a * std::pow((spot/Sk), Q);
217 Q = (-(
n-1.0) - std::sqrt(((
n-1.0)*(
n-1.0))+4.0*K))/2.0;
219 (1.0 - dividendDiscount * cumNormalDist(-d1));
222 a * std::pow((spot/Sk), Q);
228 QL_FAIL(
"unknown option type");
Barone-Adesi and Whaley approximation engine.
Black-formula calculator class.
const Instrument::results * results_
BaroneAdesiWhaleyApproximationEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >)
static Real criticalPrice(const ext::shared_ptr< StrikedTypePayoff > &payoff, DiscountFactor riskFreeDiscount, DiscountFactor dividendDiscount, Real variance, Real tolerance=1e-6)
void calculate() const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Black 1976 calculator class.
Real dividendRho(Time maturity) const
virtual Real delta(Real spot) const
Real vega(Time maturity) const
Real itmCashProbability() const
Real strikeSensitivity() const
virtual Real gamma(Real spot) const
virtual Real elasticity(Real spot) const
virtual Real thetaPerDay(Real spot, Time maturity) const
Real deltaForward() const
virtual Real theta(Real spot, Time maturity) const
Real rho(Time maturity) const
Cumulative normal distribution function.
Real derivative(Real x) const
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.
floating-point comparisons
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Option exercise classes and payoff function.
LinearInterpolation variance
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
ext::shared_ptr< QuantLib::Payoff > payoff
bool close(const Quantity &m1, const Quantity &m2, Size n)
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
normal, cumulative and inverse cumulative distributions