30 class AnalyticBinaryBarrierEngine_helper
34 AnalyticBinaryBarrierEngine_helper(
35 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process,
36 const ext::shared_ptr<StrikedTypePayoff> &
payoff,
37 const ext::shared_ptr<AmericanExercise> &exercise,
38 const BarrierOption::arguments &arguments):
48 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process_;
49 const ext::shared_ptr<StrikedTypePayoff> &
payoff_;
50 const ext::shared_ptr<AmericanExercise> &
exercise_;
51 const BarrierOption::arguments &arguments_;
56 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
57 : process_(
std::move(process)) {
63 ext::shared_ptr<AmericanExercise> ex =
64 ext::dynamic_pointer_cast<AmericanExercise>(
arguments_.exercise);
66 QL_REQUIRE(ex->payoffAtExpiry(),
"payoff must be at expiry");
68 process_->blackVolatility()->referenceDate(),
69 "American option with window exercise not handled yet");
71 ext::shared_ptr<StrikedTypePayoff>
payoff =
72 ext::dynamic_pointer_cast<StrikedTypePayoff>(
arguments_.payoff);
76 QL_REQUIRE(spot > 0.0,
"negative or null underlying given");
79 process_->blackVolatility()->blackVariance(ex->lastDate(),
83 "positive barrier value required");
108 ext::shared_ptr<PricingEngine> engine(
123 Rate riskFreeDiscount =
124 process_->riskFreeRate()->discount(ex->lastDate());
126 AnalyticBinaryBarrierEngine_helper helper(
process_,
131 Real AnalyticBinaryBarrierEngine_helper::payoffAtExpiry(
134 Rate dividendDiscount =
135 process_->dividendYield()->discount(
exercise_->lastDate());
138 "positive spot value required");
141 "positive discount required");
144 "positive dividend discount required");
147 "negative variance not allowed");
151 Real barrier = arguments_.barrier;
153 "positive barrier value required");
157 Real mu = std::log(dividendDiscount/discount)/
variance - 0.5;
161 ext::shared_ptr<CashOrNothingPayoff> coo =
162 ext::dynamic_pointer_cast<CashOrNothingPayoff>(
payoff_);
163 if (coo !=
nullptr) {
164 K = coo->cashPayoff();
168 ext::shared_ptr<AssetOrNothingPayoff> aoo =
169 ext::dynamic_pointer_cast<AssetOrNothingPayoff>(
payoff_);
170 if (aoo !=
nullptr) {
172 K = spot * dividendDiscount / discount;
175 Real log_S_X = std::log(spot/strike);
176 Real log_S_H = std::log(spot/barrier);
177 Real log_H_S = std::log(barrier/spot);
178 Real log_H2_SX = std::log(barrier*barrier/(spot*strike));
179 Real H_S_2mu = std::pow(barrier/spot, 2*mu);
186 Real cum_x1, cum_x2, cum_y1, cum_y2;
192 x1 = phi*(log_S_X/stdDev + mu*stdDev);
193 x2 = phi*(log_S_H/stdDev + mu*stdDev);
194 y1 = eta*(log_H2_SX/stdDev + mu*stdDev);
195 y2 = eta*(log_H_S/stdDev + mu*stdDev);
197 CumulativeNormalDistribution
f;
223 switch (barrierType) {
227 if (strike >= barrier) {
229 alpha = H_S_2mu * cum_y1;
232 alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2;
237 if (strike >= barrier) {
239 alpha = cum_x2 + H_S_2mu*(-cum_y1 + cum_y2);
250 if (strike >= barrier) {
255 alpha = cum_x2 + H_S_2mu * (-cum_y1 + cum_y2);
260 if (strike >= barrier) {
262 alpha = cum_x1 - cum_x2 + H_S_2mu * cum_y2;
265 alpha = H_S_2mu * cum_y1;
273 if (strike >= barrier) {
275 alpha = cum_x1 - H_S_2mu * cum_y1;
278 alpha = cum_x2 - H_S_2mu * cum_y2;
283 if (strike >= barrier) {
285 alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1-cum_y2);
295 if (strike >= barrier) {
300 alpha = cum_x1 - cum_x2 + H_S_2mu * (cum_y1-cum_y2);
305 if (strike >= barrier) {
307 alpha = cum_x2 - H_S_2mu * cum_y2;
310 alpha = cum_x1 - H_S_2mu * cum_y1;
315 QL_FAIL(
"invalid barrier type");
318 return discount * K *
alpha;
analytic binary barrier (cash/asset or nothing plus in-the-money check) option engine
Analytic European engine.
AnalyticBinaryBarrierEngine(ext::shared_ptr< GeneralizedBlackScholesProcess >)
void calculate() const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Pricing engine for European vanilla options using analytical formulae.
Barrier::Type barrierType
BarrierOption::results results_
BarrierOption::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 > &)
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.
LinearInterpolation variance
const ext::shared_ptr< Payoff > payoff_
ext::shared_ptr< QuantLib::Payoff > payoff
normal, cumulative and inverse cumulative distributions
const ParametricExercise & exercise_
Vanilla option on a single asset.