Skip to content

Commit 76eb9fb

Browse files
committed
Merge branch 'bugfix/QPR-13765' into 'master'
Resolve QPR-13765 Bugfix normal vols broken in VaR or sensi if not using spreaded curves Closes QPR-13765 See merge request qs/oreplus!3141
2 parents 21c490c + b2c583b commit 76eb9fb

10 files changed

Lines changed: 57 additions & 31 deletions

OREAnalytics/orea/scenario/scenariosimmarket.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3027,7 +3027,7 @@ ScenarioSimMarket::ScenarioSimMarket(
30273027
} else {
30283028
newVol = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackVarianceCurve3>(
30293029
0, NullCalendar(), baseVol->businessDayConvention(), dayCounter, expiryTimes,
3030-
quotes[0], false));
3030+
quotes[0], false, baseVol->volType(), baseVol->shift()));
30313031
}
30323032
} else {
30333033
DLOG("Ssm comm vol for " << name << " uses BlackVarianceSurfaceMoneynessSpot.");
@@ -3052,7 +3052,9 @@ ScenarioSimMarket::ScenarioSimMarket(
30523052
newVol = Handle<BlackVolTermStructure>(
30533053
QuantLib::ext::make_shared<BlackVarianceSurfaceMoneynessForward>(
30543054
baseVol->calendar(), spot, expiryTimes, moneyness, quotes, dayCounter,
3055-
priceYts, yts, stickyStrike, flatExtrapMoneyness));
3055+
priceYts, yts, stickyStrike, flatExtrapMoneyness, BlackVolTimeExtrapolation::FlatVolatility,
3056+
baseVol->volType(),
3057+
baseVol->shift()));
30563058
}
30573059
}
30583060

