Skip to content

Commit de00a60

Browse files
mgronckipcaspers
authored andcommitted
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "e9f890d0e2" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "5a61009915" git-subrepo: version: "0.4.6" origin: "https://github.com/Homebrew/brew" commit: "e0bc557e7b"
2 parents e792f14 + 4cdc0c8 commit de00a60

6 files changed

Lines changed: 74 additions & 33 deletions

File tree

Docs/UserGuide/parameterisation/curveconfig.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ \subsubsection{FX Volatility Structures}
202202
<DayCounter>A365</DayCounter>
203203
<Calendar>US,JP</Calendar>
204204
<Conventions>USD-JPY-FXOPTION</Conventions>
205+
<SmileExtrapolation>UseInterpolator</SmileExtrapolation>
205206
</FXVolatility>
206207
\end{minted}
207208
\caption{FX option volatility configuration Smile / Delta}
@@ -313,6 +314,10 @@ \subsubsection{FX Volatility Structures}
313314
data input. See \ref{sss:fx_option_conv} for more details.
314315
\item BaseVolatility1: For `ATMTriangulated' this denotes one of the surfaces we want to triangulate from
315316
\item BaseVolatility2: For `ATMTriangulated' this denotes one of the surfaces we want to triangulate from
317+
\item SmileExtrapolation [Optional]: Applicable only in case of SmileType Delta. Indicates the extrapolation in the
318+
smile direction. The allowable values are None, UseInterpolator (or Linear) and Flat. Both Flat and None give flat
319+
extrapolation. UseInterpolator indicates that the configured interpolation should be continued in the strike
320+
direction in order to extrapolate. Default if not provided value is Flat.
316321
\end{itemize}
317322

318323
\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) const {
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_ = QuantLib::ext::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
}

cmake/commonSettings.cmake

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -69,30 +69,6 @@ if(MSVC)
6969
set(CMAKE_MSVC_RUNTIME_LIBRARY
7070
"MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<BOOL:${MSVC_LINK_DYNAMIC_RUNTIME}>:DLL>")
7171

72-
# link against static boost libraries
73-
if(NOT DEFINED Boost_USE_STATIC_LIBS)
74-
if(BUILD_SHARED_LIBS)
75-
set(Boost_USE_STATIC_LIBS 0)
76-
else()
77-
set(Boost_USE_STATIC_LIBS 1)
78-
endif()
79-
endif()
80-
81-
# Boost static runtime ON for MSVC
82-
if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
83-
if(BUILD_SHARED_LIBS OR(MSVC AND MSVC_LINK_DYNAMIC_RUNTIME))
84-
set(Boost_USE_STATIC_RUNTIME 0)
85-
else()
86-
set(Boost_USE_STATIC_RUNTIME 1)
87-
endif()
88-
endif()
89-
90-
91-
92-
IF(NOT Boost_USE_STATIC_LIBS)
93-
add_definitions(-DBOOST_ALL_DYN_LINK)
94-
add_definitions(-DBOOST_TEST_DYN_LINK)
95-
endif()
9672
add_compile_options(/external:env:BOOST)
9773
add_compile_options(/external:W0)
9874
add_compile_definitions(_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
@@ -137,9 +113,8 @@ else()
137113
set(BUILD_SHARED_LIBS ON)
138114
endif()
139115

140-
# link against dynamic boost libraries
141-
add_definitions(-DBOOST_ALL_DYN_LINK)
142-
add_definitions(-DBOOST_TEST_DYN_LINK)
116+
# Issue with Boost CMake finder introduced in version 1.70
117+
set(Boost_NO_BOOST_CMAKE ON)
143118

144119
# avoid a crash in valgrind that sometimes occurs if this flag is not defined
145120
add_definitions(-DBOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
@@ -196,9 +171,44 @@ else()
196171
# if QuantLib is build separately
197172
include_directories("${CMAKE_CURRENT_LIST_DIR}/../QuantLib/build")
198173

199-
200174
endif()
201175

176+
# Boost #
177+
# link against static boost libraries
178+
if(NOT DEFINED Boost_USE_STATIC_LIBS)
179+
if(BUILD_SHARED_LIBS)
180+
set(Boost_USE_STATIC_LIBS OFF)
181+
else()
182+
set(Boost_USE_STATIC_LIBS ON)
183+
endif()
184+
endif()
185+
186+
# Boost static runtime. ON for MSVC
187+
if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
188+
if(BUILD_SHARED_LIBS OR(MSVC AND MSVC_LINK_DYNAMIC_RUNTIME))
189+
set(Boost_USE_STATIC_RUNTIME OFF)
190+
else()
191+
set(Boost_USE_STATIC_RUNTIME ON)
192+
endif()
193+
endif()
194+
195+
if(NOT Boost_USE_STATIC_LIBS)
196+
# link against dynamic boost libraries
197+
add_definitions(-DBOOST_ALL_DYN_LINK)
198+
add_definitions(-DBOOST_TEST_DYN_LINK)
199+
endif()
200+
201+
# Use Boost Release/Debug
202+
if(CMAKE_BUILD_TYPE MATCHES Release)
203+
set(Boost_USE_DEBUG_LIBS OFF)
204+
set(Boost_USE_RELEASE_LIBS ON)
205+
elseif(CMAKE_BUILD_TYPE MATCHES Debug)
206+
set(Boost_USE_DEBUG_LIBS ON)
207+
set(Boost_USE_RELEASE_LIBS OFF)
208+
endif()
209+
210+
# Boost end #
211+
202212
# workaround when building with boost 1.81, see https://github.com/boostorg/phoenix/issues/111
203213
add_definitions(-DBOOST_PHOENIX_STL_TUPLE_H_)
204214

xsd/curveconfig.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
<xs:element type="xs:string" name="BaseVolatility1" minOccurs="0" maxOccurs="1"/>
190190
<xs:element type="xs:string" name="BaseVolatility2" minOccurs="0" maxOccurs="1"/>
191191
<xs:element type="reportConfiguration" name="Report" minOccurs="0"/>
192+
<xs:element type="extrapolationType" name="SmileExtrapolation" minOccurs="0" maxOccurs="1"/>
192193
</xs:all>
193194
</xs:complexType>
194195

0 commit comments

Comments
 (0)