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

Builder for a Lognormal FX model component. More...

#include <ored/model/fxbsbuilder.hpp>

+ Inheritance diagram for FxBsBuilder:
+ Collaboration diagram for FxBsBuilder:

Public Member Functions

 FxBsBuilder (const QuantLib::ext::shared_ptr< ore::data::Market > &market, const QuantLib::ext::shared_ptr< FxBsData > &data, const std::string &configuration=Market::defaultConfiguration, const std::string &referenceCalibrationGrid="")
 Constructor. More...
 
Real error () const
 Return calibration error. More...
 
Inspectors
std::string foreignCurrency ()
 
QuantLib::ext::shared_ptr< QuantExt::FxBsParametrizationparametrization () const
 
std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > optionBasket () const
 
- Public Member Functions inherited from ModelBuilder
void recalibrate () const
 
virtual void forceRecalculate ()
 
virtual bool requiresRecalibration () const=0
 

ModelBuilder interface

const QuantLib::ext::shared_ptr< ore::data::Marketmarket_
 
const std::string configuration_
 
const QuantLib::ext::shared_ptr< FxBsDatadata_
 
const std::string referenceCalibrationGrid_
 
Real error_
 
QuantLib::ext::shared_ptr< QuantExt::FxBsParametrizationparametrization_
 
std::vector< booloptionActive_
 
std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > optionBasket_
 
Array optionExpiries_
 
Handle< Quote > fxSpot_
 
Handle< YieldTermStructure > ytsDom_
 
Handle< YieldTermStructure > ytsFor_
 
Handle< BlackVolTermStructurefxVol_
 
std::vector< QuantLib::Real > fxVolCache_
 
bool forceCalibration_ = false
 
QuantLib::ext::shared_ptr< QuantExt::MarketObservermarketObserver_
 
void forceRecalculate () override
 
bool requiresRecalibration () const override
 
void setCalibrationDone () const
 
void performCalculations () const override
 
Real optionStrike (const Size j) const
 
Date optionExpiry (const Size j) const
 
void buildOptionBasket () const
 
bool volSurfaceChanged (const bool updateCache) const
 

Detailed Description

Builder for a Lognormal FX model component.

This class is a utility to turn an FX model component's description into an FX model parametrization which can be used to ultimately instantiate a CrossAssetModel.

Definition at line 48 of file fxbsbuilder.hpp.

Constructor & Destructor Documentation

◆ FxBsBuilder()

FxBsBuilder ( const QuantLib::ext::shared_ptr< ore::data::Market > &  market,
const QuantLib::ext::shared_ptr< FxBsData > &  data,
const std::string &  configuration = Market::defaultConfiguration,
const std::string &  referenceCalibrationGrid = "" 
)

Constructor.

Parameters
marketMarket object
dataFX model parameters/description
configurationMarket configuration to use
referenceCalibrationGridthe reference calibration grid

Definition at line 41 of file fxbsbuilder.cpp.

43 : market_(market), configuration_(configuration), data_(data), referenceCalibrationGrid_(referenceCalibrationGrid) {
44
45 optionActive_ = std::vector<bool>(data_->optionExpiries().size(), false);
46 marketObserver_ = QuantLib::ext::make_shared<MarketObserver>();
47 QuantLib::Currency ccy = ore::data::parseCurrency(data->foreignCcy());
48 QuantLib::Currency domesticCcy = ore::data::parseCurrency(data->domesticCcy());
49 std::string ccyPair = ccy.code() + domesticCcy.code();
50
51 LOG("Start building FxBs model for " << ccyPair);
52
53 // get market data
54 fxSpot_ = market_->fxSpot(ccyPair, configuration_);
55 ytsDom_ = market_->discountCurve(domesticCcy.code(), configuration_);
56 ytsFor_ = market_->discountCurve(ccy.code(), configuration_);
57
58 // register with market observables except vols
59 marketObserver_->addObservable(fxSpot_);
60 marketObserver_->addObservable(market_->discountCurve(domesticCcy.code()));
61 marketObserver_->addObservable(market_->discountCurve(ccy.code()));
62
63 // register the builder with the market observer
64 registerWith(marketObserver_);
65
66 // notify observers of all market data changes, not only when not calculated
67 alwaysForwardNotifications();
68
69 // build option basket and derive parametrization from it
70 if (data->calibrateSigma()) {
71 fxVol_ = market_->fxVol(ccyPair, configuration_);
72 registerWith(fxVol_);
74 }
75
76 Array sigmaTimes, sigma;
77 if (data->sigmaParamType() == ParamType::Constant) {
78 QL_REQUIRE(data->sigmaTimes().size() == 0, "empty sigma tme grid expected");
79 QL_REQUIRE(data->sigmaValues().size() == 1, "initial sigma grid size 1 expected");
80 sigmaTimes = Array(0);
81 sigma = Array(data_->sigmaValues().begin(), data_->sigmaValues().end());
82 } else {
83 if (data->calibrateSigma() && data->calibrationType() == CalibrationType::Bootstrap) { // override
84 QL_REQUIRE(optionExpiries_.size() > 0, "optionExpiries is empty");
85 sigmaTimes = Array(optionExpiries_.begin(), optionExpiries_.end() - 1);
86 sigma = Array(sigmaTimes.size() + 1, data->sigmaValues()[0]);
87 } else {
88 // use input time grid and input alpha array otherwise
89 sigmaTimes = Array(data_->sigmaTimes().begin(), data_->sigmaTimes().end());
90 sigma = Array(data_->sigmaValues().begin(), data_->sigmaValues().end());
91 QL_REQUIRE(sigma.size() == sigmaTimes.size() + 1, "sigma grids do not match");
92 }
93 }
94
95 DLOG("sigmaTimes before calibration: " << sigmaTimes);
96 DLOG("sigma before calibration: " << sigma);
97
98 if (data->sigmaParamType() == ParamType::Piecewise)
100 QuantLib::ext::make_shared<QuantExt::FxBsPiecewiseConstantParametrization>(ccy, fxSpot_, sigmaTimes, sigma);
101 else if (data->sigmaParamType() == ParamType::Constant)
102 parametrization_ = QuantLib::ext::make_shared<QuantExt::FxBsConstantParametrization>(ccy, fxSpot_, sigma[0]);
103 else
104 QL_FAIL("interpolation type not supported for FX");
105}
QuantLib::ext::shared_ptr< QuantExt::FxBsParametrization > parametrization_
Definition: fxbsbuilder.hpp:94
const std::string configuration_
Definition: fxbsbuilder.hpp:88
Handle< YieldTermStructure > ytsFor_
QuantLib::ext::shared_ptr< QuantExt::MarketObserver > marketObserver_
Handle< BlackVolTermStructure > fxVol_
const QuantLib::ext::shared_ptr< FxBsData > data_
Definition: fxbsbuilder.hpp:89
Handle< YieldTermStructure > ytsDom_
const QuantLib::ext::shared_ptr< ore::data::Market > market_
Definition: fxbsbuilder.hpp:87
Handle< Quote > fxSpot_
const std::string referenceCalibrationGrid_
Definition: fxbsbuilder.hpp:90
void buildOptionBasket() const
std::vector< bool > optionActive_
Definition: fxbsbuilder.hpp:97
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
@ data
Definition: log.hpp:77
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
+ Here is the call graph for this function:

Member Function Documentation

◆ error()

Real error ( ) const

Return calibration error.

Definition at line 107 of file fxbsbuilder.cpp.

107 {
108 calculate();
109 return error_;
110}

◆ foreignCurrency()

std::string foreignCurrency ( )

Definition at line 65 of file fxbsbuilder.hpp.

65{ return data_->foreignCcy(); }

◆ parametrization()

QuantLib::ext::shared_ptr< QuantExt::FxBsParametrization > parametrization ( ) const

Definition at line 112 of file fxbsbuilder.cpp.

112 {
113 calculate();
114 return parametrization_;
115}

◆ optionBasket()

std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > optionBasket ( ) const

Definition at line 116 of file fxbsbuilder.cpp.

116 {
117 calculate();
118 return optionBasket_;
119}
std::vector< QuantLib::ext::shared_ptr< BlackCalibrationHelper > > optionBasket_
Definition: fxbsbuilder.hpp:98

◆ forceRecalculate()

void forceRecalculate ( )
overridevirtual

Reimplemented from ModelBuilder.

Definition at line 237 of file fxbsbuilder.cpp.

237 {
238 forceCalibration_ = true;
240 forceCalibration_ = false;
241}
virtual void forceRecalculate()
+ Here is the call graph for this function:

◆ requiresRecalibration()

bool requiresRecalibration ( ) const
overridevirtual

Implements ModelBuilder.

Definition at line 121 of file fxbsbuilder.cpp.

121 {
122 return data_->calibrateSigma() &&
123 (volSurfaceChanged(false) || marketObserver_->hasUpdated(false) || forceCalibration_);
124}
bool volSurfaceChanged(const bool updateCache) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setCalibrationDone()

void setCalibrationDone ( ) const

Definition at line 133 of file fxbsbuilder.cpp.

133 {
134 // reset market observer updated flag
135 marketObserver_->hasUpdated(true);
136 // update vol cache
137 volSurfaceChanged(true);
138}
+ Here is the call graph for this function:

◆ performCalculations()

void performCalculations ( ) const
overrideprivate

Definition at line 126 of file fxbsbuilder.cpp.

126 {
127 if (requiresRecalibration()) {
128 // build option basket
130 }
131}
bool requiresRecalibration() const override
+ Here is the call graph for this function:

◆ optionStrike()

Real optionStrike ( const Size  j) const
private

Definition at line 140 of file fxbsbuilder.cpp.

140 {
141 Date expiryDate = optionExpiry(j);
142 ore::data::Strike strike = ore::data::parseStrike(data_->optionStrikes()[j]);
143 Real strikeValue;
144 BlackDeltaCalculator bdc(Option::Type::Call, DeltaVolQuote::DeltaType::Spot, fxSpot_->value(),
145 ytsDom_->discount(expiryDate), ytsFor_->discount(expiryDate),
146 fxVol_->blackVol(expiryDate, Null<Real>()) * sqrt(fxVol_->timeFromReference(expiryDate)));
147
148 // TODO: Extend strike type coverage
150 strikeValue = bdc.atmStrike(DeltaVolQuote::AtmFwd);
151 else if (strike.type == ore::data::Strike::Type::Absolute)
152 strikeValue = strike.value;
153 else
154 QL_FAIL("strike type ATMF or Absolute expected");
155 Handle<Quote> quote(QuantLib::ext::make_shared<SimpleQuote>(fxVol_->blackVol(expiryDate, strikeValue)));
156 return strikeValue;
157}
Date optionExpiry(const Size j) const
Strike parseStrike(const std::string &s)
Convert text to Strike.
Definition: strike.cpp:30
RandomVariable sqrt(RandomVariable x)
QuantLib::Real value
Definition: strike.hpp:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ optionExpiry()

Date optionExpiry ( const Size  j) const
private

Definition at line 159 of file fxbsbuilder.cpp.

159 {
160 Date today = Settings::instance().evaluationDate();
161 std::string expiryString = data_->optionExpiries()[j];
162 bool expiryDateBased;
163 Period expiryPb;
164 Date expiryDb;
165 parseDateOrPeriod(expiryString, expiryDb, expiryPb, expiryDateBased);
166 Date expiryDate = expiryDateBased ? expiryDb : today + expiryPb;
167 return expiryDate;
168}
boost::variant< QuantLib::Date, QuantLib::Period > parseDateOrPeriod(const string &s)
Convert text to QuantLib::Period or QuantLib::Date.
Definition: parsers.cpp:493
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildOptionBasket()

void buildOptionBasket ( ) const
private

Definition at line 192 of file fxbsbuilder.cpp.

192 {
193 QL_REQUIRE(data_->optionExpiries().size() == data_->optionStrikes().size(), "fx option vector size mismatch");
194
195 DLOG("build reference date grid '" << referenceCalibrationGrid_ << "'");
196 Date lastRefCalDate = Date::minDate();
197 std::vector<Date> referenceCalibrationDates;
198 if (!referenceCalibrationGrid_.empty())
199 referenceCalibrationDates = DateGrid(referenceCalibrationGrid_).dates();
200
201 optionBasket_.clear();
202 std::vector<Time> expiryTimes;
203 for (Size j = 0; j < data_->optionExpiries().size(); j++) {
204 Date expiryDate = optionExpiry(j);
205
206 // check if we want to keep the helper when a reference calibration grid is given
207 auto refCalDate =
208 std::lower_bound(referenceCalibrationDates.begin(), referenceCalibrationDates.end(), expiryDate);
209 if (refCalDate == referenceCalibrationDates.end() || *refCalDate > lastRefCalDate) {
210 optionActive_[j] = true;
211 Real strikeValue = optionStrike(j);
212 Handle<Quote> quote(QuantLib::ext::make_shared<SimpleQuote>(fxVol_->blackVol(expiryDate, strikeValue)));
213 QuantLib::ext::shared_ptr<QuantExt::FxEqOptionHelper> helper = QuantLib::ext::make_shared<QuantExt::FxEqOptionHelper>(
214 expiryDate, strikeValue, fxSpot_, quote, ytsDom_, ytsFor_);
215 optionBasket_.push_back(helper);
216 helper->performCalculations();
217 expiryTimes.push_back(ytsDom_->timeFromReference(helper->option()->exercise()->date(0)));
218 DLOG("Added FxEqOptionHelper " << (data_->foreignCcy() + data_->domesticCcy()) << " "
219 << QuantLib::io::iso_date(expiryDate) << " " << helper->strike() << " "
220 << quote->value());
221 if (refCalDate != referenceCalibrationDates.end())
222 lastRefCalDate = *refCalDate;
223 } else {
224 optionActive_[j] = false;
225 }
226 }
227
228 std::sort(expiryTimes.begin(), expiryTimes.end());
229 auto itExpiryTime = unique(expiryTimes.begin(), expiryTimes.end());
230 expiryTimes.resize(distance(expiryTimes.begin(), itExpiryTime));
231
232 optionExpiries_ = Array(expiryTimes.size());
233 for (Size j = 0; j < expiryTimes.size(); j++)
234 optionExpiries_[j] = expiryTimes[j];
235}
Real optionStrike(const Size j) const
Size size(const ValueType &v)
Definition: value.cpp:145
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ volSurfaceChanged()