QuantExt/qle/termstructures/blackinvertedvoltermstructure.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class BlackInvertedVolTermStructure : public BlackVolTermStructure {
4141
/*! This will work with both a floating and fixed reference date underlying surface,
4242
since we are reimplementing the reference date and update methods */
4343
BlackInvertedVolTermStructure(const Handle<BlackVolTermStructure>& vol)
44-
: BlackVolTermStructure(vol->businessDayConvention(), vol->dayCounter()), vol_(vol) {
44+
: BlackVolTermStructure(vol->businessDayConvention(), vol->dayCounter(), vol->volType(), vol->shift()),
45+
vol_(vol) {
4546
registerWith(vol_);
4647
}
4748

QuantExt/qle/termstructures/blackvariancecurve3.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ namespace QuantExt {
2323

2424
BlackVarianceCurve3::BlackVarianceCurve3(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc,
2525
const DayCounter& dc, const std::vector<Time>& times,
26-
const std::vector<Handle<Quote> >& blackVolCurve, bool requireMonotoneVariance)
27-
: BlackVarianceTermStructure(settlementDays, cal, bdc, dc), times_(times), quotes_(blackVolCurve),
26+
const std::vector<Handle<Quote> >& blackVolCurve, bool requireMonotoneVariance,
27+
const VolatilityType type, const Real shift)
28+
: BlackVarianceTermStructure(settlementDays, cal, bdc, dc, type, shift), times_(times), quotes_(blackVolCurve),
2829
requireMonotoneVariance_(requireMonotoneVariance) {
2930

3031
QL_REQUIRE(times.size() == blackVolCurve.size(), "mismatch between date vector and black vol vector");

QuantExt/qle/termstructures/blackvariancecurve3.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class BlackVarianceCurve3 : public LazyObject, public BlackVarianceTermStructure
4949
// If requireMonotoneVariance is true, we check for monotone variance in performCalculations and throw if not
5050
BlackVarianceCurve3(Natural settlementDays, const Calendar& cal, BusinessDayConvention bdc, const DayCounter& dc,
5151
const std::vector<Time>& times, const std::vector<Handle<Quote> >& blackVolCurve,
52-
bool requireMonotoneVariance = true);
52+
bool requireMonotoneVariance = true, const VolatilityType type = ShiftedLognormal,
53+
const Real shift = 0.0);
5354
//! \name TermStructure interface
5455
//@{
5556
Date maxDate() const override;

QuantExt/qle/termstructures/blackvariancesurfacemoneyness.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ namespace QuantExt {
3131
BlackVarianceSurfaceMoneyness::BlackVarianceSurfaceMoneyness(
3232
const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
3333
const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix, const DayCounter& dayCounter, bool stickyStrike,
34-
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation)
35-
: BlackVarianceTermStructure(0, cal, Following, dayCounter), stickyStrike_(stickyStrike), spot_(spot),
34+
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation, const VolatilityType type, const Real shift)
35+
: BlackVarianceTermStructure(0, cal, Following, dayCounter, type, shift), stickyStrike_(stickyStrike), spot_(spot),
3636
times_(times), moneyness_(moneyness), flatExtrapMoneyness_(flatExtrapMoneyness),
3737
timeExtrapolation_(timeExtrapolation), quotes_(blackVolMatrix) {
3838
init();
@@ -42,8 +42,9 @@ BlackVarianceSurfaceMoneyness::BlackVarianceSurfaceMoneyness(
4242
const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
4343
const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix,
4444
const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness,
45-
BlackVolTimeExtrapolation timeExtrapolation)
46-
: BlackVarianceTermStructure(referenceDate, cal, Following, dayCounter), stickyStrike_(stickyStrike), spot_(spot),
45+
BlackVolTimeExtrapolation timeExtrapolation, const VolatilityType type, const Real shift)
46+
: BlackVarianceTermStructure(referenceDate, cal, Following, dayCounter, type, shift),
47+
stickyStrike_(stickyStrike), spot_(spot),
4748
times_(times), moneyness_(moneyness), flatExtrapMoneyness_(flatExtrapMoneyness),
4849
timeExtrapolation_(timeExtrapolation), quotes_(blackVolMatrix) {
4950
init();
@@ -126,16 +127,17 @@ Real BlackVarianceSurfaceMoneyness::blackVarianceMoneyness(Time t, Real m) const
126127
BlackVarianceSurfaceMoneynessSpot::BlackVarianceSurfaceMoneynessSpot(
127128
const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
128129
const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix, const DayCounter& dayCounter, bool stickyStrike,
129-
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation)
130+
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation, const VolatilityType type, const Real shift)
130131
: BlackVarianceSurfaceMoneyness(cal, spot, times, moneyness, blackVolMatrix, dayCounter, stickyStrike,
131-
flatExtrapMoneyness, timeExtrapolation) {}
132+
flatExtrapMoneyness, timeExtrapolation, type, shift) {}
132133

133134
BlackVarianceSurfaceMoneynessSpot::BlackVarianceSurfaceMoneynessSpot(
134135
const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
135136
const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix,
136-
const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation)
137+
const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation,
138+
const VolatilityType type, const Real shift)
137139
: BlackVarianceSurfaceMoneyness(referenceDate, cal, spot, times, moneyness, blackVolMatrix, dayCounter,
138-
stickyStrike, flatExtrapMoneyness, timeExtrapolation) {}
140+
stickyStrike, flatExtrapMoneyness, timeExtrapolation, type, shift) {}
139141

140142
Real BlackVarianceSurfaceMoneynessSpot::moneyness(Time, Real strike) const {
141143
if (strike == Null<Real>() || strike == 0) {
@@ -157,9 +159,9 @@ BlackVarianceSurfaceMoneynessForward::BlackVarianceSurfaceMoneynessForward(
157159
const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& moneyness,
158160
const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix, const DayCounter& dayCounter,
159161
const Handle<YieldTermStructure>& forTS, const Handle<YieldTermStructure>& domTS, bool stickyStrike,
160-
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation)
162+
bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation, const VolatilityType type, const Real shift)
161163
: BlackVarianceSurfaceMoneyness(cal, spot, times, moneyness, blackVolMatrix, dayCounter, stickyStrike,
162-
flatExtrapMoneyness, timeExtrapolation),
164+
flatExtrapMoneyness, timeExtrapolation, type, shift),
163165
forTS_(forTS), domTS_(domTS) {
164166
init();
165167
}
@@ -168,9 +170,10 @@ BlackVarianceSurfaceMoneynessForward::BlackVarianceSurfaceMoneynessForward(
168170
const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times,
169171
const std::vector<Real>& moneyness, const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix,
170172
const DayCounter& dayCounter, const Handle<YieldTermStructure>& forTS, const Handle<YieldTermStructure>& domTS,
171-
bool stickyStrike, bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation)
173+
bool stickyStrike, bool flatExtrapMoneyness, BlackVolTimeExtrapolation timeExtrapolation,
174+
const VolatilityType type, const Real shift)
172175
: BlackVarianceSurfaceMoneyness(referenceDate, cal, spot, times, moneyness, blackVolMatrix, dayCounter,
173-
stickyStrike, flatExtrapMoneyness, timeExtrapolation),
176+
stickyStrike, flatExtrapMoneyness, timeExtrapolation, type, shift),
174177
forTS_(forTS), domTS_(domTS) {
175178
init();
176179
}

