Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cliquetoption.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 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 ORE is free software: you can redistribute it and/or modify it
8 under the terms of the Modified BSD License. You should have received a
9 copy of the license along with this program.
10
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
22
24
25using namespace ore::data;
26using namespace QuantLib;
27using namespace std;
28
29namespace {
30
31Real getRealOrNull(XMLNode* node, const string& name) {
32 string tmp = XMLUtils::getChildValue(node, name, false);
33 if (tmp == "")
34 return Null<Real>();
35 else
36 return parseReal(tmp);
37}
38
39} // anonymous namespace
40
41namespace ore {
42namespace data {
43
44void CliquetOption::build(const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
45
46 // ISDA taxonomy
47 if (underlying_->type() == "Equity") {
48 additionalData_["isdaAssetClass"] = string("Equity");
49 additionalData_["isdaBaseProduct"] = string("Other");
50 additionalData_["isdaSubProduct"] = string("Price Return Basic Performance");
51 } else if (underlying_->type() == "Commodity") {
52 // assuming that Commoditiy is treated like Equity
53 additionalData_["isdaAssetClass"] = string("Commodity");
54 additionalData_["isdaBaseProduct"] = string("Other");
55 additionalData_["isdaSubProduct"] = string("Price Return Basic Performance");
56 } else if (underlying_->type() == "FX") {
57 additionalData_["isdaAssetClass"] = string("Foreign Exchange");
58 additionalData_["isdaBaseProduct"] = string("Complex Exotic");
59 additionalData_["isdaSubProduct"] = string("Generic");
60 } else {
61 WLOG("ISDA taxonomy not set for trade " << id());
62 }
63
64 additionalData_["isdaTransaction"] = string("");
65
66 Currency ccy = parseCurrency(currency_);
67
68 QL_REQUIRE(tradeActions().empty(), "TradeActions not supported for VanillaOption");
69
70 // Payoff
71 Option::Type type = parseOptionType(callPut_);
72 QuantLib::ext::shared_ptr<PercentageStrikePayoff> payoff = QuantLib::ext::make_shared<PercentageStrikePayoff>(type, moneyness_);
73
74 Schedule schedule;
75 schedule = makeSchedule(scheduleData_);
76 Date expiryDate = schedule.dates().back();
77
78 // Vanilla European/American.
79 // If price adjustment is necessary we build a simple EU Option
80 QuantLib::ext::shared_ptr<QuantLib::Instrument> instrument;
81 QuantLib::ext::shared_ptr<EuropeanExercise> exerciseDate = QuantLib::ext::make_shared<EuropeanExercise>(expiryDate);
82
83 Date paymentDate = schedule.calendar().advance(expiryDate, settlementDays_, Days);
84
85 for (auto d : schedule.dates())
86 valuationDates_.insert(schedule.calendar().adjust(d, schedule.businessDayConvention()));
87
88 Position::Type position = parsePositionType(longShort_);
89
90 // Create QuantExt Cliquet Option
91 QuantLib::ext::shared_ptr<Instrument> cliquet = QuantLib::ext::make_shared<QuantExt::CliquetOption>(
92 payoff, exerciseDate, valuationDates_, paymentDate, cliquetNotional_, position, localCap_, localFloor_,
94
95 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(tradeType_);
96 QL_REQUIRE(builder, "No builder found for " << tradeType_);
97 QuantLib::ext::shared_ptr<CliquetOptionEngineBuilder> cliquetOptionBuilder =
98 QuantLib::ext::dynamic_pointer_cast<CliquetOptionEngineBuilder>(builder);
99
100 cliquet->setPricingEngine(cliquetOptionBuilder->engine(name(), ccy));
101 setSensitivityTemplate(*cliquetOptionBuilder);
102
103 instrument_ = QuantLib::ext::shared_ptr<InstrumentWrapper>(new VanillaInstrument(cliquet));
104
105 npvCurrency_ = currency_;
106 maturity_ = expiryDate;
107 notional_ = cliquetNotional_;
108 notionalCurrency_ = currency_;
109
110 // add required fixings (all valuation dates)
111 for (auto const& d : valuationDates_) {
112 requiredFixings_.addFixingDate(d, "EQ-" + name(), paymentDate);
113 }
114
115 additionalData_["notional"] = cliquetNotional_;
116}
117
119 Trade::fromXML(node);
120
121 XMLNode* clNode = XMLUtils::getChildNode(node, tradeType() + "Data");
122 QL_REQUIRE(clNode, "No EquityCliquetOptionData Node");
123
124 XMLNode* tmp = XMLUtils::getChildNode(clNode, "Underlying");
125 if (!tmp)
126 tmp = XMLUtils::getChildNode(node, "Name");
127 UnderlyingBuilder underlyingBuilder;
128 underlyingBuilder.fromXML(tmp);
129 underlying_ = underlyingBuilder.underlying();
130
131 currency_ = XMLUtils::getChildValue(clNode, "Currency", true);
132 cliquetNotional_ = XMLUtils::getChildValueAsDouble(clNode, "Notional", true);
133 longShort_ = XMLUtils::getChildValue(clNode, "LongShort", true);
134 callPut_ = XMLUtils::getChildValue(clNode, "OptionType", true);
135 XMLNode* scheduleNode = XMLUtils::getChildNode(clNode, "ScheduleData");
136 scheduleData_.fromXML(scheduleNode);
137 moneyness_ = XMLUtils::getChildValueAsDouble(clNode, "Moneyness", false);
138 localCap_ = getRealOrNull(clNode, "LocalCap");
139 localFloor_ = getRealOrNull(clNode, "LocalFloor");
140 globalCap_ = getRealOrNull(clNode, "GlobalCap");
141 globalFloor_ = getRealOrNull(clNode, "GlobalFloor");
142 settlementDays_ = XMLUtils::getChildValueAsInt(clNode, "SettlementDays", false);
143 premium_ = XMLUtils::getChildValueAsDouble(clNode, "Premium", false);
144 premiumCcy_ = XMLUtils::getChildValue(clNode, "PremiumCurrency", false);
145 premiumPayDate_ = XMLUtils::getChildValue(clNode, "PremiumPaymentDate", false);
146}
147
149 XMLNode* node = Trade::toXML(doc);
150 XMLNode* clNode = doc.allocNode(tradeType() + "Data");
151 XMLUtils::appendNode(node, clNode);
152 XMLUtils::appendNode(clNode, underlying_->toXML(doc));
153 XMLUtils::addChild(doc, clNode, "Currency", currency_);
154 XMLUtils::addChild(doc, clNode, "Notional", cliquetNotional_);
155 XMLUtils::addChild(doc, clNode, "LongShort", longShort_);
156 XMLUtils::addChild(doc, clNode, "OptionType", callPut_);
157 XMLUtils::appendNode(clNode, scheduleData_.toXML(doc));
158 if (moneyness_ != Null<Real>())
159 XMLUtils::addChild(doc, clNode, "Moneyness", moneyness_);
160 if (localCap_ != Null<Real>())
161 XMLUtils::addChild(doc, clNode, "LocalCap", localCap_);
162 if (localFloor_ != Null<Real>())
163 XMLUtils::addChild(doc, clNode, "LocalFloor", localFloor_);
164 if (globalCap_ != Null<Real>())
165 XMLUtils::addChild(doc, clNode, "GlobalCap", globalCap_);
166 if (globalFloor_ != Null<Real>())
167 XMLUtils::addChild(doc, clNode, "GlobalFloor", globalFloor_);
168 if (settlementDays_ != Null<Size>())
169 XMLUtils::addChild(doc, clNode, "SettlementDays", static_cast<int>(settlementDays_));
170 if (premium_ != Null<Real>())
171 XMLUtils::addChild(doc, clNode, "Premium", premium_);
172 if (premiumCcy_ != "")
173 XMLUtils::addChild(doc, clNode, "PremiumCurrency", premiumCcy_);
174 if (premiumPayDate_ != "")
175 XMLUtils::addChild(doc, clNode, "PremiumPaymentDate", premiumPayDate_);
176 return node;
177}
178
179} // namespace data
180} // namespace ore
Engine builder for cliquet options.
const Position::Type longShort_
const std::set< Date > valuationDates_
virtual void fromXML(ore::data::XMLNode *node) override
virtual ore::data::XMLNode * toXML(ore::data::XMLDocument &doc) const override
void build(const QuantLib::ext::shared_ptr< ore::data::EngineFactory > &) override
Build QuantLib/QuantExt instrument, link pricing engine.
virtual void fromXML(XMLNode *node) override
Definition: trade.cpp:34
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: trade.cpp:46
const QuantLib::ext::shared_ptr< Underlying > & underlying()
Definition: underlying.hpp:266
void fromXML(XMLNode *node) override
Definition: underlying.cpp:305
Vanilla Instrument Wrapper.
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
Definition: xmlutils.cpp:286
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static int getChildValueAsInt(XMLNode *node, const string &name, bool mandatory=false, int defaultValue=0)
Definition: xmlutils.cpp:291
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static void appendNode(XMLNode *parent, XMLNode *child)
Definition: xmlutils.cpp:406
Equity Cliquet Option.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
Definition: parsers.cpp:404
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
Definition: parsers.cpp:481
@ data
Definition: log.hpp:77
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
Schedule makeSchedule(const ScheduleDates &data)
Definition: schedule.cpp:263
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Reference data model and serialization.
string name