Skip to content

Commit 1bc2537

Browse files
committed
Merge branch 'github-231' into 'master'
Github 231 See merge request qs/ore-github!44
2 parents b6eaa44 + 0db3194 commit 1bc2537

5 files changed

Lines changed: 36 additions & 5 deletions

File tree

Docs/UserGuide/parameterisation/curveconfig.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ \subsubsection{FX Volatility Structures}
162162
<DayCounter>A365</DayCounter>
163163
<Calendar>US,JP</Calendar>
164164
<Conventions>USD-JPY-FXOPTION</Conventions>
165+
<SmileExtrapolation>UseInterpolator</SmileExtrapolation>
165166
</FXVolatility>
166167
\end{minted}
167168
\caption{FX option volatility configuration Smile / Delta}
@@ -273,6 +274,10 @@ \subsubsection{FX Volatility Structures}
273274
data input. See \ref{sss:fx_option_conv} for more details.
274275
\item BaseVolatility1: For `ATMTriangulated' this denotes one of the surfaces we want to triangulate from
275276
\item BaseVolatility2: For `ATMTriangulated' this denotes one of the surfaces we want to triangulate from
277+
\item SmileExtrapolation [Optional]: Applicable only in case of SmileType Delta. Indicates the extrapolation in the
278+
smile direction. The allowable values are None, UseInterpolator (or Linear) and Flat. Both Flat and None give flat
279+
extrapolation. UseInterpolator indicates that the configured interpolation should be continued in the strike
280+
direction in order to extrapolate. Default if not provided value is Flat.
276281
\end{itemize}
277282

278283
\subsubsection{Equity Curve Structures}