QuantExt/qle/termstructures/blackvariancesurfacemoneyness.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,18 @@ class BlackVarianceSurfaceMoneyness : public LazyObject, public BlackVarianceTer
5252
const std::vector<Real>& moneyness,
5353
const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
5454
const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness = false,
55-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
55+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
56+
const VolatilityType type = VolatilityType::ShiftedLognormal,
57+
const Real shift = 0.0);
5658

5759
//! Moneyness variance surface with a fixed reference date.
5860
BlackVarianceSurfaceMoneyness(const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot,
5961
const std::vector<Time>& times, const std::vector<Real>& moneyness,
6062
const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
6163
const DayCounter& dayCounter, bool stickyStrike, bool flatExtrapMoneyness = false,
62-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
64+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
65+
const VolatilityType type = VolatilityType::ShiftedLognormal,
66+
const Real shift = 0.0);
6367

6468
//! \name TermStructure interface
6569
//@{
@@ -129,15 +133,19 @@ class BlackVarianceSurfaceMoneynessSpot : public BlackVarianceSurfaceMoneyness {
129133
const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
130134
const DayCounter& dayCounter, bool stickyStrike = false,
131135
bool flatExtrapMoneyness = false,
132-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
136+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
137+
const VolatilityType type = VolatilityType::ShiftedLognormal,
138+
const Real shift = 0.0);
133139

134140
//! Spot moneyness variance surface with a fixed reference date.
135141
BlackVarianceSurfaceMoneynessSpot(const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot,
136142
const std::vector<Time>& times, const std::vector<Real>& moneyness,
137143
const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
138144
const DayCounter& dayCounter, bool stickyStrike = false,
139145
bool flatExtrapMoneyness = false,
140-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
146+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
147+
const VolatilityType type = VolatilityType::ShiftedLognormal,
148+
const Real shift = 0.0);
141149

142150
private:
143151
virtual Real moneyness(Time t, Real strike) const override;
@@ -154,7 +162,9 @@ class BlackVarianceSurfaceMoneynessForward : public BlackVarianceSurfaceMoneynes
154162
const DayCounter& dayCounter, const Handle<YieldTermStructure>& forTS,
155163
const Handle<YieldTermStructure>& domTS, bool stickyStrike = false,
156164
bool flatExtrapMoneyness = false,
157-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
165+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
166+
const VolatilityType type = VolatilityType::ShiftedLognormal,
167+
const Real shift = 0.0);
158168

159169
//! Forward moneyness variance surface with a fixed reference date.
160170
BlackVarianceSurfaceMoneynessForward(const Date& referenceDate, const Calendar& cal, const Handle<Quote>& spot,
@@ -163,7 +173,9 @@ class BlackVarianceSurfaceMoneynessForward : public BlackVarianceSurfaceMoneynes
163173
const DayCounter& dayCounter, const Handle<YieldTermStructure>& forTS,
164174
const Handle<YieldTermStructure>& domTS, bool stickyStrike = false,
165175
bool flatExtrapMoneyness = false,
166-
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility);
176+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
177+
const VolatilityType type = VolatilityType::ShiftedLognormal,
178+
const Real shift = 0.0);
167179

168180
private:
169181
// Shared initialisation

