29 ext::shared_ptr<GeneralizedBlackScholesProcess> process)
30 : process_(
std::move(process)) {
37 "not a geometric average option");
40 "not an European option");
43 "positive running product required: "
47 QL_REQUIRE(pastFixings == 0,
"past fixings currently not managed");
49 ext::shared_ptr<PlainVanillaPayoff>
payoff =
50 ext::dynamic_pointer_cast<PlainVanillaPayoff>(
arguments_.payoff);
57 std::vector<Time> fixingTimes;
61 fixingTimes.push_back(
t);
65 Size remainingFixings = fixingTimes.size();
66 Size numberOfFixings = pastFixings + remainingFixings;
67 Real N =
static_cast<Real>(numberOfFixings);
69 Real pastWeight = pastFixings/N;
70 Real futureWeight = 1.0-pastWeight;
72 Time timeSum = std::accumulate(fixingTimes.begin(),
73 fixingTimes.end(),
Real(0.0));
80 QL_REQUIRE(underlying > 0.0,
"positive underlying value required");
93 Rate nu = riskFreeRate - dividendRate - 0.5*volatility*volatility;
96 for (
Size i=pastFixings+1; i<numberOfFixings; i++)
97 temp += fixingTimes[i-pastFixings-1]*(N-i);
98 Real variance = volatility*volatility /N/N * (timeSum + 2.0*temp);
99 Real covarianceTerm = volatility*volatility/N * timeSum;
100 Real sigmaSum_2 =
variance + volatility*volatility*residualTime -
103 Size M = (pastFixings == 0 ? 1 : pastFixings);
104 Real runningLogAverage = runningLog/M;
106 Real muG = pastWeight * runningLogAverage +
107 futureWeight * std::log(underlying) +
112 Real y1 = (std::log(underlying)+
113 (riskFreeRate-dividendRate)*residualTime-
114 muG -
variance/2.0 + sigmaSum_2/2.0)
115 /std::sqrt(sigmaSum_2);
116 Real y2 = y1-std::sqrt(sigmaSum_2);
118 switch (
payoff->optionType()) {
120 results_.
value = underlying*std::exp(-dividendRate*residualTime)
122 std::exp(muG +
variance/2.0 - riskFreeRate*residualTime)
126 results_.
value = -underlying*std::exp(-dividendRate*residualTime)
128 std::exp(muG +
variance/2.0 - riskFreeRate*residualTime)
132 QL_FAIL(
"invalid option type");
Analytic engine for discrete geometric average-strike Asian option.
AnalyticDiscreteGeometricAverageStrikeAsianEngine(ext::shared_ptr< GeneralizedBlackScholesProcess > process)
void calculate() const override
ext::shared_ptr< GeneralizedBlackScholesProcess > process_
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_
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
#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
@ NoFrequency
null frequency
Real Time
continuous quantity with 1-year units
Real Volatility
volatility
std::size_t Size
size of a container
ext::shared_ptr< QuantLib::Payoff > payoff
normal, cumulative and inverse cumulative distributions