28#include <ql/errors.hpp>
29#include <ql/instruments/asianoption.hpp>
30#include <ql/instruments/averagetype.hpp>
41 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
50 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
53 WLOG(
"ISDA taxonomy not set for trade " <<
id());
59 QL_REQUIRE(
tradeActions().empty(),
"TradeActions not supported for AsianOption");
70 tradeTypeBuilder +=
"Arithmetic";
72 tradeTypeBuilder +=
"Geometric";
74 QL_FAIL(
"payoff type 2 must be 'Arithmetic' or 'Geometric'");
80 tradeTypeBuilder +=
"Price";
82 tradeTypeBuilder +=
"Strike";
84 QL_FAIL(
"payoff type must be 'Asian' or 'AverageStrike'");
87 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(tradeTypeBuilder);
88 QL_REQUIRE(builder,
"No builder found for " << tradeTypeBuilder);
92 if (
auto db = QuantLib::ext::dynamic_pointer_cast<DelegatingEngineBuilder>(builder)) {
112 QuantLib::ext::shared_ptr<AsianOptionEngineBuilder> asianOptionBuilder =
113 QuantLib::ext::dynamic_pointer_cast<AsianOptionEngineBuilder>(builder);
115 QL_REQUIRE(asianOptionBuilder,
"engine builder is not an AsianOption engine builder" << tradeTypeBuilder);
117 std::string processType = asianOptionBuilder->processType();
118 QL_REQUIRE(!processType.empty(),
"ProcessType must be configured, this is unexpected");
120 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff(
new PlainVanillaPayoff(type,
tradeStrike_.
value()));
124 if (
auto fxIndex = QuantLib::ext::dynamic_pointer_cast<QuantExt::FxIndex>(index)) {
125 QL_REQUIRE(fxIndex->targetCurrency() == payCcy,
126 "FX domestic ccy " << fxIndex->targetCurrency() <<
" must match pay ccy " << payCcy);
127 assetName_ = fxIndex->sourceCurrency().code();
128 }
else if (
auto eqIndex = QuantLib::ext::dynamic_pointer_cast<QuantExt::EquityIndex2>(index)) {
131 }
else if (
auto commIndex = QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityIndex>(index)) {
136 QuantLib::ext::shared_ptr<QuantLib::Instrument> asian;
137 auto exercise = QuantLib::ext::make_shared<QuantLib::EuropeanExercise>(expiryDate);
138 if (processType ==
"Discrete") {
139 QuantLib::Date today = engineFactory->market()->asofDate();
141 Size pastFixings = 0;
150 if (observationDate < today ||
151 (observationDate == today && Settings::instance().enforcesTodaysHistoricFixings())) {
154 Real fixingValue = index->fixing(observationDate);
156 runningAccumulator *= fixingValue;
158 runningAccumulator += fixingValue;
163 asian = QuantLib::ext::make_shared<QuantLib::DiscreteAveragingAsianOption>(
165 : QuantLib::Average::Type::Arithmetic,
167 }
else if (processType ==
"Continuous") {
169 asian = QuantLib::ext::make_shared<QuantLib::ContinuousAveragingAsianOption>(
option_.
payoffType2() ==
"Geometric"
170 ? QuantLib::Average::Type::Geometric
171 : QuantLib::Average::Type::Arithmetic,
174 QL_FAIL(
"unexpected ProcessType, valid options are Discrete/Continuous");
180 if (!asian->isExpired()) {
181 asian->setPricingEngine(asianOptionBuilder->engine(
assetName_, payCcy, expiryDate));
184 DLOG(
"No engine attached for option on trade " <<
id() <<
" with expiry date " << io::iso_date(expiryDate)
185 <<
" because it is expired.");
189 Real bsInd = (positionType == QuantLib::Position::Long ? 1.0 : -1.0);
192 std::vector<QuantLib::ext::shared_ptr<Instrument>> additionalInstruments;
193 std::vector<Real> additionalMultipliers;
197 positionType == QuantLib::Position::Long ? -1.0 : 1.0, payCcy, engineFactory,
200 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(asian, mult, additionalInstruments, additionalMultipliers);
210 QL_REQUIRE(n,
"No " +
tradeType_ +
"Data node found.");
222 underlyingBuilder.
fromXML(tmp);
249std::map<AssetClass, std::set<std::string>>
251 std::map<AssetClass, std::set<std::string>> result;
270 QuantLib::ext::shared_ptr<CommodityUnderlying> comUnderlying =
271 QuantLib::ext::dynamic_pointer_cast<CommodityUnderlying>(
underlying_);
272 std::string tmp =
"COMM-" + comUnderlying->name();
273 if (comUnderlying->priceType().empty() || comUnderlying->priceType() ==
"Spot") {
275 }
else if (comUnderlying->priceType() ==
"FutureSettlement") {
276 auto conventions = InstrumentConventions::instance().conventions();
277 QL_REQUIRE(conventions->has(comUnderlying->name()),
278 "future settlement requires conventions for commodity '" << comUnderlying->name() <<
"'");
280 QuantLib::ext::dynamic_pointer_cast<CommodityFutureConvention>(conventions->get(comUnderlying->name()));
281 Size futureMonthsOffset =
282 comUnderlying->futureMonthOffset() == Null<Size>() ? 0 : comUnderlying->futureMonthOffset();
283 Size deliveryRollDays =
284 comUnderlying->deliveryRollDays() == Null<Size>() ? 0 : comUnderlying->deliveryRollDays();
285 Calendar cal =
parseCalendar(comUnderlying->deliveryRollCalendar());
289 Date adjustedObsDate =
290 deliveryRollDays != 0 ? cal.advance(expiryDate, deliveryRollDays * Days) : expiryDate;
291 auto tmp =
parseCommodityIndex(comUnderlying->name(),
false, Handle<QuantExt::PriceTermStructure>(),
292 convention->calendar(),
true);
293 tmp = tmp->clone(expiryCalculator.
nextExpiry(
true, adjustedObsDate, futureMonthsOffset));
296 QL_FAIL(
"underlying price type '" << comUnderlying->priceType() <<
"' for commodity underlying '"
297 << comUnderlying->name() <<
"' not handled.");
302 QL_FAIL(
"invalid underlying type: " <<
underlying_->type());
Asian option representation.
Abstract engine builders for European Asian Options.
QuantLib::ext::shared_ptr< Trade > delegatingBuilderTrade_
std::map< AssetClass, std::set< std::string > > underlyingIndices(const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceDataManager=nullptr) const override
QuantLib::Real notional() const override
Trade interface.
virtual void fromXML(XMLNode *node) override
QuantLib::ext::shared_ptr< Underlying > underlying_
virtual XMLNode * toXML(XMLDocument &doc) const override
ScheduleData observationDates_
const string & indexName() const
string notionalCurrency() const override
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
Build QuantLib/QuantExt instrument, link pricing engine.
void populateIndexName() const
const ScheduleData & observationDates() const
Perform date calculations for future contracts based on conventions.
QuantLib::Date nextExpiry(bool includeExpiry=true, const QuantLib::Date &referenceDate=QuantLib::Date(), QuantLib::Natural offset=0, bool forOption=false) override
const string & callPut() const
const string & payoffType2() const
const string & payoffType() const
const string & longShort() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
const PremiumData & premiumData() const
const vector< string > & exerciseDates() const
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
const vector< ScheduleDates > & dates() const
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
TradeActions & tradeActions()
Set the trade actions.
virtual void fromXML(XMLNode *node) override
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 setSensitivityTemplate(const EngineBuilder &builder)
virtual XMLNode * toXML(XMLDocument &doc) const override
RequiredFixings requiredFixings_
virtual QuantLib::Real notional() const
Return the current notional in npvCurrency. See individual sub-classes for the precise definition.
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
virtual string notionalCurrency() const
const string & tradeType() const
std::map< std::string, boost::any > additionalData_
XMLNode * toXML(XMLDocument &doc) const
void fromXML(XMLNode *node, const bool isRequired=true, const bool allowYieldStrike=false)
QuantLib::Real value() const
const QuantLib::ext::shared_ptr< Underlying > & underlying()
void fromXML(XMLNode *node) override
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
Base class for classes that perform date calculations for future contracts.
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
bool isEquityIndex(const string &indexName)
Return true if the indexName is that of an EquityIndex, otherwise false.
bool isCommodityIndex(const string &indexName)
Return true if the indexName is that of an CommodityIndex, otherwise false.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
QuantLib::ext::shared_ptr< Index > parseIndex(const string &s)
Convert std::string to QuantLib::Index.
Option::Type parseOptionType(const std::string &s)
Convert text to QuantLib::Option::Type.
Classes and functions for log message handling.
#define DLOG(text)
Logging Macro (Level = Debug)
#define WLOG(text)
Logging Macro (Level = Warning)
bool isFxIndex(const std::string &indexName)
std::string to_string(const LocationInfo &l)
QuantLib::ext::shared_ptr< QuantExt::CommodityIndex > parseCommodityIndex(const string &name, bool hasPrefix, const Handle< PriceTermStructure > &ts, const Calendar &cal, const bool enforceFutureIndex)
Schedule makeSchedule(const ScheduleDates &data)
Serializable Credit Default Swap.
Wrapper for option instruments, tracks whether option has been exercised or not.
trade schedule data model and serialization