Build QuantLib/QuantExt instrument, link pricing engine.
35 {
36
37
41 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
47
50 additionalData_[
"isdaSubProduct"] = string(
"Price Return Basic Performance");
51 }
52 else {
53 WLOG(
"ISDA taxonomy not set for trade " <<
id());
54 }
56
58
59 QL_REQUIRE(
tradeActions().empty(),
"TradeActions not supported for AsianOption");
60
64
66
67
68
70 tradeTypeBuilder += "Arithmetic";
72 tradeTypeBuilder += "Geometric";
73 else {
74 QL_FAIL("payoff type 2 must be 'Arithmetic' or 'Geometric'");
75 }
76
77
78
80 tradeTypeBuilder += "Price";
82 tradeTypeBuilder += "Strike";
83 else {
84 QL_FAIL("payoff type must be 'Asian' or 'AverageStrike'");
85 }
86
87 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(tradeTypeBuilder);
88 QL_REQUIRE(builder, "No builder found for " << tradeTypeBuilder);
89
90
91
92 if (auto db = QuantLib::ext::dynamic_pointer_cast<DelegatingEngineBuilder>(builder)) {
93
94
95
97
104
105
106
107 return;
108 }
109
110
111
112 QuantLib::ext::shared_ptr<AsianOptionEngineBuilder> asianOptionBuilder =
113 QuantLib::ext::dynamic_pointer_cast<AsianOptionEngineBuilder>(builder);
114
115 QL_REQUIRE(asianOptionBuilder, "engine builder is not an AsianOption engine builder" << tradeTypeBuilder);
116
117 std::string processType = asianOptionBuilder->processType();
118 QL_REQUIRE(!processType.empty(), "ProcessType must be configured, this is unexpected");
119
120 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff(
new PlainVanillaPayoff(type,
tradeStrike_.
value()));
121
123
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)) {
129
131 } else if (auto commIndex = QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityIndex>(index)) {
133 }
134
135
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;
144
145
147
149
150 if (observationDate < today ||
151 (observationDate == today && Settings::instance().enforcesTodaysHistoricFixings())) {
152
154 Real fixingValue = index->fixing(observationDate);
156 runningAccumulator *= fixingValue;
158 runningAccumulator += fixingValue;
159 }
160 ++pastFixings;
161 }
162 }
163 asian = QuantLib::ext::make_shared<QuantLib::DiscreteAveragingAsianOption>(
165 : QuantLib::Average::Type::Arithmetic,
167 } else if (processType == "Continuous") {
168
169 asian = QuantLib::ext::make_shared<QuantLib::ContinuousAveragingAsianOption>(
option_.
payoffType2() ==
"Geometric"
170 ? QuantLib::Average::Type::Geometric
171 : QuantLib::Average::Type::Arithmetic,
172 payoff, exercise);
173 } else {
174 QL_FAIL("unexpected ProcessType, valid options are Discrete/Continuous");
175 }
176
177
178
180 if (!asian->isExpired()) {
181 asian->setPricingEngine(asianOptionBuilder->engine(
assetName_, payCcy, expiryDate));
183 } else {
184 DLOG(
"No engine attached for option on trade " <<
id() <<
" with expiry date " << io::iso_date(expiryDate)
185 << " because it is expired.");
186 }
187
189 Real bsInd = (positionType == QuantLib::Position::Long ? 1.0 : -1.0);
191
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,
198 configuration));
199
200 instrument_ = QuantLib::ext::make_shared<VanillaInstrument>(asian, mult, additionalInstruments, additionalMultipliers);
201
205}
QuantLib::ext::shared_ptr< Trade > delegatingBuilderTrade_
const string & indexName() const
const string & callPut() const
const string & payoffType2() const
const string & payoffType() const
const string & longShort() const
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
TradeActions & tradeActions()
Set the trade actions.
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)
RequiredFixings requiredFixings_
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
std::map< std::string, boost::any > additionalData_
QuantLib::Real value() const
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.
#define DLOG(text)
Logging Macro (Level = Debug)
#define WLOG(text)
Logging Macro (Level = Warning)
Schedule makeSchedule(const ScheduleDates &data)