149 {
150
151 BOOST_TEST_MESSAGE("Testing cash settled option pricing before expiry...");
152
153 Settings::instance().evaluationDate() = Date(3, Jun, 2020);
154
155
156 Date expiry(3, Sep, 2020);
157 Date payment(7, Sep, 2020);
158 bool automaticExercise = false;
160
161
162 Rate spot = 60.00;
163 Volatility vol = 0.30;
164 Rate r = 0.02;
165 Rate q = 0.01;
166 QuantLib::ext::shared_ptr<PricingEngine> engine =
167 QuantLib::ext::make_shared<AnalyticCashSettledEuropeanEngine>(getProcess(spot, vol, r, q));
168
169
170 option.setPricingEngine(engine);
171 map<string, Real> cashSettledResults = results(option);
172
173
174 engine = QuantLib::ext::make_shared<AnalyticEuropeanEngine>(getProcess(spot, vol, r, q));
175 option.setPricingEngine(engine);
176 map<string, Real> theoreticalResults = results(option);
177
178
179 auto yts = flatYts(r);
180 DiscountFactor df_te_tp = yts->discount(payment) / yts->discount(expiry);
181 BOOST_TEST_MESSAGE("Discount factor from payment to expiry is: " << fixed << setprecision(12) << df_te_tp);
182
183
184 Real tolerance = 1e-12;
185 BOOST_REQUIRE_EQUAL(cashSettledResults.size(), theoreticalResults.size());
186 BOOST_REQUIRE(cashSettledResults.count("npv") == 1);
187 BOOST_REQUIRE(theoreticalResults.count("npv") == 1);
188 for (const auto& kv : cashSettledResults) {
189
190 BOOST_TEST_CONTEXT("With result " << kv.first) {
191
192 auto it = theoreticalResults.find(kv.first);
193 BOOST_CHECK(it != theoreticalResults.end());
194
195
196 if (it == theoreticalResults.end())
197 continue;
198
199
200 Real theorResult = it->second;
201 BOOST_TEST_MESSAGE("Value for " << kv.first << " with cash settlement is: " << fixed << setprecision(12)
202 << kv.second);
203 BOOST_TEST_MESSAGE("Value for " << kv.first << " ignoring cash settlement is: " << fixed << setprecision(12)
204 << theorResult);
205
206
207
208 if (close(theorResult, 0.0)) {
209 BOOST_CHECK(close(kv.second, 0.0));
210 } else if (kv.first == "elasticity" || kv.first == "itmCashProbability") {
211 BOOST_CHECK(close(kv.second, theorResult));
212 } else if (kv.first == "rho") {
213 Time delta_te_tp = yts->timeFromReference(payment) - yts->timeFromReference(expiry);
214 Real expRho = df_te_tp * (theorResult - delta_te_tp * theoreticalResults.at("npv"));
215 BOOST_TEST_MESSAGE("Value for expected rho is: " << fixed << setprecision(12) << expRho);
216 BOOST_CHECK(close(kv.second, expRho));
217 } else {
218 BOOST_CHECK_SMALL(kv.second / theorResult - df_te_tp, tolerance);
219 }
220 }
221 }
222}