Add BlackVolatilitySurfaceDelta class for FX options#2368
Add BlackVolatilitySurfaceDelta class for FX options#2368lballabio merged 32 commits intolballabio:masterfrom
BlackVolatilitySurfaceDelta class for FX options#2368Conversation
… iterpolateSmileSection
ql/termstructures/volatility/equityfx/blackvariancetimeextrapolation.hpp
Outdated
Show resolved
Hide resolved
|
|
||
|
|
||
| //! Extrapolate black variance using flat vol extrapolation in time direction | ||
| Real timeExtrapolatationBlackVarianceFlat(const Time t, const std::vector<double>& times, |
There was a problem hiding this comment.
"extrapolatation" (here and everywhere)
| Copyright (C) 2019 Quaternion Risk Management Ltd | ||
| Copyright (C) 2022 Skandinaviska Enskilda Banken AB (publ) | ||
| Copyright (C) 2025 Paolo D'Elia | ||
| All rights reserved. |
There was a problem hiding this comment.
"All rights reserved" is in contradiction with the terms of the license below. If it's in the ORE code (it looks like it), we need to ask for its removal. @pcaspers, any idea why it's there?
There was a problem hiding this comment.
it seems this is outdated, see here - feel free to remove this line in this PR. We will update the ORE files accordingly.
| DeltaVolQuote::DeltaType dt = DeltaVolQuote::DeltaType::Spot, | ||
| DeltaVolQuote::AtmType at = DeltaVolQuote::AtmType::AtmDeltaNeutral, | ||
| ext::optional<DeltaVolQuote::DeltaType> atmDeltaType = ext::nullopt, | ||
| const Period& switchTenor = 0 * Days, | ||
| DeltaVolQuote::DeltaType ltdt = DeltaVolQuote::DeltaType::Fwd, | ||
| DeltaVolQuote::AtmType ltat = DeltaVolQuote::AtmType::AtmDeltaNeutral, | ||
| ext::optional<DeltaVolQuote::DeltaType> longTermAtmDeltaType = ext::nullopt, | ||
| SmileInterpolationMethod interpolationMethod = | ||
| SmileInterpolationMethod::Linear, | ||
| bool flatStrikeExtrapolation = false, | ||
| BlackVolTimeExtrapolation timeExtrapolation = | ||
| BlackVolTimeExtrapolation::FlatVolatility); |
There was a problem hiding this comment.
Lots of default parameters here—@pcaspers, is their order based on your usage patterns? (i.e., are the last ones also the least likely to be passed?)
There was a problem hiding this comment.
No I don't think so to be honest, they were added over time at the back to keep backwards compatibility. Feel free to reorder them if that seems more reasonable?
There was a problem hiding this comment.
I have reorder the optional parameters in the following way:
- Short-term conventions (
dt_,at_,atmDeltaType_) - Interpolation & extrapolation (
interpolationMethod_,flatStrikeExtrapolation_,timeExtrapolation_) - Long-term conventions (
switchTenor_,ltdt_,ltat_,longTermAtmDeltaType_)
It made more sense to me. Let me know what do you think.
|
Whenever you guys have time @lballabio @pcaspers |
Made mistake by using vols instead of stdDevs when building SmileSection in the test suite
|
This PR was automatically marked as stale because it has been open 60 days with no activity. Remove stale label or comment, or this will be closed in two weeks. |
|
@pcaspers — there were a couple of questions for you here if you have some time. Thanks! |
|
this is fine, we can move to ql's interpolated smilesection and remove fxsmilesection in ore:
|
|
@pcaspers actually I think you still need the |
|
|
||
|
|
||
| //! Extrapolate black variance using flat vol extrapolation in time direction | ||
| Real timeExtrapolationBlackVarianceFlat(const Time t, const std::vector<double>& times, |
There was a problem hiding this comment.
The functions in this file seem to belong together with BlackVolTimeExtrapolation. Instead of having an enum class and a separate set of functions, How about something like
class BlackVolTimeExtrapolation {
public:
enum Type { FlatVolatility, UseInterpolatorVariance, UseInterpolatorVolatility };
static Real extrapolate(Type type, const Time t, const std::vector<double>& times, etc);
};
where extrapolate calls one of these functions (that can be declared in namespace detail) based on type?
There was a problem hiding this comment.
Yeah, actually it's more elegant to have a class to do that, then just those plain functions.
| return varianceCurve_(times_.back(), true)*t/times_.back(); | ||
| return timeExtrapolationBlackVarianceFlat(t, times_, varianceCurve_); | ||
| } else if (timeExtrapolation_ == BlackVolTimeExtrapolation::UseInterpolatorVolatility) { | ||
| return timeExtrapolationBlackVarianceInVolatility(t, times_, varianceCurve_); |
There was a problem hiding this comment.
I would have expected this case to use the existing interpolator, but timeExtrapolationBlackVarianceInVolatility always uses linear interpolation. Maybe the enum name is misleading?
There was a problem hiding this comment.
I guess, it's because if you interpolate/extrapolate variances linearly you are sure that you are not going to have calendar spreads.
There was a problem hiding this comment.
Yes, I think so, but then the enum should be something like "LinearVariance", not "UseInterpolatorVolatility".
…ad of plain functions
|
Thanks, Paolo. I'll probably make some more refactoring to wrap my head around this and push it. |
| vols[0] = close_enough(times[0], 0.0) ? 0.0 : std::sqrt(variances[0] / times[0]); | ||
| vols[1] = close_enough(times[1], 0.0) ? 0.0 : std::sqrt(variances[1] / times[1]); | ||
| LinearInterpolation interpolation(times.begin(), times.end(), vols.begin()); | ||
| return std::max(interpolation(t, true), 0.0); |
There was a problem hiding this comment.
This interpolates linearly between volatilities. It should interpolate linearly between variances, shouldn't it?
There was a problem hiding this comment.
yes, an oversight of mine. I thought it was interpolating variances, for the non arb reasons.
There was a problem hiding this comment.
No problem, I'll modify it while I'm at it.
Also, use std::function to avoid templates (allowing us to keep the implementation in the cpp file).
I guess it's fine @lballabio. We just need to update the code that is initializing the |
Not sure if I'm getting it — the interpolators are constant delta, the piecewise surface works for a set of smiles which are constant time. It would be more like replacing the ones with the others, I guess? |
BlackVolatilitySurfaceDelta classBlackVolatilitySurfaceDelta class for FX options
Added
BlackVolatilitySurfaceDeltaclass from ORE, a Black volatility surface parameterized by market deltas, mainly used in Building FX/equity volatility surfaces from market delta quotes.QL changes @lballabio:
BlackVolatilitySurfaceDeltaclassInterpolatedSmileSectionclass as an additional constructor parameter, required from theBlackVolatilitySurfaceDeltaclass and from ORE's implementation ofInterpolatedSmileSectionclassInterepolatedSmileSectionclass (logic implemented incheckStrikes()private method), thought you guys might need it since it was underlined in the commentsORE Changes @pcaspers:
InterpolatedSmileSectionclass to retrive the SmileSection from theblackVolSmilemethod in theBlackVolatilitySurfaceDeltaclass instead of the QLEInterpolatedSmileSectionsince they provide the same functionalities, (QL'sInterpolatedSmileSectionis actually more complete than the QLE ones, but the latter is derived formFxSmileSectionnot present in QL) thus there no need to introduce another redundant class.