36#include <boost/math/special_functions/sign.hpp>
41 std::vector<ext::shared_ptr<GeneralizedBlackScholesProcess> > processes,
43 Size maxNrIntegrationSteps,
44 bool calcFwdDelta,
bool controlVariate)
45 : n_(processes.size()),
46 processes_(
std::move(processes)),
49 maxNrIntegrationSteps_(maxNrIntegrationSteps),
50 calcFwdDelta_(calcFwdDelta || controlVariate),
51 controlVariate_(controlVariate) {
53 QL_REQUIRE(
n_ > 0,
"No Black-Scholes process is given.");
55 "process and correlation matrix must have the same size.");
60 [
this](
const auto& p) { registerWith(p); });
64 const ext::shared_ptr<EuropeanExercise> exercise =
66 QL_REQUIRE(exercise,
"not an European exercise");
68 const Date maturityDate = exercise->lastDate();
76 const Array fwd =
s * dq/dr0;
78 const ext::shared_ptr<AverageBasketPayoff> avgPayoff =
79 (ext::dynamic_pointer_cast<AverageBasketPayoff>(
arguments_.
payoff) !=
nullptr)
81 : (ext::dynamic_pointer_cast<SpreadBasketPayoff>(
arguments_.
payoff) !=
nullptr)
82 ? ext::make_shared<AverageBasketPayoff>(
83 ext::dynamic_pointer_cast<SpreadBasketPayoff>(
87 : ext::shared_ptr<AverageBasketPayoff>();
89 QL_REQUIRE(avgPayoff,
"average or spread basket payoff expected");
91 const Array weights = avgPayoff->weights();
93 "wrong number of weights arguments in payoff");
95 const Array g = weights*fwd /
Norm2(weights*fwd);
98 Array vStar1 = Sigma*g;
108 for (
Size i=0; i <
n_; ++i)
109 if (boost::math::sign(g[i])*vStar1[i] < tol*stdDev[i]) {
111 vStar1[i] = eps * boost::math::sign(g[i]) * stdDev[i];
117 for (
Size i=0; i <
n_; ++i)
118 q1[i] = (vStar1[i] - std::inner_product(
134 for (
Size i=0; i <
n_; ++i)
137 const SVD svd(C*R_2_n);
142 for (
Size i=0; i <
n_-1; ++i)
145 [i, &sv](
Real x) ->
Real { return sv[i]*x; }
148 std::vector<Size> nIntOrder(
n_-1);
153 for (
Size i=0; i <
n_-1; ++i)
154 nIntOrder[i] =
Size(std::lround(1 + intScale*sv[i]));
158 "can not rescale lambda to fit max integration order");
159 }
while (std::accumulate(
160 nIntOrder.begin(), nIntOrder.end(), 1.0, std::multiplies<>())
163 std::vector<ext::shared_ptr<SimpleQuote> > quotes;
164 std::vector<ext::shared_ptr<GeneralizedBlackScholesProcess> > p;
165 for (
Size i=0; i <
n_; ++i) {
166 quotes.push_back(ext::make_shared<SimpleQuote>(fwd[i]));
170 bv->dayCounter().yearFraction(bv->referenceDate(), maturityDate)
173 ext::make_shared<BlackProcess>(
177 ext::make_shared<BlackConstantVol>(
178 bv->referenceDate(), bv->calendar(),
191 for (
Size i=0; i <
n_; ++i)
192 vq[i] = 0.5*std::accumulate(
193 v.row_begin(i),
v.row_end(i),
Real(0.0),
199 [](
const Size n) {
return ext::make_shared<GaussHermiteIntegration>(
n); }
201 const Real normFactor = std::pow(
M_PI, -0.5*nIntOrder.size());
203 std::vector<Real> dStore;
204 dStore.reserve(ghq.weights().size());
205 const auto bsm1dPricer = [&](
const Array& z) ->
Real {
208 for (
Size i=0; i <
f.size(); ++i)
209 quotes[i]->setValue(
f[i]);
218 const ext::shared_ptr<PlainVanillaPayoff>
payoff =
219 ext::dynamic_pointer_cast<PlainVanillaPayoff>(avgPayoff->basePayoff());
227 for (
Size k=0; k <
n_; ++k) {
230 const auto deltaPricer = [&](
const Array& z) ->
Real {
231 const Real d = dStore[dStoreCounter++];
232 const Real vz = std::inner_product(
233 v.row_begin(k),
v.row_end(k), z.begin(),
Real(0.0));
236 return std::exp(-
DotProduct(z, z)) *
f * N(
d + vStar1[k]);
239 fwdDelta[k] = dr0*weights[k]*(ghq(deltaPricer) * normFactor + putIndicator);
241 const std::string deltaName =
"forwardDelta " + std::to_string(k);
246 for (
Size k=0; k <
n_; ++k) {
247 const auto fHatPricer = [&](
const Array& z) ->
Real {
248 const Real vz = std::inner_product(
249 v.row_begin(k),
v.row_end(k), z.begin(),
Real(0.0));
254 fHat[k] = ghq(fHatPricer) * normFactor;
256 const Array cv = fwdDelta*fwd*(fHat-1.0);
Black constant volatility, no time dependence, no strike dependence.
Jaehyuk Choi: Sum of all Black-Scholes-Merton Models.
1-D array used in linear algebra.
const_iterator end() const
Size size() const
dimension of the array
const_iterator begin() const
Basket option on a number of assets.
const bool controlVariate_
const Size maxNrIntegrationSteps_
ChoiBasketEngine(std::vector< ext::shared_ptr< GeneralizedBlackScholesProcess > > processes, Matrix rho, Real lambda=10.0, Size maxNrIntegrationSteps=std::numeric_limits< Size >::max(), bool calcfwdDelta=false, bool controlVariate=false)
void calculate() const override
const std::vector< ext::shared_ptr< GeneralizedBlackScholesProcess > > processes_
Cumulative normal distribution function.
BasketOption::results results_
BasketOption::arguments arguments_
Shared handle to an observable.
std::map< std::string, ext::any > additionalResults
const std::map< std::string, ext::any > & additionalResults() const
returns all additional result returned by the pricing engine.
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.
Matrix used in linear algebra.
const_row_iterator row_begin(Size i) const
const_column_iterator column_begin(Size i) const
const_row_iterator row_end(Size i) const
const_column_iterator column_end(Size i) const
ext::shared_ptr< Exercise > exercise
ext::shared_ptr< Payoff > payoff
Singular value decomposition.
const Array & singularValues() const
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Option exercise classes and payoff function.
Integral of a 1-dimensional function using the Gauss quadratures.
Covariance matrix calculation.
Real DiscountFactor
discount factor between dates
Real Volatility
volatility
std::size_t Size
size of a container
Householder transformation and Householder projection.
ext::shared_ptr< QuantLib::Payoff > payoff
Matrix CholeskyDecomposition(const Matrix &S, bool flexible)
Matrix getCovariance(DataIterator stdDevBegin, DataIterator stdDevEnd, const Matrix &corr, Real tolerance=1.0e-12)
Calculation of covariance from correlation and standard deviations.
Array Exp(const Array &v)
Array Sqrt(const Array &v)
Real Norm2(const Array &v)
Matrix transpose(const Matrix &m)
Real DotProduct(const Array &v1, const Array &v2)
normal, cumulative and inverse cumulative distributions
ext::shared_ptr< BlackVolTermStructure > v
Basket engine where all underlyings are driven by one stochastic factor.
singular value decomposition