221 {
222
223 BOOST_TEST_MESSAGE("Testing EquityFutureOption Put-Call parity...");
224
225 Date today = Settings::instance().evaluationDate();
226
227
228 QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
229 Settings::instance().evaluationDate() = market->asofDate();
230 Date expiry = market->asofDate() + 6 * Months + 1 * Days;
231 ostringstream o;
232 o << QuantLib::io::iso_date(expiry);
233 string exp_str = o.str();
234
235 Date futureExpiry = market->asofDate() + 12 * Months + 1 * Days;
236 ostringstream o_2;
237 o_2 << QuantLib::io::iso_date(futureExpiry);
238 string f_exp_str = o_2.str();
239
240 QuantLib::ext::shared_ptr<ore::data::Underlying> underlying = QuantLib::ext::make_shared<ore::data::EquityUnderlying>("zzzCorp");
241 double spot = 100;
242
243 OptionData callData(
"Long",
"Call",
"European",
true, vector<string>(1, exp_str));
244 OptionData callDataPremium(
"Long",
"Call",
"European",
true, vector<string>(1, exp_str),
"Physical",
"",
246 OptionData putData(
"Long",
"Put",
"European",
true, vector<string>(1, exp_str));
247 OptionData putDataPremium(
"Long",
"Put",
"European",
true, vector<string>(1, exp_str),
"Physical",
"",
250 TradeStrike strike(TradeStrike::Type::Price, 95.0);
251 EquityFutureOption eqCall(env, callData,
"EUR", 1.0, underlying, strike, futureExpiry);
252 EquityFutureOption eqCallPremium(env, callDataPremium,
"EUR", 1.0, underlying, strike, futureExpiry);
254 EquityFutureOption eqPutPremium(env, putDataPremium,
"EUR", 1.0, underlying, strike, futureExpiry);
256
257
258 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
259 engineData->model("EquityFutureOption") = "BlackScholes";
260 engineData->engine("EquityFutureOption") = "AnalyticEuropeanForwardEngine";
261 engineData->model("EquityOption") = "BlackScholesMerton";
262 engineData->engine("EquityOption") = "AnalyticEuropeanEngine";
263 engineData->model("EquityForward") = "DiscountedCashflows";
264 engineData->engine("EquityForward") = "DiscountingEquityForwardEngine";
265 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
266
267 eqCall.build(engineFactory);
268 eqCallPremium.build(engineFactory);
269 eqPut.build(engineFactory);
270 eqPutPremium.build(engineFactory);
271 eqFwd.build(engineFactory);
272
273 Handle<YieldTermStructure> discountCurve =
275
278
279 Real npv_call = eqCall.instrument()->NPV();
280 Real npv_call_premium = eqCallPremium.instrument()->NPV();
281 Real npv_put = eqPut.instrument()->NPV();
282 Real npv_put_premium = eqPutPremium.instrument()->NPV();
283
284 Real npv_fwd = spot * dividend->discount(futureExpiry) / forecast->discount(futureExpiry);;
285
286 Real put_sum = npv_put + ( npv_fwd - strike.value() ) * discountCurve->discount(expiry);
287 Real put_premium_sum = npv_put_premium + ( npv_fwd - strike.value() ) * discountCurve->discount(expiry);
288
289 BOOST_CHECK_CLOSE(npv_call, put_sum, 0.001);
290 BOOST_CHECK_CLOSE(npv_call_premium, put_premium_sum, 0.001);
291
292 Settings::instance().evaluationDate() = today;
293}
static const string defaultConfiguration
Default configuration label.