QuantExt/qle/termstructures/blackvariancesurfacestddevs.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ namespace QuantExt {
2828
BlackVarianceSurfaceStdDevs::BlackVarianceSurfaceStdDevs(
2929
const Calendar& cal, const Handle<Quote>& spot, const std::vector<Time>& times, const std::vector<Real>& stdDevs,
3030
const std::vector<std::vector<Handle<Quote>>>& blackVolMatrix, const DayCounter& dayCounter,
31-
const QuantLib::ext::shared_ptr<EqFxIndexBase>& index, bool stickyStrike, bool flatExtrapMoneyness)
32-
: BlackVarianceSurfaceMoneyness(cal, spot, times, stdDevs, blackVolMatrix, dayCounter, stickyStrike), index_(index),
33-
flatExtrapolateMoneyness_(flatExtrapMoneyness) {
31+
const QuantLib::ext::shared_ptr<EqFxIndexBase>& index, bool stickyStrike, bool flatExtrapMoneyness,
32+
BlackVolTimeExtrapolation timeExtrapolation, const VolatilityType type, const Real shift)
33+
: BlackVarianceSurfaceMoneyness(cal, spot, times, stdDevs, blackVolMatrix, dayCounter, stickyStrike,
34+
flatExtrapMoneyness, timeExtrapolation, type, shift),
35+
index_(index), flatExtrapolateMoneyness_(flatExtrapMoneyness) {
3436

3537
// set up atm variance curve - maybe just take ATM vols in
3638
vector<Real>::const_iterator it = find(stdDevs.begin(), stdDevs.end(), 0.0);

QuantExt/qle/termstructures/blackvariancesurfacestddevs.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ class BlackVarianceSurfaceStdDevs : public BlackVarianceSurfaceMoneyness {
4343
const std::vector<Real>& stdDevs,
4444
const std::vector<std::vector<Handle<Quote> > >& blackVolMatrix,
4545
const DayCounter& dayCounter, const QuantLib::ext::shared_ptr<EqFxIndexBase>& index,
46-
bool stickyStrike = false, bool flatExtrapMoneyness = false);
46+
bool stickyStrike = false, bool flatExtrapMoneyness = false,
47+
BlackVolTimeExtrapolation timeExtrapolation = BlackVolTimeExtrapolation::FlatVolatility,
48+
const VolatilityType type = VolatilityType::ShiftedLognormal,
49+
const Real shift = 0.0);
4750

4851
// A method that takes a reference to a vector of vector of quotes (that will be populated), termstructure,
4952
// expiry times, and standard deviation points. Fills the quotes with the correct points from the termstructure.

QuantExt/qle/termstructures/blackvolconstantspread.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ namespace QuantExt {
2424

2525
BlackVolatilityConstantSpread::BlackVolatilityConstantSpread(const Handle<BlackVolTermStructure>& atm,
2626
const Handle<BlackVolTermStructure>& surface)
27-
: BlackVolTermStructure(0, atm->calendar(), atm->businessDayConvention(), atm->dayCounter()), atm_(atm),
28-
surface_(surface) {
27+
: BlackVolTermStructure(0, atm->calendar(), atm->businessDayConvention(), atm->dayCounter(), atm->volType(),
28+
atm->shift()),
29+
atm_(atm), surface_(surface) {
2930
enableExtrapolation(atm->allowsExtrapolation());
3031
registerWith(atm);
3132
registerWith(surface);

QuantExt/qle/termstructures/blackvolsurfaceproxy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ BlackVolatilitySurfaceProxy::BlackVolatilitySurfaceProxy(
2727
const QuantLib::ext::shared_ptr<EqFxIndexBase>& proxyIndex, const QuantLib::ext::shared_ptr<BlackVolTermStructure>& fxSurface,
2828
const QuantLib::ext::shared_ptr<FxIndex>& fxIndex, const QuantLib::ext::shared_ptr<CorrelationTermStructure>& correlation)
2929
: BlackVolatilityTermStructure(0, proxySurface->calendar(), proxySurface->businessDayConvention(),
30-
proxySurface->dayCounter()),
30+
proxySurface->dayCounter(), proxySurface->volType(), proxySurface->shift()),
3131
proxySurface_(proxySurface), index_(index), proxyIndex_(proxyIndex), fxSurface_(fxSurface),
3232
fxIndex_(fxIndex), correlation_(correlation) {
3333

0 commit comments

Comments
 (0)