OREData/ored/configuration/fxvolcurveconfig.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright (C) 2016 Quaternion Risk Management Ltd
3+
Copyright (C) 2024 Skandinaviska Enskilda Banken AB (publ)
34
All rights reserved.
45
56
This file is part of ORE, a free-software/open-source library
@@ -33,11 +34,11 @@ FXVolatilityCurveConfig::FXVolatilityCurveConfig(const string& curveID, const st
3334
const string& fxForeignCurveID, const string& fxDomesticCurveID,
3435
const DayCounter& dayCounter, const Calendar& calendar,
3536
const SmileInterpolation& interp, const string& conventionsID,
36-
const std::vector<Size>& smileDelta)
37+
const std::vector<Size>& smileDelta, const string& smileExtrapolation)
3738
: CurveConfig(curveID, curveDescription), dimension_(dimension), expiries_(expiries), dayCounter_(dayCounter),
3839
calendar_(calendar), fxSpotID_(fxSpotID), fxForeignYieldCurveID_(fxForeignCurveID),
3940
fxDomesticYieldCurveID_(fxDomesticCurveID), conventionsID_(conventionsID), smileDelta_(smileDelta),
40-
smileInterpolation_(interp) {
41+
smileInterpolation_(interp), smileExtrapolation_(smileExtrapolation) {
4142
populateRequiredCurveIds();
4243
}
4344

@@ -134,14 +135,17 @@ void FXVolatilityCurveConfig::fromXML(XMLNode* node) {
134135
smileDelta_ = parseListOfValues<Size>(sDelta, &parseInteger);
135136
} else if (smileType == "Delta") {
136137
dimension_ = Dimension::SmileDelta;
137-
// only read smile interpolation method if dimension is smile.
138+
// only read smile interpolation and extrapolation method if dimension is smile.
138139
if (smileInterp == "" || smileInterp == "Linear") {
139140
smileInterpolation_ = SmileInterpolation::Linear;
140141
} else if (smileInterp == "Cubic") {
141142
smileInterpolation_ = SmileInterpolation::Cubic;
142143
} else {
143144
QL_FAIL("SmileInterpolation " << smileInterp << " not supported");
144145
}
146+
147+
smileExtrapolation_ = XMLUtils::getChildValue(node, "SmileExtrapolation", false, "Flat");
148+
145149
deltas_ = XMLUtils::getChildrenValuesAsStrings(node, "Deltas", true);
146150

147151
// check that these are valid deltas
@@ -235,6 +239,8 @@ XMLNode* FXVolatilityCurveConfig::toXML(XMLDocument& doc) {
235239
} else {
236240
QL_FAIL("Unknown SmileInterpolation in FXVolatilityCurveConfig::toXML()");
237241
}
242+
if (!smileExtrapolation_.empty())
243+
XMLUtils::addChild(doc, node, "SmileExtrapolation", smileExtrapolation_);
238244
XMLUtils::addChild(doc, node, "Conventions", to_string(conventionsID_));
239245
XMLUtils::addGenericChildAsList(doc, node, "Deltas", deltas_);
240246
} else if (dimension_ == Dimension::SmileBFRR) {

OREData/ored/configuration/fxvolcurveconfig.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright (C) 2016 Quaternion Risk Management Ltd
3+
Copyright (C) 2024 Skandinaviska Enskilda Banken AB (publ)
34
All rights reserved.
45
56
This file is part of ORE, a free-software/open-source library
@@ -72,7 +73,8 @@ class FXVolatilityCurveConfig : public CurveConfig {
7273
const DayCounter& dayCounter = QuantLib::Actual365Fixed(),
7374
const Calendar& calendar = QuantLib::TARGET(),
7475
const SmileInterpolation& interp = SmileInterpolation::VannaVolga2,
75-
const string& conventionsID = "", const std::vector<Size>& smileDelta = {25});
76+
const string& conventionsID = "", const std::vector<Size>& smileDelta = {25},
77+
const string& smileExtrapolation = "Flat");
7678

7779
FXVolatilityCurveConfig(const string& curveID, const string& curveDescription, const Dimension& dimension,
7880
const string& baseVolatility1, const string& baseVolatility2,
@@ -98,6 +100,7 @@ class FXVolatilityCurveConfig : public CurveConfig {
98100
const string& fxForeignYieldCurveID() const { return fxForeignYieldCurveID_; }
99101
const string& fxDomesticYieldCurveID() const { return fxDomesticYieldCurveID_; }
100102
const SmileInterpolation& smileInterpolation() const { return smileInterpolation_; }
103+
const std::string& smileExtrapolation() const { return smileExtrapolation_; }
101104
const string& conventionsID() const { return conventionsID_; }
102105
const std::vector<Size>& smileDelta() const { return smileDelta_; }
103106
const vector<string>& quotes() override;
@@ -111,6 +114,7 @@ class FXVolatilityCurveConfig : public CurveConfig {
111114
//@{
112115
Dimension& dimension() { return dimension_; }
113116
SmileInterpolation& smileInterpolation() { return smileInterpolation_; }
117+
string& smileExtrapolation() { return smileExtrapolation_; }
114118
vector<string>& deltas() { return deltas_; }
115119
DayCounter& dayCounter() { return dayCounter_; }
116120
Calendar& calendar() { return calendar_; }
@@ -140,6 +144,7 @@ class FXVolatilityCurveConfig : public CurveConfig {
140144
std::vector<Size> smileDelta_;
141145
std::set<string> requiredYieldCurveIDs_;
142146
SmileInterpolation smileInterpolation_;
147+
string smileExtrapolation_;
143148
string baseVolatility1_;
144149
string baseVolatility2_;
145150
string fxIndexTag_;

OREData/ored/marketdata/fxvolcurve.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ void FXVolCurve::buildSmileDeltaCurve(Date asof, FXVolatilityCurveSpec spec, con
217217
QL_FAIL("Delta FX vol surface: invalid interpolation, expected Linear, Cubic");
218218
}
219219

220+
bool flatExtrapolation = true;
221+
auto smileExtrapType = parseExtrapolation(config->smileExtrapolation());
222+
if (smileExtrapType == Extrapolation::UseInterpolator) {
223+
DLOG("Smile extrapolation switched to using interpolator.");
224+
flatExtrapolation = false;
225+
} else if (smileExtrapType == Extrapolation::None) {
226+
DLOG("Smile extrapolation cannot be turned off on its own so defaulting to flat.");
227+
} else if (smileExtrapType == Extrapolation::Flat) {
228+
DLOG("Smile extrapolation has been set to flat.");
229+
} else {
230+
DLOG("Smile extrapolation " << smileExtrapType << " not expected so defaulting to flat.");
231+
}
232+
220233
// daycounter used for interpolation in time.
221234
// TODO: push into conventions or config
222235
DayCounter dc = config->dayCounter();
@@ -227,7 +240,8 @@ void FXVolCurve::buildSmileDeltaCurve(Date asof, FXVolatilityCurveSpec spec, con
227240
[](const std::pair<Real, string>& x) { return x.first; });
228241
vol_ = boost::make_shared<QuantExt::BlackVolatilitySurfaceDelta>(
229242
asof, dates, putDeltasNum, callDeltasNum, hasATM, blackVolMatrix, dc, cal, fxSpot_, domYts_, forYts_,
230-
deltaType_, atmType_, boost::none, switchTenor_, longTermDeltaType_, longTermAtmType_, boost::none, interp);
243+
deltaType_, atmType_, boost::none, switchTenor_, longTermDeltaType_, longTermAtmType_, boost::none, interp,
244+
flatExtrapolation);
231245

232246
vol_->enableExtrapolation();
233247
}

xsd/curveconfig.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
<xs:element type="xs:string" name="BaseVolatility1" minOccurs="0" maxOccurs="1"/>
160160
<xs:element type="xs:string" name="BaseVolatility2" minOccurs="0" maxOccurs="1"/>
161161
<xs:element type="reportConfiguration" name="Report" minOccurs="0"/>
162+
<xs:element type="extrapolationType" name="SmileExtrapolation" minOccurs="0" maxOccurs="1"/>
162163
</xs:all>
163164
</xs:complexType>
164165

0 commit comments

Comments
 (0)