43 const bool adaptVanDelta,
44 const Real bsPriceWithSmile)
45 : atmVol_(
std::move(atmVol)), vol25Put_(
std::move(vol25Put)), vol25Call_(
std::move(vol25Call)),
46 T_(atmVol_->maturity()), spotFX_(
std::move(spotFX)), domesticTS_(
std::move(domesticTS)),
47 foreignTS_(
std::move(foreignTS)), adaptVanDelta_(adaptVanDelta),
48 bsPriceWithSmile_(bsPriceWithSmile) {
54 "Maturity of 3 vols are not the same");
71 "Invalid barrier type");
73 const Real sigmaShift_vega = 0.0001;
74 const Real sigmaShift_volga = 0.0001;
75 const Real spotShift_delta = 0.0001 *
spotFX_->value();
76 const Real sigmaShift_vanna = 0.0001;
79 ext::make_shared<SimpleQuote>(
spotFX_->value()));
81 ext::make_shared<SimpleQuote>(
atmVol_->value()));
83 ext::shared_ptr<BlackVolTermStructure> blackVolTS =
84 ext::make_shared<BlackConstantVol>(
87 ext::shared_ptr<BlackScholesMertonProcess> stochProcess =
88 ext::make_shared<BlackScholesMertonProcess>(
94 ext::shared_ptr<PricingEngine> engineBS =
95 ext::make_shared<AnalyticBarrierEngine>(stochProcess);
108 put25Vol * sqrt(
T_));
112 call25Vol * sqrt(
T_));
117 std::vector<Real> strikes;
118 std::vector<Real> vols;
119 strikes.push_back(put25Strike);
120 vols.push_back(put25Vol);
121 strikes.push_back(atmStrike);
122 vols.push_back(
atmVol_->value());
123 strikes.push_back(call25Strike);
124 vols.push_back(call25Vol);
128 const ext::shared_ptr<StrikedTypePayoff>
payoff =
129 ext::dynamic_pointer_cast<StrikedTypePayoff>(
arguments_.payoff);
130 Real strikeVol = interpolation(
payoff->strike());
136 strikeVol * sqrt(
T_),
187 ext::dynamic_pointer_cast<StrikedTypePayoff>(
arguments_.payoff),
193 Real priceBS = barrierOption.
NPV();
216 call25Vol * sqrt(
T_),
226 Real d1atm = (std::log(forward/atmStrike)
227 + 0.5*std::pow(atmVolQuote->value(),2.0) *
T_)/(atmVolQuote->value() * sqrt(
T_));
228 Real vegaAtm_Analytical = x0Quote->value() * norm(d1atm) * sqrt(
T_) *
foreignTS_->discount(
T_);
229 Real vannaAtm_Analytical = vegaAtm_Analytical/x0Quote->value() *(1.0 - d1atm/(atmVolQuote->value()*sqrt(
T_)));
230 Real volgaAtm_Analytical = vegaAtm_Analytical * d1atm * (d1atm - atmVolQuote->value() * sqrt(
T_))/atmVolQuote->value();
232 Real d125call = (std::log(forward/call25Strike)
233 + 0.5*std::pow(atmVolQuote->value(),2.0) *
T_)/(atmVolQuote->value() * sqrt(
T_));
234 Real vega25Call_Analytical = x0Quote->value() * norm(d125call) * sqrt(
T_) *
foreignTS_->discount(
T_);
235 Real vanna25Call_Analytical = vega25Call_Analytical/x0Quote->value() *(1.0 - d125call/(atmVolQuote->value()*sqrt(
T_)));
236 Real volga25Call_Analytical = vega25Call_Analytical * d125call * (d125call - atmVolQuote->value() * sqrt(
T_))/atmVolQuote->value();
238 Real d125Put = (std::log(forward/put25Strike)
239 + 0.5*std::pow(atmVolQuote->value(),2.0) *
T_)/(atmVolQuote->value() * sqrt(
T_));
240 Real vega25Put_Analytical = x0Quote->value() * norm(d125Put) * sqrt(
T_) *
foreignTS_->discount(
T_);
241 Real vanna25Put_Analytical = vega25Put_Analytical/x0Quote->value() *(1.0 - d125Put/(atmVolQuote->value()*sqrt(
T_)));
242 Real volga25Put_Analytical = vega25Put_Analytical * d125Put * (d125Put - atmVolQuote->value() * sqrt(
T_))/atmVolQuote->value();
246 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
248 Real vegaBarBS = (barrierOption.
NPV() - priceBS)/sigmaShift_vega;
250 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() - sigmaShift_vega);
256 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() + sigmaShift_volga);
258 Real priceBS2 = barrierOption.
NPV();
261 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() + sigmaShift_vega);
263 Real vegaBarBS2 = (barrierOption.
NPV() - priceBS2)/sigmaShift_vega;
264 Real volgaBarBS = (vegaBarBS2 - vegaBarBS)/sigmaShift_volga;
266 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value()
272 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() + spotShift_delta);
274 Real priceBS_delta1 = barrierOption.
NPV();
276 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);
278 Real priceBS_delta2 = barrierOption.
NPV();
280 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() + spotShift_delta);
281 Real deltaBar1 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);
284 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() + sigmaShift_vanna);
285 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() + spotShift_delta);
287 priceBS_delta1 = barrierOption.
NPV();
289 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() - 2 * spotShift_delta);
291 priceBS_delta2 = barrierOption.
NPV();
293 ext::static_pointer_cast<SimpleQuote> (x0Quote.
currentLink())->setValue(x0Quote->value() + spotShift_delta);
294 Real deltaBar2 = (priceBS_delta1 - priceBS_delta2)/(2.0*spotShift_delta);
296 Real vannaBarBS = (deltaBar2 - deltaBar1)/sigmaShift_vanna;
298 ext::static_pointer_cast<SimpleQuote> (atmVolQuote.
currentLink())->setValue(atmVolQuote->value() - sigmaShift_vanna);
304 A[0][0] = vegaAtm_Analytical;
305 A[0][1] = vega25Call_Analytical;
306 A[0][2] = vega25Put_Analytical;
307 A[1][0] = vannaAtm_Analytical;
308 A[1][1] = vanna25Call_Analytical;
309 A[1][2] = vanna25Put_Analytical;
310 A[2][0] = volgaAtm_Analytical;
311 A[2][1] = volga25Call_Analytical;
312 A[2][2] = volga25Put_Analytical;
326 Real probTouch = 0.0;
331 Real p_survival = 1.0 - probTouch;
333 Real lambda = p_survival ;
334 Real adjust =
q[0]*(priceAtmCallMkt - priceAtmCallBS)
335 +
q[1]*(price25CallMkt - price25CallBS)
336 +
q[2]*(price25PutMkt - price25PutBS);
337 Real outPrice = priceBS + lambda*adjust;
349 outPrice = std::max(0.0, std::min(vanillaOption, outPrice));
350 inPrice = vanillaOption - outPrice;
Analytic barrier option engines.
Black constant volatility, no time dependence, no strike dependence.
Black-Scholes formula delta calculator class.
Actual/365 (Fixed) day count convention.
1-D array used in linear algebra.
Barrier::Type barrierType
Barrier option on a single asset.
Black delta calculator class.
Real atmStrike(DeltaVolQuote::AtmType atmT) const
Real strikeFromDelta(Real delta) const
Cumulative normal distribution function.
BarrierOption::results results_
BarrierOption::arguments arguments_
Shared handle to an observable.
const ext::shared_ptr< T > & currentLink() const
dereferencing
std::map< std::string, ext::any > additionalResults
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.
base class for 1-D interpolations.
Matrix used in linear algebra.
Normal distribution function.
Calendar for reproducing theoretical calculations.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
static Settings & instance()
access to the unique instance
const bool adaptVanDelta_
const Handle< Quote > spotFX_
const Handle< YieldTermStructure > foreignTS_
const Handle< DeltaVolQuote > vol25Put_
const Handle< DeltaVolQuote > vol25Call_
void calculate() const override
VannaVolgaBarrierEngine(Handle< DeltaVolQuote > atmVol, Handle< DeltaVolQuote > vol25Put, Handle< DeltaVolQuote > vol25Call, Handle< Quote > spotFX, Handle< YieldTermStructure > domesticTS, Handle< YieldTermStructure > foreignTS, bool adaptVanDelta=false, Real bsPriceWithSmile=0.0)
const Handle< YieldTermStructure > domesticTS_
const Real bsPriceWithSmile_
const Handle< DeltaVolQuote > atmVol_
VannaVolga-interpolation factory and traits
Interpolation interpolate(const I1 &xBegin, const I1 &xEnd, const I2 &yBegin) const
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
ext::function< Real(Real)> b
ext::shared_ptr< QuantLib::Payoff > payoff
matrix used in linear algebra.
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
Matrix inverse(const Matrix &m)
Calendar for reproducing theoretical calculations.
ext::shared_ptr< YieldTermStructure > q
Vanna/Volga barrier option engine.
Vanna/Volga interpolation between discrete points.