29 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
30 : process_(
std::move(process)) {
35 const ext::shared_ptr<PlainVanillaPayoff>&
payoff,
36 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process)
const {
46 switch (barrierType) {
48 switch (barrierRange) {
50 return CA(1, barrier, strike,
r,
q);
52 return CoB1(barrier, strike,
r,
q);
56 QL_FAIL(
"invalid barrier range");
61 switch (barrierRange) {
63 return CIA(1, barrier, strike,
r,
q);
66 QL_FAIL(
"Down-and-in partial-time end barrier is not implemented");
68 QL_FAIL(
"invalid barrier range");
73 switch (barrierRange) {
75 return CA(-1, barrier, strike,
r,
q);
77 return CoB1(barrier, strike,
r,
q);
81 QL_FAIL(
"invalid barrier range");
86 switch (barrierRange) {
88 return CIA(-1, barrier, strike,
r,
q);
91 QL_FAIL(
"Up-and-in partial-time end barrier is not implemented");
93 QL_FAIL(
"invalid barrier range");
97 QL_FAIL(
"unknown barrier type");
102 ext::shared_ptr<PlainVanillaPayoff>
payoff =
106 "strike must be positive");
109 QL_REQUIRE(spot > 0.0,
"negative or null underlying given");
121 Real spotSq = spot * spot;
123 ext::shared_ptr<PlainVanillaPayoff> callPayoff =
124 ext::make_shared<PlainVanillaPayoff>(
Option::Call, callStrike);
127 tmp_arguments_.payoff = callPayoff;
128 auto callProcess = ext::make_shared<GeneralizedBlackScholesProcess>(
148 Real g1_ =
g1(barrier, strike,
b);
149 Real g2_ =
g2(barrier, strike,
b);
150 Real g3_ =
g3(barrier, strike,
b);
151 Real g4_ =
g4(barrier, strike,
b);
152 Real e1_ =
e1(barrier, strike,
b);
153 Real e2_ =
e2(barrier, strike,
b);
154 Real e3_ =
e3(barrier, strike,
b);
155 Real e4_ =
e4(barrier, strike,
b);
157 Real HSMu =
HS(
S, barrier, 2 * mu_);
158 Real HSMu1 =
HS(
S, barrier, 2 * (mu_ + 1));
159 Real X1 = strike * std::exp(-
r *
T);
161 if (strike < barrier){
162 switch (barrierType) {
164 result =
S * std::exp((
b -
r) *
T);
165 result *= (
M(g1_, e1_, rho_) - HSMu1 *
M(g3_, -e3_, -rho_));
166 result -= X1 * (
M(g2_, e2_, rho_)-HSMu*
M(g4_, -e4_, -rho_));
170 result =
S * std::exp((
b -
r) *
T);
171 result *= (
M(-g1_, -e1_, rho_) - HSMu1 *
M(-g3_, e3_, -rho_));
172 result -= X1 * (
M(-g2_, -e2_, rho_) - HSMu *
M(-g4_, e4_, -rho_));
173 result -=
S * std::exp((
b -
r) *
T) *
174 (
M(-
d1(strike,
b), -e1_, rho_) - HSMu1 *
175 M(e3_, -
f1(barrier, strike,
b),-rho_));
176 result += X1 * (
M(-
d2(strike,
b), -e2_, rho_) - HSMu *
177 M(e4_, -
f2(barrier, strike,
b), -rho_));
181 QL_FAIL(
"invalid barrier type");
184 QL_FAIL(
"case of strike>barrier is not implemented for OutEnd B2 type");
194 Real g1_ =
g1(barrier, strike,
b);
195 Real g2_ =
g2(barrier, strike,
b);
196 Real g3_ =
g3(barrier, strike,
b);
197 Real g4_ =
g4(barrier, strike,
b);
198 Real e1_ =
e1(barrier, strike,
b);
199 Real e2_ =
e2(barrier, strike,
b);
200 Real e3_ =
e3(barrier, strike,
b);
201 Real e4_ =
e4(barrier, strike,
b);
203 Real HSMu =
HS(
S, barrier, 2 * mu_);
204 Real HSMu1 =
HS(
S, barrier, 2 * (mu_ + 1));
205 Real X1 = strike * std::exp(-
r *
T);
207 if (strike > barrier) {
208 result =
S * std::exp((
b -
r) *
T);
209 result *= (
M(
d1(strike,
b), e1_, rho_) - HSMu1 *
M(
f1(barrier, strike,
b), -e3_, -rho_));
210 result -= X1 * (
M(
d2(strike,
b), e2_, rho_) - HSMu *
M(
f2(barrier, strike,
b), -e4_, -rho_));
213 Real S1 =
S * std::exp((
b -
r) *
T);
215 result *= (
M(-g1_, -e1_, rho_) - HSMu1 *
M(-g3_,e3_,-rho_));
216 result -= X1 * (
M(-g2_, -e2_, rho_) - HSMu *
M(-g4_, e4_, -rho_));
217 result -= S1 * (
M(-
d1(strike,
b), -e1_, rho_) - HSMu1 *
M(-
f1(barrier, strike,
b), e3_, -rho_));
218 result += X1 * (
M(-
d2(strike,
b), -e2_, rho_) - HSMu *
M(-
f2(barrier, strike,
b), e4_, -rho_));
219 result += S1 * (
M(g1_, e1_, rho_) - HSMu1 *
M(g3_, -e3_, -rho_));
220 result -= X1 * (
M(g2_, e2_, rho_) - HSMu *
M(g4_, -e4_, -rho_));
228 ext::shared_ptr<EuropeanExercise> exercise =
231 ext::shared_ptr<PlainVanillaPayoff>
payoff =
237 ext::make_shared<AnalyticEuropeanEngine>(
process_));
239 return europeanOption.
NPV() -
CA(eta, barrier, strike,
r,
q);
249 Real e1_ =
e1(barrier, strike,
b);
250 Real e2_ =
e2(barrier, strike,
b);
251 Real e3_ =
e3(barrier, strike,
b);
252 Real e4_ =
e4(barrier, strike,
b);
253 Real HSMu =
HS(
S, barrier,2 * mu_);
254 Real HSMu1 =
HS(
S, barrier, 2 * (mu_ + 1));
257 result =
S * std::exp((
b -
r) *
T);
258 result *= (
M(
d1(strike,
b), eta * e1_, eta * rho_)-HSMu1 *
259 M(
f1(barrier, strike,
b), eta * e3_, eta * rho_));
260 result -= (strike * std::exp(-
r *
T) *
261 (
M(
d2(strike,
b),eta * e2_, eta * rho_) - HSMu *
262 M(
f2(barrier, strike,
b), eta * e4_, eta * rho_)));
279 return process_->blackVolatility()->blackVol(
t, strike);
286 return (std::log(
S / strike) + 2 * std::log(barrier /
S) +
297 return CmlNormDist(a,
b);
306 return (
b - (vol * vol) / 2) / (vol * vol);
312 return (std::log(
underlying() / strike) + (
b + vol * vol / 2) * T2) / (std::sqrt(T2) * vol);
318 return d1(strike,
b) - vol * std::sqrt(T2);
324 return (std::log(
underlying() / barrier) + (
b + vol * vol / 2) * T1) / (std::sqrt(T1) * vol);
330 return e1(barrier, strike,
b) - vol * std::sqrt(T1);
336 return e1(barrier, strike,
b) + (2 * std::log(barrier /
underlying()) / (vol * std::sqrt(T1)));
347 return (std::log(
underlying() / barrier) + (
b + vol * vol / 2) * T2) / (std::sqrt(T2) * vol);
353 return g1(barrier, strike,
b) - vol * std::sqrt(T2);
359 return g1(barrier, strike,
b) + (2 * std::log(barrier /
underlying()) /(vol * std::sqrt(T2)));
365 return g3(barrier, strike,
b) - vol * std::sqrt(T2);
369 return std::pow((H /
S), power);
Analytic European engine.
bivariate cumulative normal distribution
Real g1(Real barrier, Real strike, Rate b) const
Real e4(Real barrier, Real strike, Rate b) const
Volatility volatility(Time t, Real strike) const
Time residualTime() const
Real g4(Real barrier, Real strike, Rate b) const
Real e3(Real barrier, Real strike, Rate b) const
Real CA(Integer n, Real barrier, Real strike, Rate r, Rate q) const
Real CIA(Integer n, Real barrier, Real strike, Rate r, Rate q) const
AnalyticPartialTimeBarrierOptionEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
Real e2(Real barrier, Real strike, Rate b) const
void calculate() const override
Real HS(Real S, Real H, Real power) const
Real f1(Real barrier, Real strike, Rate b) const
Real CoB2(Barrier::Type barrierType, Real barrier, Real strike, Rate r, Rate q) const
Rate mu(Real strike, Rate b) const
Real d1(Real strike, Rate b) const
Real M(Real a, Real b, Real rho) const
Time coverEventTime() const
Real f2(Real barrier, Real strike, Rate b) const
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Real g3(Real barrier, Real strike, Rate b) const
Real g2(Real barrier, Real strike, Rate b) const
Real CoB1(Real barrier, Real strike, Rate r, Rate q) const
Real e1(Real barrier, Real strike, Rate b) const
Real d2(Real strike, Rate b) const
Cumulative bivariate normal distribution function.
PartialTimeBarrierOption::results results_
PartialTimeBarrierOption::arguments arguments_
Real NPV() const
returns the net present value of the instrument.
void setPricingEngine(const ext::shared_ptr< PricingEngine > &)
set the pricing engine to be used.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
ext::shared_ptr< Exercise > exercise
ext::shared_ptr< Payoff > payoff
Arguments for partial-time barrier option calculation
Barrier::Type barrierType
Vanilla option (no discrete dividends, no barriers) on a single asset.
#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.
std::function< Real(Real)> b
@ NoFrequency
null frequency
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
QL_INTEGER Integer
integer number
ext::shared_ptr< QuantLib::Payoff > payoff
ext::shared_ptr< YieldTermStructure > q
ext::shared_ptr< YieldTermStructure > r
Analytic engine for partial-time barrier options.