Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | List of all members
VanillaOptionTrade Class Reference

Serializable Vanilla Option. More...

#include <ored/portfolio/vanillaoption.hpp>

+ Inheritance diagram for VanillaOptionTrade:
+ Collaboration diagram for VanillaOptionTrade:

Public Member Functions

void build (const QuantLib::ext::shared_ptr< EngineFactory > &) override
 Build QuantLib/QuantExt instrument, link pricing engine. More...
 
void setNotionalAndCurrencies ()
 
- Public Member Functions inherited from Trade
 Trade ()
 Default constructor. More...
 
 Trade (const string &tradeType, const Envelope &env=Envelope(), const TradeActions &ta=TradeActions())
 Base class constructor. More...
 
virtual ~Trade ()
 Default destructor. More...
 
virtual void build (const QuantLib::ext::shared_ptr< EngineFactory > &)=0
 
virtual std::map< std::string, RequiredFixings::FixingDatesfixings (const QuantLib::Date &settlementDate=QuantLib::Date()) const
 
const RequiredFixingsrequiredFixings () const
 
virtual std::map< AssetClass, std::set< std::string > > underlyingIndices (const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const
 
virtual void fromXML (XMLNode *node) override
 
virtual XMLNodetoXML (XMLDocument &doc) const override
 
void reset ()
 Reset trade, clear all base class data. This does not reset accumulated timings for this trade. More...
 
void resetPricingStats (const std::size_t numberOfPricings=0, const boost::timer::nanosecond_type cumulativePricingTime=0)
 Reset accumulated timings to given values. More...
 
string & id ()
 Set the trade id. More...
 
void setEnvelope (const Envelope &envelope)
 Set the envelope with counterparty and portfolio info. More...
 
void setAdditionalData (const std::map< std::string, boost::any > &additionalData)
 
TradeActionstradeActions ()
 Set the trade actions. More...
 
const string & id () const
 
const string & tradeType () const
 
const Envelopeenvelope () const
 
const set< string > & portfolioIds () const
 
const TradeActionstradeActions () const
 
const QuantLib::ext::shared_ptr< InstrumentWrapper > & instrument () const
 
const std::vector< QuantLib::Leg > & legs () const
 
const std::vector< string > & legCurrencies () const
 
const std::vector< bool > & legPayers () const
 
const string & npvCurrency () const
 
virtual QuantLib::Real notional () const
 Return the current notional in npvCurrency. See individual sub-classes for the precise definition. More...
 
virtual string notionalCurrency () const
 
const Date & maturity () const
 
virtual bool isExpired (const Date &d)
 
const string & issuer () const
 
template<typename T >
additionalDatum (const std::string &tag) const
 returns any additional datum. More...
 
virtual const std::map< std::string, boost::any > & additionalData () const
 returns all additional data returned by the trade once built More...
 
const std::string & sensitivityTemplate () const
 
void validate () const
 Utility to validate that everything that needs to be set in this base class is actually set. More...
 
virtual bool hasCashflows () const
 
boost::timer::nanosecond_type getCumulativePricingTime () const
 Get cumulative timing spent on pricing. More...
 
std::size_t getNumberOfPricings () const
 Get number of pricings. More...
 
- Public Member Functions inherited from XMLSerializable
virtual ~XMLSerializable ()
 
virtual void fromXML (XMLNode *node)=0
 
virtual XMLNodetoXML (XMLDocument &doc) const =0
 
void fromFile (const std::string &filename)
 
void toFile (const std::string &filename) const
 
void fromXMLString (const std::string &xml)
 Parse from XML string. More...
 
std::string toXMLString () const
 Parse from XML string. More...
 

Inspectors

AssetClass assetClassUnderlying_
 
OptionData option_
 
string assetName_
 
string currency_
 
Currency underlyingCurrency_
 
double quantity_
 
TradeStrike strike_
 
QuantLib::ext::shared_ptr< QuantLib::Index > index_
 An index is needed if the option is to be automatically exercised on expiry. More...
 
std::string indexName_
 Hold the external index name if needed e.g. in the case of an FX index. More...
 
QuantLib::Date expiryDate_
 Store the option expiry date. More...
 
QuantLib::Date forwardDate_
 Store the (optional) forward date. More...
 
QuantLib::Date paymentDate_
 Store the (optional) payment date. More...
 
const OptionDataoption () const
 
const string & asset () const
 
const string & currency () const
 
TradeStrike strike () const
 
double quantity () const
 
const QuantLib::Date forwardDate () const
 
const QuantLib::Date paymentDate () const
 
 VanillaOptionTrade (AssetClass assetClassUnderlying)
 
 VanillaOptionTrade (const Envelope &env, AssetClass assetClassUnderlying, OptionData option, string assetName, string currency, double quantity, TradeStrike strike, const QuantLib::ext::shared_ptr< QuantLib::Index > &index=nullptr, const std::string &indexName="", QuantLib::Date forwardDate=QuantLib::Date())
 

Additional Inherited Members

- Protected Member Functions inherited from Trade
Date addPremiums (std::vector< QuantLib::ext::shared_ptr< Instrument > > &instruments, std::vector< Real > &multipliers, const Real tradeMultiplier, const PremiumData &premiumData, const Real premiumMultiplier, const Currency &tradeCurrency, const QuantLib::ext::shared_ptr< EngineFactory > &factory, const string &configuration)
 
void setLegBasedAdditionalData (const Size legNo, Size resultLegId=Null< Size >()) const
 
void setSensitivityTemplate (const EngineBuilder &builder)
 
void setSensitivityTemplate (const std::string &id)
 
- Protected Attributes inherited from Trade
string tradeType_
 
QuantLib::ext::shared_ptr< InstrumentWrapperinstrument_
 
std::vector< QuantLib::Leg > legs_
 
std::vector< string > legCurrencies_
 
std::vector< boollegPayers_
 
string npvCurrency_
 
QuantLib::Real notional_
 
string notionalCurrency_
 
Date maturity_
 
string issuer_
 
string sensitivityTemplate_
 
bool sensitivityTemplateSet_ = false
 
std::size_t savedNumberOfPricings_ = 0
 
boost::timer::nanosecond_type savedCumulativePricingTime_ = 0
 
RequiredFixings requiredFixings_
 
std::map< std::string, boost::any > additionalData_
 

Detailed Description

Serializable Vanilla Option.

Definition at line 39 of file vanillaoption.hpp.

Constructor & Destructor Documentation

◆ VanillaOptionTrade() [1/2]

VanillaOptionTrade ( AssetClass  assetClassUnderlying)
protected

Definition at line 57 of file vanillaoption.hpp.

58 : Trade("VanillaOption"), assetClassUnderlying_(assetClassUnderlying), quantity_(0) {}
Trade()
Default constructor.
Definition: trade.hpp:59

◆ VanillaOptionTrade() [2/2]

VanillaOptionTrade ( const Envelope env,
AssetClass  assetClassUnderlying,
OptionData  option,
string  assetName,
string  currency,
double  quantity,
TradeStrike  strike,
const QuantLib::ext::shared_ptr< QuantLib::Index > &  index = nullptr,
const std::string &  indexName = "",
QuantLib::Date  forwardDate = QuantLib::Date() 
)
protected

Definition at line 59 of file vanillaoption.hpp.

63 : Trade("VanillaOption", env), assetClassUnderlying_(assetClassUnderlying), option_(option),
65 indexName_(indexName), forwardDate_(forwardDate) {}
const string & currency() const
const OptionData & option() const
TradeStrike strike() const
const QuantLib::Date forwardDate() const
QuantLib::Date forwardDate_
Store the (optional) forward date.
std::string indexName_
Hold the external index name if needed e.g. in the case of an FX index.
QuantLib::ext::shared_ptr< QuantLib::Index > index_
An index is needed if the option is to be automatically exercised on expiry.

Member Function Documentation

◆ build()

void build ( const QuantLib::ext::shared_ptr< EngineFactory > &  )
overridevirtual

Build QuantLib/QuantExt instrument, link pricing engine.

Implements Trade.

Definition at line 39 of file vanillaoption.cpp.

39 {
41
42 QL_REQUIRE(tradeActions().empty(), "TradeActions not supported for VanillaOption");
43
44 // If underlying currency is empty, then set to payment currency by default.
45 // If non-empty, then check if the currencies are different for a Quanto payoff
46 Currency ccy = parseCurrencyWithMinors(currency_);
47 Currency underlyingCurrency = underlyingCurrency_.empty() ? ccy : underlyingCurrency_;
48 bool sameCcy = underlyingCurrency == ccy;
49
50 if (strike_.currency().empty())
51 strike_.setCurrency(ccy.code());
52
53 // Payoff
54 Option::Type type = parseOptionType(option_.callPut());
55 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, strike_.value()));
56 QuantLib::Exercise::Type exerciseType = parseExerciseType(option_.style());
57 QL_REQUIRE(option_.exerciseDates().size() == 1, "Invalid number of exercise dates");
59 // Set the maturity date equal to the expiry date. It may get updated below if option is cash settled with
60 // payment after expiry.
62 // Exercise
63 QuantLib::ext::shared_ptr<Exercise> exercise;
64 switch (exerciseType) {
65 case QuantLib::Exercise::Type::European: {
66 exercise = QuantLib::ext::make_shared<EuropeanExercise>(expiryDate_);
67 break;
68 }
69 case QuantLib::Exercise::Type::American: {
70 exercise = QuantLib::ext::make_shared<AmericanExercise>(expiryDate_, option_.payoffAtExpiry());
71 break;
72 }
73 default:
74 QL_FAIL("Option Style " << option_.style() << " is not supported");
75 }
76 // Create the instrument and then populate the name for the engine builder.
77 QuantLib::ext::shared_ptr<Instrument> vanilla;
78 string tradeTypeBuilder = tradeType_;
79 Settlement::Type settlementType = parseSettlementType(option_.settlement());
80
81 // For Quanto, check for European and Cash, except for an FX underlying
82 if (!sameCcy) {
83 QL_REQUIRE(exerciseType == Exercise::Type::European, "Option exercise must be European for a Quanto payoff.");
84 if (settlementType == Settlement::Type::Physical) {
86 "Physically settled Quanto options are allowed only for an FX underlying.");
87 }
88 }
89
90 if (exerciseType == Exercise::European && settlementType == Settlement::Cash) {
91 // We have a European cash settled option.
92
93 // Get the payment date.
94 const boost::optional<OptionPaymentData>& opd = option_.paymentData();
96 if (opd) {
97 if (opd->rulesBased()) {
98 const Calendar& cal = opd->calendar();
99 QL_REQUIRE(cal != Calendar(), "Need a non-empty calendar for rules based payment date.");
100 paymentDate = cal.advance(expiryDate_, opd->lag(), Days, opd->convention());
101 } else {
102 const vector<Date>& dates = opd->dates();
103 QL_REQUIRE(dates.size() == 1, "Need exactly one payment date for cash settled European option.");
104 paymentDate = dates[0];
105 }
106 QL_REQUIRE(paymentDate >= expiryDate_, "Payment date must be greater than or equal to expiry date.");
107 }
108
109 if (paymentDate > expiryDate_) {
110 QL_REQUIRE(sameCcy, "Payment date must equal expiry date for a Quanto payoff. Trade: " << id() << ".");
111
112 // Build a QuantExt::CashSettledEuropeanOption if payment date is strictly greater than expiry.
113
114 // Has the option been marked as exercised
115 const boost::optional<OptionExerciseData>& oed = option_.exerciseData();
116 bool exercised = false;
117 Real exercisePrice = Null<Real>();
118 if (oed) {
119 QL_REQUIRE(oed->date() == expiryDate_, "The supplied exercise date ("
120 << io::iso_date(oed->date())
121 << ") should equal the option's expiry date ("
122 << io::iso_date(expiryDate_) << ").");
123 exercised = true;
124 exercisePrice = oed->price();
125 }
126
127 // If automatic exercise, we will need an index fixing on the expiry date.
129 QL_REQUIRE(index_, "Option trade " << id() << " has automatic exercise so we need a valid index.");
130 // If index name has not been populated, use logic here to populate it from the index object.
131 string indexName = indexName_;
132 if (indexName.empty()) {
133 indexName = index_->name();
135 indexName = "EQ-" + indexName;
136 }
138 }
139
140 // Build the instrument
141 LOG("Build CashSettledEuropeanOption for trade " << id());
142 vanilla = QuantLib::ext::make_shared<CashSettledEuropeanOption>(
143 type, strike_.value(), expiryDate_, paymentDate, option_.isAutomaticExercise(), index_, exercised, exercisePrice);
144
145 // Allow for a separate pricing engine that takes care of payment on a date after expiry. Do this by
146 // appending 'EuropeanCS' to the trade type.
147 tradeTypeBuilder = tradeType_ + "EuropeanCS";
148
149 // Update the maturity date.
151
152 } else {
153 if (forwardDate_ == QuantLib::Date()) {
154 // If payment date is not greater than expiry, build QuantLib::VanillaOption.
155 if (sameCcy) {
156 LOG("Build VanillaOption for trade " << id());
157 vanilla = QuantLib::ext::make_shared<QuantLib::VanillaOption>(payoff, exercise);
158 }
159 else {
160 LOG("Build QuantoVanillaOption for trade " << id());
161 vanilla = QuantLib::ext::make_shared<QuantLib::QuantoVanillaOption>(payoff, exercise);
163 tradeTypeBuilder = "QuantoEquityOption";
165 tradeTypeBuilder = "QuantoCommodityOption";
166 else
167 QL_FAIL("Option Quanto payoff not supported for " << assetClassUnderlying_ << " class.");
168 }
169 } else {
170 LOG("Build VanillaForwardOption for trade " << id());
171 QL_REQUIRE(sameCcy, "Quanto payoff is not currently supported for Forward Options: Trade " << id());
172 vanilla = QuantLib::ext::make_shared<QuantExt::VanillaForwardOption>(payoff, exercise, forwardDate_);
174 tradeTypeBuilder = tradeType_ + "Forward";
175 }
176 }
177
178 } else {
179 if (forwardDate_ == QuantLib::Date()) {
180 // If not European or not cash settled, build QuantLib::VanillaOption.
181 if (sameCcy) {
182 LOG("Build VanillaOption for trade " << id());
183 vanilla = QuantLib::ext::make_shared<QuantLib::VanillaOption>(payoff, exercise);
184 } else {
185 LOG("Build QuantoVanillaOption for trade " << id());
186 vanilla = QuantLib::ext::make_shared<QuantLib::QuantoVanillaOption>(payoff, exercise);
187 }
188 } else {
189 QL_REQUIRE(exerciseType == QuantLib::Exercise::Type::European, "Only European Forward Options currently supported");
190 LOG("Built VanillaForwardOption for trade " << id());
191 vanilla = QuantLib::ext::make_shared<QuantExt::VanillaForwardOption>(payoff, exercise, forwardDate_, paymentDate_);
193 tradeTypeBuilder = tradeType_ + "Forward";
194 }
195
196 // If the tradeTypeBuilder has not been modified yet..
197 if (tradeTypeBuilder == tradeType_) {
198 if (sameCcy)
199 tradeTypeBuilder = tradeType_ + (exerciseType == QuantLib::Exercise::Type::European ? "" : "American");
200 else
201 tradeTypeBuilder = "QuantoFxOption";
202 }
203 }
204 LOG("tradeTypeBuilder set to " << tradeTypeBuilder << " for trade " << id());
205
206 // Generally we need to set the pricing engine here even if the option is expired at build time, since the valuation date
207 // might change after build, and we get errors for the edge case valuation date = expiry date for European options.
208 string configuration = Market::defaultConfiguration;
209 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(tradeTypeBuilder);
210 QL_REQUIRE(builder, "No builder found for " << tradeTypeBuilder);
211
212 if (sameCcy) {
213 QuantLib::ext::shared_ptr<VanillaOptionEngineBuilder> vanillaOptionBuilder =
214 QuantLib::ext::dynamic_pointer_cast<VanillaOptionEngineBuilder>(builder);
215 QL_REQUIRE(vanillaOptionBuilder != nullptr, "No engine builder found for trade type " << tradeTypeBuilder);
216
217 if (forwardDate_ != Date()) {
218 vanilla->setPricingEngine(vanillaOptionBuilder->engine(assetName_, ccy, expiryDate_, false));
219 } else {
220 vanilla->setPricingEngine(vanillaOptionBuilder->engine(assetName_, ccy, expiryDate_, true));
221 }
222 setSensitivityTemplate(*vanillaOptionBuilder);
223
224 configuration = vanillaOptionBuilder->configuration(MarketContext::pricing);
225 } else {
226 QuantLib::ext::shared_ptr<QuantoVanillaOptionEngineBuilder> quantoVanillaOptionBuilder =
227 QuantLib::ext::dynamic_pointer_cast<QuantoVanillaOptionEngineBuilder>(builder);
228 QL_REQUIRE(quantoVanillaOptionBuilder != nullptr, "No (Quanto) engine builder found for trade type "
229 << tradeTypeBuilder);
230
231 vanilla->setPricingEngine(quantoVanillaOptionBuilder->engine(assetName_, underlyingCurrency, ccy, expiryDate_));
232 setSensitivityTemplate(*quantoVanillaOptionBuilder);
233
234 configuration = quantoVanillaOptionBuilder->configuration(MarketContext::pricing);
235 }
236
237 Position::Type positionType = parsePositionType(option_.longShort());
238 Real bsInd = (positionType == QuantLib::Position::Long ? 1.0 : -1.0);
239 Real mult = quantity_ * bsInd;
240
241 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
242 std::vector<Real> additionalMultipliers;
243 maturity_ = std::max(maturity_, addPremiums(additionalInstruments, additionalMultipliers, mult,
244 option_.premiumData(), -bsInd, ccy, engineFactory, configuration));
245
246 instrument_ = QuantLib::ext::shared_ptr<InstrumentWrapper>(
247 new VanillaInstrument(vanilla, mult, additionalInstruments, additionalMultipliers));
248}
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
const string & callPut() const
Definition: optiondata.hpp:71
const string & longShort() const
Definition: optiondata.hpp:70
const string & style() const
Definition: optiondata.hpp:74
const string & settlement() const
Definition: optiondata.hpp:81
const bool & payoffAtExpiry() const
Definition: optiondata.hpp:75
bool isAutomaticExercise() const
Automatic exercise assumed false if not explicitly provided.
Definition: optiondata.hpp:117
const boost::optional< OptionPaymentData > & paymentData() const
Definition: optiondata.hpp:93
const boost::optional< OptionExerciseData > & exerciseData() const
Definition: optiondata.hpp:92
const PremiumData & premiumData() const
Definition: optiondata.hpp:83
const vector< string > & exerciseDates() const
Definition: optiondata.hpp:76
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
TradeActions & tradeActions()
Set the trade actions.
Definition: trade.hpp:126
Date addPremiums(std::vector< QuantLib::ext::shared_ptr< Instrument > > &instruments, std::vector< Real > &multipliers, const Real tradeMultiplier, const PremiumData &premiumData, const Real premiumMultiplier, const Currency &tradeCurrency, const QuantLib::ext::shared_ptr< EngineFactory > &factory, const string &configuration)
Definition: trade.cpp:58
void setSensitivityTemplate(const EngineBuilder &builder)
Definition: trade.cpp:295
string tradeType_
Definition: trade.hpp:196
RequiredFixings requiredFixings_
Definition: trade.hpp:223
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
Definition: trade.hpp:197
void setCurrency(const std::string &currency)
std::string currency()
QuantLib::Real value() const
QuantLib::Date expiryDate_
Store the option expiry date.
QuantLib::Date paymentDate_
Store the (optional) payment date.
const QuantLib::Date paymentDate() const
Exercise::Type parseExerciseType(const std::string &s)
Convert text to QuantLib::Exercise::Type.
Definition: parsers.cpp:466
Currency parseCurrencyWithMinors(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:310
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Definition: parsers.cpp:404
Settlement::Type parseSettlementType(const std::string &s)
Convert text to QuantLib::Settlement::Type.
Definition: parsers.cpp:434
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
Definition: parsers.cpp:481
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setNotionalAndCurrencies()

void setNotionalAndCurrencies ( )

Definition at line 250 of file vanillaoption.cpp.

250 {
251 Currency ccy = parseCurrencyWithMinors(currency_);
252 npvCurrency_ = ccy.code();
253
254 // Notional - we really need todays spot to get the correct notional.
255 // But rather than having it move around we use strike * quantity
257 // the following is correct for vanilla (sameCcy = true) and quanto (sameCcy = false)
258 notionalCurrency_ = ccy.code();
259}
string npvCurrency_
Definition: trade.hpp:201
QuantLib::Real notional_
Definition: trade.hpp:202
string notionalCurrency_
Definition: trade.hpp:203
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ option()

const OptionData & option ( ) const

Definition at line 47 of file vanillaoption.hpp.

47{ return option_; }

◆ asset()

const string & asset ( ) const

Definition at line 48 of file vanillaoption.hpp.

48{ return assetName_; }

◆ currency()

const string & currency ( ) const

Definition at line 49 of file vanillaoption.hpp.

49{ return currency_; }

◆ strike()

TradeStrike strike ( ) const

Definition at line 50 of file vanillaoption.hpp.

50{ return strike_; }

◆ quantity()

double quantity ( ) const

Definition at line 51 of file vanillaoption.hpp.

51{ return quantity_; }

◆ forwardDate()

const QuantLib::Date forwardDate ( ) const

Definition at line 52 of file vanillaoption.hpp.

52{ return forwardDate_; }

◆ paymentDate()

const QuantLib::Date paymentDate ( ) const

Definition at line 53 of file vanillaoption.hpp.

53{ return paymentDate_; }
+ Here is the caller graph for this function:

Member Data Documentation

◆ assetClassUnderlying_

AssetClass assetClassUnderlying_
protected

Definition at line 67 of file vanillaoption.hpp.

◆ option_

OptionData option_
protected

Definition at line 68 of file vanillaoption.hpp.

◆ assetName_

string assetName_
protected

Definition at line 69 of file vanillaoption.hpp.

◆ currency_

string currency_
protected

Definition at line 70 of file vanillaoption.hpp.

◆ underlyingCurrency_

Currency underlyingCurrency_
protected

Definition at line 71 of file vanillaoption.hpp.

◆ quantity_

double quantity_
protected

Definition at line 72 of file vanillaoption.hpp.

◆ strike_

TradeStrike strike_
protected

Definition at line 73 of file vanillaoption.hpp.

◆ index_

QuantLib::ext::shared_ptr<QuantLib::Index> index_
protected

An index is needed if the option is to be automatically exercised on expiry.

Definition at line 76 of file vanillaoption.hpp.

◆ indexName_

std::string indexName_
protected

Hold the external index name if needed e.g. in the case of an FX index.

Definition at line 79 of file vanillaoption.hpp.

◆ expiryDate_

QuantLib::Date expiryDate_
protected

Store the option expiry date.

Definition at line 82 of file vanillaoption.hpp.

◆ forwardDate_

QuantLib::Date forwardDate_
protected

Store the (optional) forward date.

Definition at line 85 of file vanillaoption.hpp.

◆ paymentDate_

QuantLib::Date paymentDate_
protected

Store the (optional) payment date.

Definition at line 88 of file vanillaoption.hpp.