Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
equitytrades.cpp File Reference
#include <boost/make_shared.hpp>
#include <boost/test/unit_test.hpp>
#include <ored/marketdata/marketimpl.hpp>
#include <ored/portfolio/builders/equityforward.hpp>
#include <ored/portfolio/builders/equityoption.hpp>
#include <ored/portfolio/builders/equityfuturesoption.hpp>
#include <ored/portfolio/enginedata.hpp>
#include <ored/portfolio/equityforward.hpp>
#include <ored/portfolio/equityoption.hpp>
#include <ored/portfolio/equityfuturesoption.hpp>
#include <oret/toplevelfixture.hpp>
#include <ql/math/distributions/normaldistribution.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/daycounters/actualactual.hpp>
#include <qle/indexes/equityindex.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testEquityTradePrices)
 
 BOOST_AUTO_TEST_CASE (testEquityFutureOptionPrices)
 
 BOOST_AUTO_TEST_CASE (testEquityFutureParity)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/3]

BOOST_AUTO_TEST_CASE ( testEquityTradePrices  )

Definition at line 96 of file equitytrades.cpp.

96 {
97
98 BOOST_TEST_MESSAGE("Testing EquityOption Price...");
99
100 Date today = Settings::instance().evaluationDate();
101
102 // build market
103 QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
104 Settings::instance().evaluationDate() = market->asofDate();
105 Date expiry = market->asofDate() + 6 * Months + 1 * Days;
106 ostringstream o;
107 o << QuantLib::io::iso_date(expiry);
108 string exp_str = o.str();
109
110 // build EquityOption - expiry in 1 Year
111 OptionData callData("Long", "Call", "European", true, vector<string>(1, exp_str));
112 OptionData callDataPremium("Long", "Call", "European", true, vector<string>(1, exp_str), "Cash", "",
113 PremiumData{1.0, "EUR", expiry});
114 OptionData putData("Short", "Put", "European", true, vector<string>(1, exp_str));
115 OptionData putDataPremium("Short", "Put", "European", true, vector<string>(1, exp_str), "Cash", "",
116 PremiumData{1.0, "EUR", expiry});
117 Envelope env("CP1");
118 TradeStrike tradeStrike(95.0, "EUR");
119 EquityOption eqCall(env, callData, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
120 EquityOption eqCallPremium(env, callDataPremium, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
121 EquityOption eqPut(env, putData, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
122 EquityOption eqPutPremium(env, putDataPremium, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
123 ore::data::EquityForward eqFwd(env, "Long", EquityUnderlying("zzzCorp"), "EUR", 1.0, exp_str, 95.0);
124
125 Real expectedNPV_Put = -2.4648; // negative for sold option
126 Real expectedNPV_Put_Premium = -1.513558; // less negative due to received premium of 1 EUR at expiry
127
128 // Build and price
129 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
130 engineData->model("EquityOption") = "BlackScholesMerton";
131 engineData->engine("EquityOption") = "AnalyticEuropeanEngine";
132 engineData->model("EquityForward") = "DiscountedCashflows";
133 engineData->engine("EquityForward") = "DiscountingEquityForwardEngine";
134 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
135
136 eqCall.build(engineFactory);
137 eqCallPremium.build(engineFactory);
138 eqPut.build(engineFactory);
139 eqPutPremium.build(engineFactory);
140 eqFwd.build(engineFactory);
141
142 Real npv_call = eqCall.instrument()->NPV();
143 Real npv_call_premium = eqCallPremium.instrument()->NPV();
144 Real npv_put = eqPut.instrument()->NPV();
145 Real npv_put_premium = eqPutPremium.instrument()->NPV();
146 Real npv_fwd = eqFwd.instrument()->NPV();
147
148 Real put_call_sum = npv_call + npv_put;
149 Real put_call_premium_sum = npv_call_premium + npv_put_premium;
150
151 BOOST_CHECK_CLOSE(expectedNPV_Put, npv_put, 0.001);
152 BOOST_CHECK_CLOSE(expectedNPV_Put_Premium, npv_put_premium, 0.001);
153 BOOST_CHECK_CLOSE(npv_fwd, put_call_sum, 0.001); // put-call parity check
154 BOOST_CHECK_CLOSE(npv_fwd, put_call_premium_sum, 0.001); // put-call parity check
155
156 Settings::instance().evaluationDate() = today; // reset
157}
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Serializable Equity Option.
Serializable object holding option data.
Definition: optiondata.hpp:42
Serializable object holding premium data.
Definition: premiumdata.hpp:37
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [2/3]

BOOST_AUTO_TEST_CASE ( testEquityFutureOptionPrices  )

Definition at line 160 of file equitytrades.cpp.

160 {
161
162 BOOST_TEST_MESSAGE("Testing EquityFutureOption Price...");
163
164 Date today = Settings::instance().evaluationDate();
165
166 // build market
167 QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
168 Settings::instance().evaluationDate() = market->asofDate();
169 Date expiry = market->asofDate() + 6 * Months + 1 * Days;
170 ostringstream o;
171 o << QuantLib::io::iso_date(expiry);
172 string exp_str = o.str();
173
174 QuantLib::ext::shared_ptr<ore::data::Underlying> underlying = QuantLib::ext::make_shared<ore::data::EquityUnderlying>("zzzCorp");
175 // build EquityOption - expiry in 1 Year
176 OptionData callData("Long", "Call", "European", true, vector<string>(1, exp_str));
177 OptionData callDataPremium("Long", "Call", "European", true, vector<string>(1, exp_str), "Physical", "",
178 PremiumData(1.0, "EUR", expiry));
179 OptionData putData("Short", "Put", "European", true, vector<string>(1, exp_str));
180 OptionData putDataPremium("Short", "Put", "European", true, vector<string>(1, exp_str), "Physical", "",
181 PremiumData(1.0, "EUR", expiry));
182 Envelope env("CP1");
183 TradeStrike strike(TradeStrike::Type::Price, 95.0);
184 EquityFutureOption eqFwdCall(env, callData, "EUR", 1.0, underlying, strike, expiry);
185 EquityFutureOption eqFwdCallPremium(env, callDataPremium, "EUR", 1.0, underlying, strike, expiry);
186 EquityFutureOption eqFwdPut(env, putData, "EUR", 1.0, underlying, strike, expiry);
187 EquityFutureOption eqFwdPutPremium(env, putDataPremium, "EUR", 1.0, underlying, strike, expiry);
188
189 TradeStrike tradeStrike(95.0, "EUR");
190 EquityOption eqCall(env, callData, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
191 EquityOption eqCallPremium(env, callDataPremium, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
192 EquityOption eqPut(env, putData, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
193 EquityOption eqPutPremium(env, putDataPremium, EquityUnderlying("zzzCorp"), "EUR", 1.0, tradeStrike);
194
195 // Build and price
196 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
197 engineData->model("EquityOption") = "BlackScholesMerton";
198 engineData->engine("EquityOption") = "AnalyticEuropeanEngine";
199 engineData->model("EquityFutureOption") = "BlackScholes";
200 engineData->engine("EquityFutureOption") = "AnalyticEuropeanForwardEngine";
201 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
202
203 eqFwdCall.build(engineFactory);
204 eqFwdCallPremium.build(engineFactory);
205 eqFwdPut.build(engineFactory);
206 eqFwdPutPremium.build(engineFactory);
207
208 eqCall.build(engineFactory);
209 eqCallPremium.build(engineFactory);
210 eqPut.build(engineFactory);
211 eqPutPremium.build(engineFactory);
212
213 BOOST_CHECK_CLOSE(eqCall.instrument()->NPV(), eqFwdCall.instrument()->NPV(), 0.001);
214 BOOST_CHECK_CLOSE(eqCallPremium.instrument()->NPV(), eqFwdCallPremium.instrument()->NPV(), 0.001);
215 BOOST_CHECK_CLOSE(eqPut.instrument()->NPV(), eqFwdPut.instrument()->NPV(), 0.001);
216 BOOST_CHECK_CLOSE(eqPutPremium.instrument()->NPV(), eqFwdPutPremium.instrument()->NPV(), 0.001);
217
218 Settings::instance().evaluationDate() = today; // reset
219}
Serializable EQ Futures Option.
+ Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [3/3]

BOOST_AUTO_TEST_CASE ( testEquityFutureParity  )

Definition at line 221 of file equitytrades.cpp.

221 {
222
223 BOOST_TEST_MESSAGE("Testing EquityFutureOption Put-Call parity...");
224
225 Date today = Settings::instance().evaluationDate();
226
227 // build market
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 // build EquityOption - expiry in 1 Year
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", "",
245 PremiumData(1.0, "EUR", expiry));
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", "",
248 PremiumData(1.0, "EUR", expiry));
249 Envelope env("CP1");
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);
253 EquityFutureOption eqPut(env, putData, "EUR", 1.0, underlying, strike, futureExpiry);
254 EquityFutureOption eqPutPremium(env, putDataPremium, "EUR", 1.0, underlying, strike, futureExpiry);
255 ore::data::EquityForward eqFwd(env, "Long", EquityUnderlying("zzzCorp"), "EUR", 1.0, f_exp_str, 0);
256
257 // Build and price
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 =
274 market->discountCurve("EUR", Market::defaultConfiguration);
275
276 Handle<YieldTermStructure> dividend = market->equityDividendCurve("zzzCorp", Market::defaultConfiguration);
277 Handle<YieldTermStructure> forecast = market->equityForecastCurve("zzzCorp", Market::defaultConfiguration);
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); // put-call parity check
290 BOOST_CHECK_CLOSE(npv_call_premium, put_premium_sum, 0.001); // put-call parity check
291
292 Settings::instance().evaluationDate() = today; // reset
293}
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
+ Here is the call graph for this function: