20#include <boost/algorithm/string.hpp>
24#include <ql/errors.hpp>
32 const Dimension& dimension,
const vector<string>& expiries,
33 const vector<string>& strikes,
const string& fxSpotID,
34 const string& fxForeignCurveID,
const string& fxDomesticCurveID,
35 const DayCounter& dayCounter,
const Calendar&
calendar,
37 const std::vector<Size>& smileDelta,
const string& smileExtrapolation)
38 :
CurveConfig(curveID, curveDescription), dimension_(dimension), expiries_(expiries), dayCounter_(dayCounter),
39 calendar_(
calendar), fxSpotID_(fxSpotID), fxForeignYieldCurveID_(fxForeignCurveID),
40 fxDomesticYieldCurveID_(fxDomesticCurveID), conventionsID_(conventionsID), smileDelta_(smileDelta),
41 smileInterpolation_(interp), smileExtrapolation_(smileExtrapolation) {
46 const Dimension& dimension,
const string& baseVolatility1,
47 const string& baseVolatility2,
const string& fxIndexTag)
48 :
CurveConfig(curveID, curveDescription), dimension_(dimension), baseVolatility1_(baseVolatility1),
49 baseVolatility2_(baseVolatility2), fxIndexTag_(fxIndexTag) {
55 vector<string> tokens;
56 boost::split(tokens,
fxSpotID(), boost::is_any_of(
"/"));
57 QL_REQUIRE(tokens.size() == 3,
"Expected 3 tokens FX/CCY1/CCY2 in fxSpotID (" <<
fxSpotID() <<
")");
58 quotes_.push_back(
"FX/RATE/" + tokens[1] +
"/" + tokens[2]);
59 string base =
"FX_OPTION/RATE_LNVOL/" + tokens[1] +
"/" + tokens[2] +
"/";
61 quotes_.push_back(base + e +
"/ATM");
69 quotes_.push_back(base + e +
"/" + d);
88 vector<string> tokens;
89 boost::split(tokens,
fxSpotID_, boost::is_any_of(
"/"));
90 QL_REQUIRE(tokens.size() == 3,
"Expected 3 tokens FX/CCY1/CCY2 in fxSpotID (" <<
fxSpotID_ <<
")");
92 cal = tokens[1] +
"," + tokens[2];
101 if (dim ==
"ATMTriangulated") {
113 }
else if (dim ==
"Smile") {
117 if (smileType ==
"" || smileType ==
"VannaVolga") {
121 if (smileInterp ==
"") {
123 }
else if (smileInterp ==
"VannaVolga1") {
125 }
else if (smileInterp ==
"VannaVolga2") {
128 QL_FAIL(
"SmileInterpolation " << smileInterp <<
" not supported");
136 }
else if (smileType ==
"Delta") {
139 if (smileInterp ==
"" || smileInterp ==
"Linear") {
141 }
else if (smileInterp ==
"Cubic") {
144 QL_FAIL(
"SmileInterpolation " << smileInterp <<
" not supported");
153 QL_REQUIRE(d ==
"ATM" || d.back() ==
'P' || d.back() ==
'C',
154 "this is not a valid value for delta, " << d);
159 }
else if (smileType ==
"BFRR") {
161 if (smileInterp ==
"" || smileInterp ==
"Cubic") {
163 }
else if (smileInterp ==
"Linear") {
166 QL_FAIL(
"SmileInterpolation " << smileInterp <<
" not supported");
173 }
else if (smileType ==
"Absolute") {
175 if (smileInterp ==
"" || smileInterp ==
"Cubic") {
177 }
else if (smileInterp ==
"Linear") {
180 QL_FAIL(
"SmileInterpolation " << smileInterp <<
" not supported");
183 QL_FAIL(
"SmileType '" << smileType <<
"' not supported, expected VannaVolga, Delta, BFRR");
186 QL_FAIL(
"Dimension " << dim <<
" not supported yet");
227 QL_FAIL(
"Unknown SmileInterpolation in FXVolatilityCurveConfig::toXML()");
240 QL_FAIL(
"Unknown SmileInterpolation in FXVolatilityCurveConfig::toXML()");
254 QL_FAIL(
"Unknown SmileInterpolation in FXVolatilityCurveConfig::toXML()");
266 QL_FAIL(
"Unknown SmileInterpolation in FXVolatilityCurveConfig::toXML()");
270 QL_FAIL(
"Unknown Dimension in FXVolatilityCurveConfig::toXML()");
287 std::vector<string> domTokens, forTokens;
291 if (domTokens.size() == 3 && domTokens[0] ==
"Yield") {
293 }
else if (domTokens.size() == 1) {
296 QL_FAIL(
"Cannot determine the required domestic yield curve for fx vol curve " <<
curveID_);
299 if (forTokens.size() == 3 && forTokens[0] ==
"Yield") {
301 }
else if (forTokens.size() == 1) {
304 QL_FAIL(
"Cannot determine the required foreign yield curve for fx vol curve " <<
curveID_);
312 vector<string> tokens;
313 boost::split(tokens,
fxSpotID_, boost::is_any_of(
"/"));
314 QL_REQUIRE(tokens.size() == 3,
"unexpected fxSpot format: " <<
fxSpotID_);
315 auto forTarget = tokens[1];
316 auto domTarget = tokens[2];
330 std::string baseCcy =
"";
331 if (forBase1 == forBase2 || forBase1 == domBase2) {
334 QL_REQUIRE(domBase1 == forBase2 || domBase1 == domBase2,
"no common currency found for baseVolatilities");
339 std::string forIndex =
"FX-" +
fxIndexTag_ +
"-" + forTarget +
"-" + baseCcy;
340 std::string domIndex =
"FX-" +
fxIndexTag_ +
"-" + domTarget +
"-" + baseCcy;
345 std::string forIndexInverse =
"FX-" +
fxIndexTag_ +
"-" + baseCcy +
"-" + forTarget;
349 std::string domIndexInverse =
"FX-" +
fxIndexTag_ +
"-" + baseCcy +
"-" + domTarget;
Base curve configuration.
map< CurveSpec::CurveType, set< string > > requiredCurveIds_
const string & fxSpotID() const
void populateRequiredCurveIds()
ReportConfig reportConfig_
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
string smileExtrapolation_
const vector< string > & quotes() override
Return all the market quotes required for this config.
FXVolatilityCurveConfig()
Default constructor.
vector< string > expiries_
string fxForeignYieldCurveID_
std::vector< Size > smileDelta_
string fxDomesticYieldCurveID_
SmileInterpolation smileInterpolation_
const string & fxIndexTag() const
Dimension
supported volatility structure types
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static void addGenericChildAsList(XMLDocument &doc, XMLNode *n, const string &name, const vector< T > &values, const string &attrName="", const string &attr="")
static void checkNode(XMLNode *n, const string &expectedName)
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static vector< string > getChildrenValuesAsStrings(XMLNode *node, const string &name, bool mandatory=false)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
FX volatility curve configuration classes.
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
Real parseReal(const string &s)
Convert text to Real.
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
std::string to_string(const LocationInfo &l)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
string conversion utilities