35 Real euroTwoAssetMinBasketCall(
Real forward1,
Real forward2,
41 Real stdDev1 = std::sqrt(variance1);
42 Real stdDev2 = std::sqrt(variance2);
47 Real modRho1 = (
rho * stdDev2 - stdDev1) / stdDev;
48 Real modRho2 = (
rho * stdDev1 - stdDev2) / stdDev;
50 Real D1 = (std::log(forward1/forward2) + 0.5*
variance) / stdDev;
62 (std::log(forward1/strike) + 0.5*variance1) / stdDev1;
64 (std::log(forward2/strike) + 0.5*variance2) / stdDev2;
65 alfa = bivCNormMod1(D1_1, -D1);
66 beta = bivCNormMod2(D1_2, D1 - stdDev);
67 gamma = bivCNorm(D1_1 - stdDev1, D1_2 - stdDev2);
69 CumulativeNormalDistribution cum;
71 beta = cum(D1 - stdDev);
75 return riskFreeDiscount *
76 (forward1*alfa + forward2*
beta - strike*gamma);
81 Real euroTwoAssetMaxBasketCall(
Real forward1,
Real forward2,
87 ext::shared_ptr<StrikedTypePayoff>
payoff(
new
91 forward1, std::sqrt(variance1)) * riskFreeDiscount;
94 forward2, std::sqrt(variance2)) * riskFreeDiscount;
96 return black1 + black2 -
97 euroTwoAssetMinBasketCall(forward1, forward2, strike,
99 variance1, variance2,
rho);
104 ext::shared_ptr<GeneralizedBlackScholesProcess> process2,
106 : process1_(
std::move(process1)), process2_(
std::move(process2)), rho_(correlation) {
114 "not an European Option");
116 ext::shared_ptr<EuropeanExercise> exercise =
118 QL_REQUIRE(exercise,
"not an European Option");
120 ext::shared_ptr<BasketPayoff> basket_payoff =
123 ext::shared_ptr<MinBasketPayoff> min_basket =
126 ext::shared_ptr<MaxBasketPayoff> max_basket =
128 QL_REQUIRE(min_basket || max_basket,
"unknown basket type");
130 ext::shared_ptr<PlainVanillaPayoff>
payoff =
131 ext::dynamic_pointer_cast<PlainVanillaPayoff>(basket_payoff->basePayoff());
136 Real variance1 =
process1_->blackVolatility()->blackVariance(
137 exercise->lastDate(), strike);
138 Real variance2 =
process2_->blackVolatility()->blackVariance(
139 exercise->lastDate(), strike);
142 process1_->riskFreeRate()->discount(exercise->lastDate());
146 process1_->dividendYield()->discount(exercise->lastDate());
148 process2_->dividendYield()->discount(exercise->lastDate());
151 dividendDiscount1 / riskFreeDiscount;
153 dividendDiscount2 / riskFreeDiscount;
155 if (max_basket !=
nullptr) {
156 switch (
payoff->optionType()) {
160 euroTwoAssetMaxBasketCall(forward1, forward2, strike,
162 variance1, variance2,
169 euroTwoAssetMaxBasketCall(forward1, forward2, 0.0,
171 variance1, variance2,
rho_) +
172 euroTwoAssetMaxBasketCall(forward1, forward2, strike,
174 variance1, variance2,
rho_);
177 QL_FAIL(
"unknown option type");
179 }
else if (min_basket !=
nullptr) {
180 switch (
payoff->optionType()) {
184 euroTwoAssetMinBasketCall(forward1, forward2, strike,
186 variance1, variance2,
192 euroTwoAssetMinBasketCall(forward1, forward2, 0.0,
194 variance1, variance2,
rho_) +
195 euroTwoAssetMinBasketCall(forward1, forward2, strike,
197 variance1, variance2,
rho_);
200 QL_FAIL(
"unknown option type");
bivariate cumulative normal distribution
Black-formula calculator class.
BasketOption::results results_
BasketOption::arguments arguments_
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
ext::shared_ptr< Exercise > exercise
ext::shared_ptr< Payoff > payoff
ext::shared_ptr< GeneralizedBlackScholesProcess > process2_
ext::shared_ptr< GeneralizedBlackScholesProcess > process1_
StulzEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process1, ext::shared_ptr< GeneralizedBlackScholesProcess > process2, Real correlation)
void calculate() const override
#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 DiscountFactor
discount factor between dates
ext::shared_ptr< QuantLib::Payoff > payoff
BivariateCumulativeNormalDistributionWe04DP BivariateCumulativeNormalDistribution
default bivariate implementation
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
normal, cumulative and inverse cumulative distributions
2D European Basket formulae, due to Stulz (1982)