22#include <ql/exercise.hpp>
23#include <ql/math/distributions/normaldistribution.hpp>
24#include <ql/pricingengines/asian/analytic_discr_geom_av_price.hpp>
25#include <ql/pricingengines/blackcalculator.hpp>
26#include <ql/pricingengines/greeks.hpp>
34 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
35 : process_(
std::move(process)) {
48 "not an European Option");
54 "positive running product required: "
64 ext::shared_ptr<PlainVanillaPayoff> payoff =
65 ext::dynamic_pointer_cast<PlainVanillaPayoff>(
arguments_.payoff);
66 QL_REQUIRE(payoff,
"non-plain payoff given");
68 Date referenceDate =
process_->riskFreeRate()->referenceDate();
72 std::vector<Time> fixingTimes;
78 fixingTimes.push_back(t);
82 Size remainingFixings = fixingTimes.size();
83 Size numberOfFixings = pastFixings + remainingFixings;
84 Real N =
static_cast<Real>(numberOfFixings);
86 Real pastWeight = pastFixings/N;
87 Real futureWeight = 1.0-pastWeight;
89 Time timeSum = std::accumulate(fixingTimes.begin(),
90 fixingTimes.end(),
Real(0.0));
96 for (i=pastFixings+1; i<numberOfFixings; i++)
97 temp += fixingTimes[i-pastFixings-1]*(N-i);
98 Real variance = vola*vola /N/N * (timeSum+ 2.0*temp);
99 Real dsigG_dsig = std::sqrt((timeSum + 2.0*temp))/N;
100 Real sigG = vola * dsigG_dsig;
101 Real dmuG_dsig = -(vola * timeSum)/N;
108 Rate nu = riskFreeRate - dividendRate - 0.5*vola*vola;
111 QL_REQUIRE(s > 0.0,
"positive underlying value required");
113 Size M = (pastFixings == 0 ? 1 : pastFixings);
114 Real muG = pastWeight * runningLog/M +
115 futureWeight * std::log(s) + nu*timeSum/N;
116 Real forwardPrice = std::exp(muG + variance / 2.0);
125 results_.delta = futureWeight*black.
delta(forwardPrice)*forwardPrice/s;
126 results_.gamma = forwardPrice*futureWeight/(s*s)
127 *( black.
gamma(forwardPrice)*futureWeight*forwardPrice
128 - pastWeight*black.
delta(forwardPrice) );
134 Real x_1 = (muG-std::log(payoff->strike())+variance)/sigG;
138 Nx_1 = (muG > std::log(payoff->strike()) ? 1.0 : 0.0);
141 results_.vega = forwardPrice * riskFreeDiscount *
142 ( (dmuG_dsig + sigG * dsigG_dsig)*Nx_1 + nx_1*dsigG_dsig );
145 results_.vega -= riskFreeDiscount * forwardPrice *
146 (dmuG_dsig + sigG * dsigG_dsig);
154 process_->dividendYield()->referenceDate(),
AnalyticDiscreteGeometricAveragePriceAsianEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
void calculate() const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
Black 1976 calculator class.
Real dividendRho(Time maturity) const
virtual Real delta(Real spot) const
Real strikeSensitivity() const
virtual Real gamma(Real spot) const
Real rho(Time maturity) const
Cumulative normal distribution function.
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Average::Type averageType
std::vector< Date > fixingDates
DiscreteAveragingAsianOption::results results_
DiscreteAveragingAsianOption::arguments arguments_
Normal distribution function.
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
@ NoFrequency
null frequency
Real Time
continuous quantity with 1-year units
Real DiscountFactor
discount factor between dates
Real Volatility
volatility
std::size_t Size
size of a container
Real blackScholesTheta(const ext::shared_ptr< GeneralizedBlackScholesProcess > &p, Real value, Real delta, Real gamma)
default theta calculation for Black-Scholes options