Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
vanillaoption.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file portfolio/builders/vanillaoption.hpp
20 \brief Abstract engine builders for European and American Options
21 \ingroup builders
22*/
23
24#pragma once
25
26#include <boost/make_shared.hpp>
32#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
33#include <ql/pricingengines/vanilla/fdblackscholesvanillaengine.hpp>
34#include <ql/processes/blackscholesprocess.hpp>
40
41namespace ore {
42namespace data {
43
44template <class T, typename... Args> class CachingOptionEngineBuilder : public CachingPricingEngineBuilder<T, Args...> {
45public:
46 CachingOptionEngineBuilder(const string& model, const string& engine, const set<string>& tradeTypes,
47 const AssetClass& assetClass)
48 : CachingPricingEngineBuilder<T, Args...>(model, engine, tradeTypes), assetClass_(assetClass) {}
49
50protected:
51 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> getBlackScholesProcess(const string& assetName,
52 const Currency& ccy,
53 const AssetClass& assetClassUnderlying,
54 const std::vector<Time>& timePoints = {},
55 const bool useFxSpot = true) {
56
59
60 if (assetClassUnderlying == AssetClass::EQ) {
61 Handle<BlackVolTermStructure> vol = this->market_->equityVol(assetName, config);
62 if (!timePoints.empty()) {
63 vol = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<VVTS>(vol, timePoints));
64 vol->enableExtrapolation();
65 }
66 return QuantLib::ext::make_shared<QuantLib::GeneralizedBlackScholesProcess>(
67 this->market_->equitySpot(assetName, config), this->market_->equityDividendCurve(assetName, config),
68 this->market_->equityForecastCurve(assetName, config), vol);
69
70 } else if (assetClassUnderlying == AssetClass::FX) {
71 const string& ccyPairCode = assetName + ccy.code();
72 Handle<BlackVolTermStructure> vol = this->market_->fxVol(ccyPairCode, config);
73 if (!timePoints.empty()) {
74 vol = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<VVTS>(vol, timePoints));
75 vol->enableExtrapolation();
76 }
77 if (useFxSpot) {
78 return QuantLib::ext::make_shared<QuantLib::GeneralizedBlackScholesProcess>(
79 this->market_->fxSpot(ccyPairCode, config), this->market_->discountCurve(assetName, config),
80 this->market_->discountCurve(ccy.code(), config), vol);
81 }
82 return QuantLib::ext::make_shared<QuantLib::GeneralizedBlackScholesProcess>(
83 this->market_->fxRate(ccyPairCode, config), this->market_->discountCurve(assetName, config),
84 this->market_->discountCurve(ccy.code(), config), vol);
85
86
87 } else if (assetClassUnderlying == AssetClass::COM) {
88
89 Handle<BlackVolTermStructure> vol = this->market_->commodityVolatility(assetName, config);
90 if (!timePoints.empty()) {
91 vol = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<VVTS>(vol, timePoints));
92 vol->enableExtrapolation();
93 }
94
95 // Create the commodity convenience yield curve for the process
96 Handle<QuantExt::PriceTermStructure> priceCurve = this->market_->commodityPriceCurve(assetName, config);
97 Handle<Quote> commoditySpot(QuantLib::ext::make_shared<QuantExt::DerivedPriceQuote>(priceCurve));
98 Handle<YieldTermStructure> discount = this->market_->discountCurve(ccy.code(), config);
99 Handle<YieldTermStructure> yield(
100 QuantLib::ext::make_shared<QuantExt::PriceTermStructureAdapter>(*priceCurve, *discount));
101 yield->enableExtrapolation();
102
103 return QuantLib::ext::make_shared<QuantLib::GeneralizedBlackScholesProcess>(commoditySpot, yield, discount, vol);
104
105 } else {
106 QL_FAIL("Asset class of " << (int)assetClassUnderlying << " not recognized.");
107 }
108 }
110};
111
112//! Abstract Engine Builder for Vanilla Options
113/*! Pricing engines are cached by asset/currency
114
115 \ingroup builders
116 */
118 : public CachingOptionEngineBuilder<string, const string&, const Currency&, const AssetClass&, const Date&, const bool> {
119public:
120 VanillaOptionEngineBuilder(const string& model, const string& engine, const set<string>& tradeTypes,
121 const AssetClass& assetClass, const Date& expiryDate)
122 : CachingOptionEngineBuilder(model, engine, tradeTypes, assetClass), expiryDate_(expiryDate) {}
123
124 QuantLib::ext::shared_ptr<PricingEngine> engine(const string& assetName, const Currency& ccy, const Date& expiryDate, const bool useFxSpot = true) {
125 return CachingPricingEngineBuilder<string, const string&, const Currency&, const AssetClass&,
126 const Date&, const bool>::engine(assetName, ccy, assetClass_, expiryDate, useFxSpot);
127 }
128
129 QuantLib::ext::shared_ptr<PricingEngine> engine(const Currency& ccy1, const Currency& ccy2, const Date& expiryDate,
130 const bool useFxSpot = true) {
131 return CachingPricingEngineBuilder<string, const string&, const Currency&, const AssetClass&,
132 const Date&, const bool>::engine(ccy1.code(), ccy2, assetClass_, expiryDate, useFxSpot);
133 }
134
135protected:
136 virtual string keyImpl(const string& assetName, const Currency& ccy, const AssetClass& assetClassUnderlying,
137 const Date& expiryDate, const bool useFxSpot) override {
138 return assetName + "/" + ccy.code() + "/" + to_string(expiryDate);
139 }
140
142};
143
144//! Abstract Engine Builder for European Vanilla Options
145/*! Pricing engines are cached by asset/currency
146
147 \ingroup builders
148 */
150public:
151 EuropeanOptionEngineBuilder(const string& model, const set<string>& tradeTypes, const AssetClass& assetClass)
152 : VanillaOptionEngineBuilder(model, "AnalyticEuropeanEngine", tradeTypes, assetClass, Date()) {}
153
154protected:
155 virtual QuantLib::ext::shared_ptr<PricingEngine> engineImpl(const string& assetName, const Currency& ccy,
156 const AssetClass& assetClassUnderlying,
157 const Date& expiryDate, const bool useFxSpot) override {
158 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> gbsp =
159 getBlackScholesProcess(assetName, ccy, assetClassUnderlying);
160 Handle<YieldTermStructure> discountCurve =
161 market_->discountCurve(ccy.code(), configuration(MarketContext::pricing));
162 return QuantLib::ext::make_shared<QuantLib::AnalyticEuropeanEngine>(gbsp, discountCurve);
163 }
164};
165
166//! Abstract Engine Builder for European Vanilla Forward Options
167/*! Pricing engines are cached by asset/currency
168
169 \ingroup builders
170 */
172public:
173 EuropeanForwardOptionEngineBuilder(const string& model, const set<string>& tradeTypes, const AssetClass& assetClass)
174 : VanillaOptionEngineBuilder(model, "AnalyticEuropeanForwardEngine", tradeTypes, assetClass, Date()) {}
175
176protected:
177 virtual QuantLib::ext::shared_ptr<PricingEngine> engineImpl(const string& assetName, const Currency& ccy,
178 const AssetClass& assetClassUnderlying, const Date& expiryDate,
179 const bool useFxSpot) override {
180 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> gbsp =
181 getBlackScholesProcess(assetName, ccy, assetClassUnderlying);
182 Handle<YieldTermStructure> discountCurve =
183 market_->discountCurve(ccy.code(), configuration(MarketContext::pricing));
184 return QuantLib::ext::make_shared<QuantExt::AnalyticEuropeanForwardEngine>(gbsp, discountCurve);
185 }
186};
187
188/*! European cash-settled option engine builder
189 \ingroup builders
190 */
192public:
193 EuropeanCSOptionEngineBuilder(const string& model, const set<string>& tradeTypes, const AssetClass& assetClass)
194 : VanillaOptionEngineBuilder(model, "AnalyticCashSettledEuropeanEngine", tradeTypes, assetClass, Date()) {}
195
196protected:
197 virtual QuantLib::ext::shared_ptr<PricingEngine> engineImpl(const string& assetName, const Currency& ccy,
198 const AssetClass& assetClassUnderlying, const Date& expiryDate,
199 const bool useFxSpot) override {
200 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> gbsp =
201 getBlackScholesProcess(assetName, ccy, assetClassUnderlying);
202 Handle<YieldTermStructure> discountCurve =
203 market_->discountCurve(ccy.code(), configuration(MarketContext::pricing));
204 return QuantLib::ext::make_shared<QuantExt::AnalyticCashSettledEuropeanEngine>(gbsp, discountCurve);
205 }
206};
207
208//! Abstract Engine Builder for American Vanilla Options
209/*! Pricing engines are cached by asset/currency
210
211 \ingroup builders
212 */
214public:
215 AmericanOptionEngineBuilder(const string& model, const string& engine, const set<string>& tradeTypes,
216 const AssetClass& assetClass, const Date& expiryDate)
217 : VanillaOptionEngineBuilder(model, engine, tradeTypes, assetClass, expiryDate) {}
218};
219
220//! Abstract Engine Builder for American Vanilla Options using Finite Difference Method
221/*! Pricing engines are cached by asset/currency
222
223 \ingroup builders
224 */
226public:
227 AmericanOptionFDEngineBuilder(const string& model, const set<string>& tradeTypes, const AssetClass& assetClass,
228 const Date& expiryDate)
229 : AmericanOptionEngineBuilder(model, "FdBlackScholesVanillaEngine", tradeTypes, assetClass, expiryDate) {}
230
231protected:
232 virtual QuantLib::ext::shared_ptr<PricingEngine> engineImpl(const string& assetName, const Currency& ccy,
233 const AssetClass& assetClass, const Date& expiryDate,
234 const bool useFxSpot) override {
235 // We follow the way FdBlackScholesBarrierEngine determines maturity for time grid generation
236 Handle<YieldTermStructure> riskFreeRate =
237 market_->discountCurve(ccy.code(), configuration(ore::data::MarketContext::pricing));
238 Time expiry = riskFreeRate->dayCounter().yearFraction(riskFreeRate->referenceDate(),
239 std::max(riskFreeRate->referenceDate(), expiryDate));
240
241 FdmSchemeDesc scheme = parseFdmSchemeDesc(engineParameter("Scheme"));
242 Size tGrid = (Size)(parseInteger(engineParameter("TimeGridPerYear")) * expiry);
243 Size xGrid = parseInteger(engineParameter("XGrid"));
244 Size dampingSteps = parseInteger(engineParameter("DampingSteps"));
245 bool monotoneVar = parseBool(engineParameter("EnforceMonotoneVariance", {}, false, "true"));
246 Size tGridMin = parseInteger(engineParameter("TimeGridMinimumSize", {}, false, "1"));
247 tGrid = std::max(tGridMin, tGrid);
248
249 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> gbsp;
250
251 if (monotoneVar) {
252 // Replicate the construction of time grid in FiniteDifferenceModel::rollbackImpl
253 // This time grid is required to build a BlackMonotoneVarVolTermStructure which
254 // ensures monotonic variance along the time grid
255 const Size totalSteps = tGrid + dampingSteps;
256 std::vector<Time> timePoints(totalSteps + 1);
257 Array timePointsArray(totalSteps, expiry, -expiry / totalSteps);
258 timePoints[0] = 0.0;
259 for (Size i = 0; i < totalSteps; i++)
260 timePoints[timePoints.size() - i - 1] = timePointsArray[i];
261 timePoints.insert(std::upper_bound(timePoints.begin(), timePoints.end(), 0.99 / 365), 0.99 / 365);
262 gbsp = getBlackScholesProcess(assetName, ccy, assetClass, timePoints);
263 } else {
264 gbsp = getBlackScholesProcess(assetName, ccy, assetClass);
265 }
266 return QuantLib::ext::make_shared<FdBlackScholesVanillaEngine>(gbsp, tGrid, xGrid, dampingSteps, scheme);
267 }
268};
269
270//! Abstract Engine Builder for American Vanilla Options using Barone Adesi Whaley Approximation
271/*! Pricing engines are cached by asset/currency
272
273 \ingroup builders
274 */
276public:
277 AmericanOptionBAWEngineBuilder(const string& model, const set<string>& tradeTypes, const AssetClass& assetClass)
278 : AmericanOptionEngineBuilder(model, "BaroneAdesiWhaleyApproximationEngine", tradeTypes, assetClass, Date()) {}
279
280protected:
281 virtual QuantLib::ext::shared_ptr<PricingEngine> engineImpl(const string& assetName, const Currency& ccy,
282 const AssetClass& assetClass, const Date& expiryDate,
283 const bool useFxSpot) override {
284 QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> gbsp = getBlackScholesProcess(assetName, ccy, assetClass);
285 return QuantLib::ext::make_shared<QuantExt::BaroneAdesiWhaleyApproximationEngine>(gbsp);
286 }
287};
288
289} // namespace data
290} // namespace ore
Abstract template engine builder class.
Abstract Engine Builder for American Vanilla Options using Barone Adesi Whaley Approximation.
AmericanOptionBAWEngineBuilder(const string &model, const set< string > &tradeTypes, const AssetClass &assetClass)
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClass, const Date &expiryDate, const bool useFxSpot) override
Abstract Engine Builder for American Vanilla Options.
AmericanOptionEngineBuilder(const string &model, const string &engine, const set< string > &tradeTypes, const AssetClass &assetClass, const Date &expiryDate)
Abstract Engine Builder for American Vanilla Options using Finite Difference Method.
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClass, const Date &expiryDate, const bool useFxSpot) override
AmericanOptionFDEngineBuilder(const string &model, const set< string > &tradeTypes, const AssetClass &assetClass, const Date &expiryDate)
Abstract template EngineBuilder class that can cache engines and coupon pricers.
QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > getBlackScholesProcess(const string &assetName, const Currency &ccy, const AssetClass &assetClassUnderlying, const std::vector< Time > &timePoints={}, const bool useFxSpot=true)
CachingOptionEngineBuilder(const string &model, const string &engine, const set< string > &tradeTypes, const AssetClass &assetClass)
QuantLib::ext::shared_ptr< Market > market_
const string & engine() const
Return the engine name.
const set< string > & tradeTypes() const
Return the possible trade types.
const string & model() const
Return the model name.
std::string engineParameter(const std::string &p, const std::vector< std::string > &qualifiers={}, const bool mandatory=true, const std::string &defaultValue="") const
const string & configuration(const MarketContext &key)
Return a configuration (or the default one if key not found)
EuropeanCSOptionEngineBuilder(const string &model, const set< string > &tradeTypes, const AssetClass &assetClass)
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClassUnderlying, const Date &expiryDate, const bool useFxSpot) override
Abstract Engine Builder for European Vanilla Forward Options.
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClassUnderlying, const Date &expiryDate, const bool useFxSpot) override
EuropeanForwardOptionEngineBuilder(const string &model, const set< string > &tradeTypes, const AssetClass &assetClass)
Abstract Engine Builder for European Vanilla Options.
virtual QuantLib::ext::shared_ptr< PricingEngine > engineImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClassUnderlying, const Date &expiryDate, const bool useFxSpot) override
EuropeanOptionEngineBuilder(const string &model, const set< string > &tradeTypes, const AssetClass &assetClass)
Abstract Engine Builder for Vanilla Options.
QuantLib::ext::shared_ptr< PricingEngine > engine(const string &assetName, const Currency &ccy, const Date &expiryDate, const bool useFxSpot=true)
VanillaOptionEngineBuilder(const string &model, const string &engine, const set< string > &tradeTypes, const AssetClass &assetClass, const Date &expiryDate)
QuantLib::ext::shared_ptr< PricingEngine > engine(const Currency &ccy1, const Currency &ccy2, const Date &expiryDate, const bool useFxSpot=true)
virtual string keyImpl(const string &assetName, const Currency &ccy, const AssetClass &assetClassUnderlying, const Date &expiryDate, const bool useFxSpot) override
Pricing Engine Factory.
bool parseBool(const string &s)
Convert text to bool.
Definition: parsers.cpp:144
FdmSchemeDesc parseFdmSchemeDesc(const std::string &s)
Convert string to fdm scheme desc.
Definition: parsers.cpp:692
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
Definition: parsers.cpp:136
Map text representations to QuantLib/QuantExt types.
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
Serializable Credit Default Swap.
Definition: namespaces.docs:23
string conversion utilities