bool volSurfaceChanged ( const bool  updateCache) const
private

Definition at line 170 of file fxbsbuilder.cpp.

170 {
171 bool hasUpdated = false;
172
173 // if cache doesn't exist resize vector
174 if (fxVolCache_.size() != optionBasket_.size())
175 fxVolCache_ = vector<Real>(optionBasket_.size(), Null<Real>());
176
177 Size optionCounter = 0;
178 for (Size j = 0; j < data_->optionExpiries().size(); j++) {
179 if (!optionActive_[j])
180 continue;
181 Real vol = fxVol_->blackVol(optionExpiry(j), optionStrike(j));
182 if (!close_enough(fxVolCache_[optionCounter], vol)) {
183 if (updateCache)
184 fxVolCache_[optionCounter] = vol;
185 hasUpdated = true;
186 }
187 optionCounter++;
188 }
189 return hasUpdated;
190}
std::vector< QuantLib::Real > fxVolCache_
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ market_

const QuantLib::ext::shared_ptr<ore::data::Market> market_
private

Definition at line 87 of file fxbsbuilder.hpp.

◆ configuration_

const std::string configuration_
private

Definition at line 88 of file fxbsbuilder.hpp.

◆ data_

const QuantLib::ext::shared_ptr<FxBsData> data_
private

Definition at line 89 of file fxbsbuilder.hpp.

◆ referenceCalibrationGrid_

const std::string referenceCalibrationGrid_
private

Definition at line 90 of file fxbsbuilder.hpp.

◆ error_

Real error_
mutableprivate

Definition at line 93 of file fxbsbuilder.hpp.

◆ parametrization_

QuantLib::ext::shared_ptr<QuantExt::FxBsParametrization> parametrization_
private

Definition at line 94 of file fxbsbuilder.hpp.

◆ optionActive_

std::vector<bool> optionActive_
mutableprivate

Definition at line 97 of file fxbsbuilder.hpp.

◆ optionBasket_

std::vector<QuantLib::ext::shared_ptr<BlackCalibrationHelper> > optionBasket_
mutableprivate

Definition at line 98 of file fxbsbuilder.hpp.

◆ optionExpiries_

Array optionExpiries_
mutableprivate

Definition at line 99 of file fxbsbuilder.hpp.

◆ fxSpot_

Handle<Quote> fxSpot_
private

Definition at line 102 of file fxbsbuilder.hpp.

◆ ytsDom_

Handle<YieldTermStructure> ytsDom_
private

Definition at line 103 of file fxbsbuilder.hpp.

◆ ytsFor_

Handle<YieldTermStructure> ytsFor_
private

Definition at line 103 of file fxbsbuilder.hpp.

◆ fxVol_

Handle<BlackVolTermStructure> fxVol_
private

Definition at line 104 of file fxbsbuilder.hpp.

◆ fxVolCache_

std::vector<QuantLib::Real> fxVolCache_
mutableprivate

Definition at line 107 of file fxbsbuilder.hpp.

◆ forceCalibration_

bool forceCalibration_ = false
private

Definition at line 110 of file fxbsbuilder.hpp.

◆ marketObserver_

QuantLib::ext::shared_ptr<QuantExt::MarketObserver> marketObserver_
private

Definition at line 113 of file fxbsbuilder.hpp.